[tor-commits] [orbot/master] Deal with Doze in the less painful way

n8fr8 at torproject.org n8fr8 at torproject.org
Thu Mar 2 04:10:21 UTC 2017


commit 41ebcc50507b346e37d7aced4d6d88b49fe174be
Author: arrase <arrase at gmail.com>
Date:   Thu Dec 8 15:22:53 2016 +0100

    Deal with Doze in the less painful way
---
 app/src/main/AndroidManifest.xml                   |   1 +
 .../org/torproject/android/OrbotMainActivity.java  |   5 +-
 .../ui/hiddenservices/ClientCookiesActivity.java   |   6 +-
 .../ui/hiddenservices/HiddenServicesActivity.java  |  21 ++++-
 .../dialogs/CookieActionsDialog.java               |   6 +-
 .../ui/hiddenservices/dialogs/HSActionsDialog.java |   6 +-
 .../permissions/PermissionManager.java             | 103 +++++++++++++++++++++
 .../hiddenservices/storage/PermissionManager.java  |  50 ----------
 app/src/main/res/values/strings.xml                |   4 +
 9 files changed, 137 insertions(+), 65 deletions(-)

diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7dd9c1c..a713cf5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -23,6 +23,7 @@
     <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
 
     <android:uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
index 3abcdb8..1a468d4 100644
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@ -30,6 +30,7 @@ import org.torproject.android.ui.Rotate3dAnimation;
 import org.torproject.android.ui.hiddenservices.ClientCookiesActivity;
 import org.torproject.android.ui.hiddenservices.HiddenServicesActivity;
 import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
+import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
 import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
 import org.torproject.android.vpn.VPNEnableActivity;
 
@@ -124,8 +125,6 @@ public class OrbotMainActivity extends AppCompatActivity
     private final static int REQUEST_SETTINGS = 0x9874;
     private final static int REQUEST_VPN_APPS_SELECT = 8889;
 
-    private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
-
     // message types for mStatusUpdateHandler
     private final static int STATUS_UPDATE = 1;
     private static final int MESSAGE_TRAFFIC_COUNT = 2;
