diff --git a/app/build.gradle b/app/build.gradle
index fb4598597..9eb3ccef7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -17,7 +17,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
-
+
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
@@ -35,4 +35,5 @@ dependencies {
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'org.jsoup:jsoup:1.8.3'
compile 'org.mozilla:rhino:1.7.7'
+ compile 'info.guardianproject.netcipher:netcipher:1.2'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d028886b1..ef84c57b3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
() {
+
+ 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();
+ }
+
}
diff --git a/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java b/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java
index d5fea8c3e..13a1cefed 100644
--- a/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/PlayVideoActivity.java
@@ -187,6 +187,18 @@ public class PlayVideoActivity extends AppCompatActivity {
videoView.pause();
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ App.checkStartTor(this);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ prefs = getPreferences(Context.MODE_PRIVATE);
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
diff --git a/app/src/main/java/org/schabi/newpipe/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/SettingsActivity.java
index c8a548ab6..f599ebd8b 100644
--- a/app/src/main/java/org/schabi/newpipe/SettingsActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/SettingsActivity.java
@@ -1,7 +1,12 @@
package org.schabi.newpipe;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.support.annotation.LayoutRes;
@@ -13,6 +18,8 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import info.guardianproject.netcipher.proxy.OrbotHelper;
+
/**
* Created by Christian Schabesberger on 31.08.15.
*
@@ -35,6 +42,7 @@ import android.view.ViewGroup;
public class SettingsActivity extends PreferenceActivity {
+ private static final int REQUEST_INSTALL_ORBOT = 0x1234;
private AppCompatDelegate mDelegate = null;
@Override
@@ -52,13 +60,48 @@ public class SettingsActivity extends PreferenceActivity {
}
public static class SettingsFragment extends PreferenceFragment {
+ private CheckBoxPreference useTorCheckBox;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
diff --git a/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java b/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java
index 4a553241f..f93ca4b9e 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoItemDetailActivity.java
@@ -113,6 +113,12 @@ public class VideoItemDetailActivity extends AppCompatActivity {
.commit();
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ App.checkStartTor(this);
+ }
+
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(VideoItemDetailFragment.VIDEO_URL, videoUrl);
diff --git a/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java b/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java
index d15709b23..8c4f5c57e 100644
--- a/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java
+++ b/app/src/main/java/org/schabi/newpipe/VideoItemListActivity.java
@@ -175,6 +175,12 @@ public class VideoItemListActivity extends AppCompatActivity
PreferenceManager.setDefaultValues(this, R.xml.settings_screen, false);
}
+ @Override
+ public void onResume() {
+ super.onResume();
+ App.checkStartTor(this);
+ }
+
/**
* Callback method from {@link VideoItemListFragment.Callbacks}
* indicating that the item with the given ID was selected.
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 12fb9275d..c7058759e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -63,4 +63,6 @@
Uploader thumbnail
Dislikes
Likes
+ Use Tor
+ Force download traffic through Tor for increased privacy (streaming videos not yet supported)
diff --git a/app/src/main/res/xml/settings_screen.xml b/app/src/main/res/xml/settings_screen.xml
index d4b21426f..4d21b457b 100644
--- a/app/src/main/res/xml/settings_screen.xml
+++ b/app/src/main/res/xml/settings_screen.xml
@@ -72,5 +72,10 @@
android:summary="@string/autoPlayThroughIntentSummary"
android:defaultValue="false" />
+
+