mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-11-17 15:24:55 +00:00
Merge pull request #136 from eighthave/tor-support-for-all-except-streaming
Tor support for all except streaming
This commit is contained in:
commit
0da1aef763
@ -35,4 +35,5 @@ dependencies {
|
|||||||
compile 'com.android.support:recyclerview-v7:23.1.1'
|
compile 'com.android.support:recyclerview-v7:23.1.1'
|
||||||
compile 'org.jsoup:jsoup:1.8.3'
|
compile 'org.jsoup:jsoup:1.8.3'
|
||||||
compile 'org.mozilla:rhino:1.7.7'
|
compile 'org.mozilla:rhino:1.7.7'
|
||||||
|
compile 'info.guardianproject.netcipher:netcipher:1.2'
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<application
|
<application
|
||||||
|
android:name=".App"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:logo="@mipmap/ic_launcher"
|
android:logo="@mipmap/ic_launcher"
|
||||||
|
46
app/src/main/java/org/schabi/newpipe/App.java
Normal file
46
app/src/main/java/org/schabi/newpipe/App.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import info.guardianproject.netcipher.NetCipher;
|
||||||
|
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||||
|
|
||||||
|
public class App extends Application {
|
||||||
|
|
||||||
|
private static boolean useTor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
// if Orbot is installed, then default to using Tor, the user can still override
|
||||||
|
if (OrbotHelper.requestStartTor(this)) {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
configureTor(prefs.getBoolean(getString(R.string.useTor), true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the proxy settings based on whether Tor should be enabled or not.
|
||||||
|
*/
|
||||||
|
static void configureTor(boolean enabled) {
|
||||||
|
useTor = enabled;
|
||||||
|
if (useTor) {
|
||||||
|
NetCipher.useTor();
|
||||||
|
} else {
|
||||||
|
NetCipher.setProxy(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkStartTor(Context context) {
|
||||||
|
if (useTor) {
|
||||||
|
OrbotHelper.requestStartTor(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isUsingTor() {
|
||||||
|
return useTor;
|
||||||
|
}
|
||||||
|
}
|
@ -61,17 +61,17 @@ public class DownloadDialog extends DialogFragment {
|
|||||||
String suffix = "";
|
String suffix = "";
|
||||||
String title = arguments.getString(TITLE);
|
String title = arguments.getString(TITLE);
|
||||||
String url = "";
|
String url = "";
|
||||||
String downloadFolder = "Download";
|
String downloadFolder = Environment.DIRECTORY_DOWNLOADS;
|
||||||
switch(which) {
|
switch(which) {
|
||||||
case 0: // Video
|
case 0: // Video
|
||||||
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
|
suffix = arguments.getString(FILE_SUFFIX_VIDEO);
|
||||||
url = arguments.getString(VIDEO_URL);
|
url = arguments.getString(VIDEO_URL);
|
||||||
downloadFolder = "Movies";
|
downloadFolder = Environment.DIRECTORY_MOVIES;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
|
suffix = arguments.getString(FILE_SUFFIX_AUDIO);
|
||||||
url = arguments.getString(AUDIO_URL);
|
url = arguments.getString(AUDIO_URL);
|
||||||
downloadFolder = "Music";
|
downloadFolder = Environment.DIRECTORY_MUSIC;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.d(TAG, "lolz");
|
Log.d(TAG, "lolz");
|
||||||
@ -87,15 +87,21 @@ public class DownloadDialog extends DialogFragment {
|
|||||||
//TODO notify user "download directory should be changed" ?
|
//TODO notify user "download directory should be changed" ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
String saveFilePath = dir + "/" + title + suffix;
|
||||||
DownloadManager.Request request = new DownloadManager.Request(
|
if (App.isUsingTor()) {
|
||||||
Uri.parse(url));
|
// if using Tor, do not use DownloadManager because the proxy cannot be set
|
||||||
request.setDestinationUri(Uri.fromFile(new File(dir + "/" + title + suffix)));
|
Downloader.downloadFile(getContext(), url, saveFilePath);
|
||||||
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
} else {
|
||||||
try {
|
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||||
dm.enqueue(request);
|
DownloadManager.Request request = new DownloadManager.Request(
|
||||||
} catch (Exception e) {
|
Uri.parse(url));
|
||||||
e.printStackTrace();
|
request.setDestinationUri(Uri.fromFile(new File(saveFilePath)));
|
||||||
|
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
|
||||||
|
try {
|
||||||
|
dm.enqueue(request);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,12 +1,30 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
import info.guardianproject.netcipher.NetCipher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 14.08.15.
|
* Created by Christian Schabesberger on 14.08.15.
|
||||||
*
|
*
|
||||||
@ -28,6 +46,7 @@ import java.net.UnknownHostException;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class Downloader {
|
public class Downloader {
|
||||||
|
public static final String TAG = "Downloader";
|
||||||
|
|
||||||
private static final String USER_AGENT = "Mozilla/5.0";
|
private static final String USER_AGENT = "Mozilla/5.0";
|
||||||
|
|
||||||
@ -40,7 +59,7 @@ public class Downloader {
|
|||||||
String ret = "";
|
String ret = "";
|
||||||
try {
|
try {
|
||||||
URL url = new URL(siteUrl);
|
URL url = new URL(siteUrl);
|
||||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
|
||||||
con.setRequestProperty("Accept-Language", language);
|
con.setRequestProperty("Accept-Language", language);
|
||||||
ret = dl(con);
|
ret = dl(con);
|
||||||
}
|
}
|
||||||
@ -84,7 +103,7 @@ public class Downloader {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
URL url = new URL(siteUrl);
|
URL url = new URL(siteUrl);
|
||||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
HttpsURLConnection con = NetCipher.getHttpsURLConnection(url);
|
||||||
ret = dl(con);
|
ret = dl(con);
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
catch(Exception e) {
|
||||||
@ -93,4 +112,92 @@ public class Downloader {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads a file from a URL in the background using an {@link AsyncTask}.
|
||||||
|
*
|
||||||
|
* @param fileURL HTTP URL of the file to be downloaded
|
||||||
|
* @param saveFilePath path of the directory to save the file
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static void downloadFile(final Context context, final String fileURL, final String saveFilePath) {
|
||||||
|
new AsyncTask<Void, Integer, Void>() {
|
||||||
|
|
||||||
|
private NotificationManager nm;
|
||||||
|
private NotificationCompat.Builder builder;
|
||||||
|
private int notifyId = 0x1234;
|
||||||
|
private int fileSize = 0xffffffff;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
super.onPreExecute();
|
||||||
|
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
Drawable icon = context.getResources().getDrawable(R.mipmap.ic_launcher);
|
||||||
|
builder = new NotificationCompat.Builder(context)
|
||||||
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
||||||
|
.setLargeIcon(((BitmapDrawable) icon).getBitmap())
|
||||||
|
.setContentTitle(saveFilePath.substring(saveFilePath.lastIndexOf('/') + 1))
|
||||||
|
.setContentText(saveFilePath)
|
||||||
|
.setProgress(fileSize, 0, false);
|
||||||
|
nm.notify(notifyId, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... voids) {
|
||||||
|
HttpsURLConnection con = null;
|
||||||
|
try {
|
||||||
|
con = NetCipher.getHttpsURLConnection(fileURL);
|
||||||
|
int responseCode = con.getResponseCode();
|
||||||
|
|
||||||
|
// always check HTTP response code first
|
||||||
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||||
|
fileSize = con.getContentLength();
|
||||||
|
InputStream inputStream = new BufferedInputStream(con.getInputStream());
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(saveFilePath);
|
||||||
|
|
||||||
|
int bufferSize = 8192;
|
||||||
|
int downloaded = 0;
|
||||||
|
|
||||||
|
int bytesRead = -1;
|
||||||
|
byte[] buffer = new byte[bufferSize];
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
downloaded += bytesRead;
|
||||||
|
if (downloaded % 50000 < bufferSize) {
|
||||||
|
publishProgress(downloaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream.close();
|
||||||
|
inputStream.close();
|
||||||
|
publishProgress(bufferSize);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "No file to download. Server replied HTTP code: " + responseCode);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (con != null) {
|
||||||
|
con.disconnect();
|
||||||
|
con = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProgressUpdate(Integer... progress) {
|
||||||
|
builder.setProgress(fileSize, progress[0], false);
|
||||||
|
nm.notify(notifyId, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void aVoid) {
|
||||||
|
super.onPostExecute(aVoid);
|
||||||
|
nm.cancel(notifyId);
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,18 @@ public class PlayVideoActivity extends AppCompatActivity {
|
|||||||
videoView.pause();
|
videoView.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
App.checkStartTor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
prefs = getPreferences(Context.MODE_PRIVATE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.preference.CheckBoxPreference;
|
||||||
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
@ -13,6 +18,8 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import info.guardianproject.netcipher.proxy.OrbotHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Christian Schabesberger on 31.08.15.
|
* Created by Christian Schabesberger on 31.08.15.
|
||||||
*
|
*
|
||||||
@ -35,6 +42,7 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
public class SettingsActivity extends PreferenceActivity {
|
public class SettingsActivity extends PreferenceActivity {
|
||||||
|
|
||||||
|
private static final int REQUEST_INSTALL_ORBOT = 0x1234;
|
||||||
private AppCompatDelegate mDelegate = null;
|
private AppCompatDelegate mDelegate = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,13 +60,48 @@ public class SettingsActivity extends PreferenceActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class SettingsFragment extends PreferenceFragment {
|
public static class SettingsFragment extends PreferenceFragment {
|
||||||
|
private CheckBoxPreference useTorCheckBox;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
addPreferencesFromResource(R.xml.settings_screen);
|
addPreferencesFromResource(R.xml.settings_screen);
|
||||||
|
|
||||||
|
// if Orbot is installed, then default to using Tor, the user can still override
|
||||||
|
useTorCheckBox = (CheckBoxPreference) findPreference(getString(R.string.useTor));
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
final boolean useTor = OrbotHelper.isOrbotInstalled(activity);
|
||||||
|
useTorCheckBox.setDefaultValue(useTor);
|
||||||
|
useTorCheckBox.setChecked(useTor);
|
||||||
|
useTorCheckBox.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||||
|
boolean useTor = (Boolean) o;
|
||||||
|
if (useTor) {
|
||||||
|
if (OrbotHelper.isOrbotInstalled(activity)) {
|
||||||
|
App.configureTor(true);
|
||||||
|
} else {
|
||||||
|
Intent intent = OrbotHelper.getOrbotInstallIntent(activity);
|
||||||
|
activity.startActivityForResult(intent, REQUEST_INSTALL_ORBOT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
App.configureTor(false);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
// try to start tor regardless of resultCode since clicking back after
|
||||||
|
// installing the app does not necessarily return RESULT_OK
|
||||||
|
App.configureTor(requestCode == REQUEST_INSTALL_ORBOT
|
||||||
|
&& OrbotHelper.requestStartTor(this));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
super.onPostCreate(savedInstanceState);
|
super.onPostCreate(savedInstanceState);
|
||||||
|
@ -113,6 +113,12 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
|||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
App.checkStartTor(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
|
||||||
|
@ -175,6 +175,12 @@ public class VideoItemListActivity extends AppCompatActivity
|
|||||||
PreferenceManager.setDefaultValues(this, R.xml.settings_screen, false);
|
PreferenceManager.setDefaultValues(this, R.xml.settings_screen, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
App.checkStartTor(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method from {@link VideoItemListFragment.Callbacks}
|
* Callback method from {@link VideoItemListFragment.Callbacks}
|
||||||
* indicating that the item with the given ID was selected.
|
* indicating that the item with the given ID was selected.
|
||||||
|
@ -63,4 +63,6 @@
|
|||||||
<string name="detailUploaderThumbnailViewDescription">Uploader thumbnail</string>
|
<string name="detailUploaderThumbnailViewDescription">Uploader thumbnail</string>
|
||||||
<string name="detailThumbsDownImgViewDescription">Dislikes</string>
|
<string name="detailThumbsDownImgViewDescription">Dislikes</string>
|
||||||
<string name="detailThumbsUpImgViewDescription">Likes</string>
|
<string name="detailThumbsUpImgViewDescription">Likes</string>
|
||||||
|
<string name="useTor">Use Tor</string>
|
||||||
|
<string name="useTorSummary">Force download traffic through Tor for increased privacy (streaming videos not yet supported)</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -72,5 +72,10 @@
|
|||||||
android:summary="@string/autoPlayThroughIntentSummary"
|
android:summary="@string/autoPlayThroughIntentSummary"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="@string/useTor"
|
||||||
|
android:title="@string/useTor"
|
||||||
|
android:summary="@string/useTorSummary" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
Loading…
Reference in New Issue
Block a user