@@ -586,7 +585,7 @@ public class OrbotMainActivity extends AppCompatActivity
         Prefs.putUseVpn(enable);
 
         if (enable) {
-            if (mIsLollipop) //let the user choose the apps
+            if (PermissionManager.isLollipopOrHigher()) //let the user choose the apps
                 startActivityForResult(new Intent(OrbotMainActivity.this, AppManager.class), REQUEST_VPN_APPS_SELECT);
             else
                 startActivity(new Intent(OrbotMainActivity.this, VPNEnableActivity.class));
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java
index 0b94812..ffbe3d5 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/ClientCookiesActivity.java
@@ -28,8 +28,8 @@ import org.torproject.android.ui.hiddenservices.adapters.ClienCookiesAdapter;
 import org.torproject.android.ui.hiddenservices.dialogs.AddCookieDialog;
 import org.torproject.android.ui.hiddenservices.dialogs.CookieActionsDialog;
 import org.torproject.android.ui.hiddenservices.dialogs.SelectCookieBackupDialog;
+import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
 import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
-import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
 
 public class ClientCookiesActivity extends AppCompatActivity {
     public final int WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTIONBAR = 3;
@@ -111,9 +111,9 @@ public class ClientCookiesActivity extends AppCompatActivity {
         int id = item.getItemId();
 
         if (id == R.id.cookie_restore_backup) {
-            if (PermissionManager.usesRuntimePermissions()
+            if (PermissionManager.isLollipopOrHigher()
                     && !PermissionManager.hasExternalWritePermission(this)) {
-                PermissionManager.requestPermissions(this, WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTIONBAR);
+                PermissionManager.requestExternalWritePermissions(this, WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTIONBAR);
                 return true;
             }
 
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
index ae2cd55..f644558 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/HiddenServicesActivity.java
@@ -25,8 +25,8 @@ import org.torproject.android.ui.hiddenservices.adapters.OnionListAdapter;
 import org.torproject.android.ui.hiddenservices.dialogs.HSActionsDialog;
 import org.torproject.android.ui.hiddenservices.dialogs.HSDataDialog;
 import org.torproject.android.ui.hiddenservices.dialogs.SelectHSBackupDialog;
+import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
 import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
-import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
 
 public class HiddenServicesActivity extends AppCompatActivity {
     public final int WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR = 1;
@@ -150,9 +150,9 @@ public class HiddenServicesActivity extends AppCompatActivity {
         int id = item.getItemId();
 
         if (id == R.id.menu_restore_backup) {
-            if (PermissionManager.usesRuntimePermissions()
+            if (PermissionManager.isLollipopOrHigher()
                     && !PermissionManager.hasExternalWritePermission(this)) {
-                PermissionManager.requestPermissions(this, WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR);
+                PermissionManager.requestExternalWritePermissions(this, WRITE_EXTERNAL_STORAGE_FROM_ACTIONBAR);
                 return true;
             }
 
@@ -194,6 +194,21 @@ public class HiddenServicesActivity extends AppCompatActivity {
             mAdapter.changeCursor(mResolver.query(
                     HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, mWhere, null, null
             ));
+
+            if (PermissionManager.isLollipopOrHigher()) {
+                Cursor active = mResolver.query(
+                        HSContentProvider.CONTENT_URI, HSContentProvider.PROJECTION, HSContentProvider.HiddenService.ENABLED + "=1", null, null
+                );
+
+                if (active == null) return;
+
+                if (active.getCount() > 0) // Call only if there running services
+                    PermissionManager.requestBatteryPermmssions(HiddenServicesActivity.this, getApplicationContext());
+                else // Drop whe not needed
+                    PermissionManager.requestDropBatteryPermmssions(HiddenServicesActivity.this, getApplicationContext());
+
+                active.close();
+            }
         }
     }
 }
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java
index e5683da..7b5a2cf 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/CookieActionsDialog.java
@@ -15,7 +15,7 @@ import android.widget.Toast;
 
 import org.torproject.android.R;
 import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
-import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
+import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
 
 public class CookieActionsDialog extends DialogFragment {
     public static final int WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTION_DIALOG = 4;
@@ -36,10 +36,10 @@ public class CookieActionsDialog extends DialogFragment {
             public void onClick(View v) {
                 Context mContext = v.getContext();
 
-                if (PermissionManager.usesRuntimePermissions()
+                if (PermissionManager.isLollipopOrHigher()
                         && !PermissionManager.hasExternalWritePermission(mContext)) {
 
-                    PermissionManager.requestPermissions(
+                    PermissionManager.requestExternalWritePermissions(
                             getActivity(), WRITE_EXTERNAL_STORAGE_FROM_COOKIE_ACTION_DIALOG);
 
                     return;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
index ff7f7e1..5be7691 100644
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/dialogs/HSActionsDialog.java
@@ -17,7 +17,7 @@ import android.widget.Toast;
 
 import org.torproject.android.R;
 import org.torproject.android.ui.hiddenservices.backup.BackupUtils;
-import org.torproject.android.ui.hiddenservices.storage.PermissionManager;
+import org.torproject.android.ui.hiddenservices.permissions.PermissionManager;
 
 public class HSActionsDialog extends DialogFragment {
     public static final int WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG = 2;
@@ -38,10 +38,10 @@ public class HSActionsDialog extends DialogFragment {
             public void onClick(View v) {
                 Context mContext = v.getContext();
 
-                if (PermissionManager.usesRuntimePermissions()
+                if (PermissionManager.isLollipopOrHigher()
                         && !PermissionManager.hasExternalWritePermission(mContext)) {
 
-                    PermissionManager.requestPermissions(
+                    PermissionManager.requestExternalWritePermissions(
                             getActivity(), WRITE_EXTERNAL_STORAGE_FROM_ACTION_DIALOG);
 
                     return;
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/permissions/PermissionManager.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/permissions/PermissionManager.java
new file mode 100644
index 0000000..a9df5a9
--- /dev/null
+++ b/app/src/main/java/org/torproject/android/ui/hiddenservices/permissions/PermissionManager.java
@@ -0,0 +1,103 @@
+package org.torproject.android.ui.hiddenservices.permissions;
+
+
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.support.design.widget.Snackbar;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.app.FragmentActivity;
+import android.view.View;
+
+import org.torproject.android.R;
+
+public class PermissionManager {
+    public static int VERY_LONG_LENGTH = 6000;
+
+    public static boolean isLollipopOrHigher() {
+        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
+    }
+
+    @SuppressLint("NewApi")
+    public static boolean hasExternalWritePermission(Context context) {
+        return (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
+    }
+
+    public static void requestExternalWritePermissions(FragmentActivity activity, int action) {
+        final int mAction = action;
+        final FragmentActivity mActivity = activity;
+
+        if (ActivityCompat.shouldShowRequestPermissionRationale
+                (mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+            Snackbar.make(mActivity.findViewById(android.R.id.content),
+                    R.string.please_grant_permissions_for_external_storage,
+                    Snackbar.LENGTH_INDEFINITE).setAction(R.string.activate,
+                    new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            ActivityCompat.requestPermissions(mActivity,
+                                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+                                    mAction);
+                        }
+                    }).show();
+        } else {
+            ActivityCompat.requestPermissions(mActivity,
+                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+                    mAction);
+        }
+    }
+
+    @TargetApi(Build.VERSION_CODES.M)
+    public static void requestBatteryPermmssions(FragmentActivity activity, Context context) {
+        final Context mContext = context;
+        final String packageName = mContext.getPackageName();
+        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+
+        if (pm.isIgnoringBatteryOptimizations(packageName))
+            return;
+
+        Snackbar.make(activity.findViewById(android.R.id.content),
+                R.string.consider_disable_battery_optimizations,
+                VERY_LONG_LENGTH).setAction(R.string.disable,
+                new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        Intent intent = new Intent();
+                        intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+                        intent.setData(Uri.parse("package:" + packageName));
+                        mContext.startActivity(intent);
+                    }
+                }).show();
+    }
+
+    @TargetApi(Build.VERSION_CODES.M)
+    public static void requestDropBatteryPermmssions(FragmentActivity activity, Context context) {
+        final Context mContext = context;
+
+        final String packageName = context.getPackageName();
+        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+
+        if (!pm.isIgnoringBatteryOptimizations(packageName))
+            return;
+
+        Snackbar.make(activity.findViewById(android.R.id.content),
+                R.string.consider_enable_battery_optimizations,
+                VERY_LONG_LENGTH).setAction(R.string.enable,
+                new View.OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        Intent intent = new Intent();
+                        intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
+                        mContext.startActivity(intent);
+                    }
+                }).show();
+    }
+}
+
diff --git a/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java b/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java
deleted file mode 100644
index 3a3cf09..0000000
--- a/app/src/main/java/org/torproject/android/ui/hiddenservices/storage/PermissionManager.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.torproject.android.ui.hiddenservices.storage;
-
-
-import android.Manifest;
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.support.design.widget.Snackbar;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.app.FragmentActivity;
-import android.view.View;
-
-import org.torproject.android.R;
-
-public class PermissionManager {
-
-    public static boolean usesRuntimePermissions() {
-        return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
-    }
-
-    @SuppressLint("NewApi")
-    public static boolean hasExternalWritePermission(Context context) {
-        return (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
-    }
-
-    public static void requestPermissions(FragmentActivity activity, int action) {
-        final int mAction = action;
-        final FragmentActivity mActivity = activity;
-
-        if (ActivityCompat.shouldShowRequestPermissionRationale
-                (mActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
-            Snackbar.make(mActivity.findViewById(android.R.id.content),
-                    R.string.please_grant_permissions_for_external_storage,
-                    Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
-                    new View.OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            ActivityCompat.requestPermissions(mActivity,
-                                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
-                                    mAction);
-                        }
-                    }).show();
-        } else {
-            ActivityCompat.requestPermissions(mActivity,
-                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
-                    mAction);
-        }
-    }
-}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6a07c44..41b9e81 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -376,4 +376,8 @@
     <string name="confirm_cookie_deletion">Confirm cookie deletion</string>
     <string name="hosted_services">Hosted Services</string>
     <string name="share_as_qr">Share as QR</string>
+    <string name="disable">Disable</string>
+    <string name="enable">Enable</string>
+    <string name="consider_disable_battery_optimizations">Consider disable battery optimizations</string>
+    <string name="consider_enable_battery_optimizations">Consider enable battery optimizations</string>
 </resources>





More information about the tor-commits mailing list