[tor-commits] [orbot/master] Fixes #401 Only NEWNYM Through UI When Sensible

n8fr8 at torproject.org n8fr8 at torproject.org
Wed Dec 23 16:36:12 UTC 2020


commit e63b9e61c822450dd64da0c5804ba7ee11a9f544
Author: bim <dsnake at protonmail.com>
Date:   Fri Oct 16 15:29:13 2020 -0400

    Fixes #401 Only NEWNYM Through UI When Sensible
    - The "NEW IDENTITY" button in the notification is only visible when the user can click on it
    - Clicking the refresh button in the main app gives you a new identity if you have one, does nothing if Tor is starting, and starts tor if it's off/stopping
---
 .../org/torproject/android/OrbotMainActivity.java  |  32 ++++--
 .../torproject/android/service/OrbotService.java   | 108 ++++++++-------------
 2 files changed, 61 insertions(+), 79 deletions(-)

diff --git a/app/src/main/java/org/torproject/android/OrbotMainActivity.java b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
index 6c2cb173..7102ea94 100644
--- a/app/src/main/java/org/torproject/android/OrbotMainActivity.java
+++ b/app/src/main/java/org/torproject/android/OrbotMainActivity.java
@@ -95,6 +95,10 @@ import static org.torproject.android.service.TorServiceConstants.ACTION_START;
 import static org.torproject.android.service.TorServiceConstants.ACTION_START_VPN;
 import static org.torproject.android.service.TorServiceConstants.ACTION_STOP_VPN;
 import static org.torproject.android.service.TorServiceConstants.DIRECTORY_TOR_DATA;
+import static org.torproject.android.service.TorServiceConstants.STATUS_OFF;
+import static org.torproject.android.service.TorServiceConstants.STATUS_ON;
+import static org.torproject.android.service.TorServiceConstants.STATUS_STARTING;
+import static org.torproject.android.service.TorServiceConstants.STATUS_STOPPING;
 import static org.torproject.android.service.vpn.VpnPrefs.PREFS_KEY_TORIFIED;
 
 public class OrbotMainActivity extends AppCompatActivity implements OrbotConstants {
@@ -132,7 +136,7 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan
     private boolean autoStartFromIntent = false;
     // this is what takes messages or values from the callback threads or other non-mainUI threads
     // and passes them back into the main UI thread for display to the user
-    private Handler mStatusUpdateHandler = new MainActivityStatusUpdateHandler(this);
+    private final Handler mStatusUpdateHandler = new MainActivityStatusUpdateHandler(this);
     /**
      * The state and log info from {@link OrbotService} are sent to the UI here in
      * the form of a local broadcast. Regular broadcasts can be sent by any app,
@@ -1093,15 +1097,23 @@ public class OrbotMainActivity extends AppCompatActivity implements OrbotConstan
     }
 
     private void requestNewTorIdentity() {
-        sendIntentToService(TorServiceConstants.CMD_NEWNYM);
-
-        Rotate3dAnimation rotation = new Rotate3dAnimation(ROTATE_FROM, ROTATE_TO, imgStatus.getWidth() / 2f, imgStatus.getWidth() / 2f, 20f, false);
-        rotation.setFillAfter(true);
-        rotation.setInterpolator(new AccelerateInterpolator());
-        rotation.setDuration((long) 2 * 1000);
-        rotation.setRepeatCount(0);
-        imgStatus.startAnimation(rotation);
-        lblStatus.setText(getString(R.string.newnym));
+        switch (torStatus) {
+            case STATUS_ON: // tor is on, we can ask for a new identity
+                Rotate3dAnimation rotation = new Rotate3dAnimation(ROTATE_FROM, ROTATE_TO, imgStatus.getWidth() / 2f, imgStatus.getWidth() / 2f, 20f, false);
+                rotation.setFillAfter(true);
+                rotation.setInterpolator(new AccelerateInterpolator());
+                rotation.setDuration((long) 2 * 1000);
+                rotation.setRepeatCount(0);
+                imgStatus.startAnimation(rotation);
+                lblStatus.setText(getString(R.string.newnym));
+                break;
+            case STATUS_STARTING: return; // tor is starting up, a new identity isn't needed
+            case STATUS_OFF:
+            case STATUS_STOPPING:
+                startTor();
+                break;
+            default: break;
+        }
     }
 
     private void drawAppShortcuts(boolean showSelectedApps) {
diff --git a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java
index 820c84d6..a7f75577 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/OrbotService.java
@@ -40,6 +40,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 import com.jaredrummler.android.shell.CommandResult;
 
 import net.freehaven.tor.control.ConfigEntry;
+import net.freehaven.tor.control.TorControlCommands;
 import net.freehaven.tor.control.TorControlConnection;
 
 import org.apache.commons.io.FileUtils;
@@ -114,15 +115,13 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
     private ArrayList<String> configBuffer = null;
     private ArrayList<String> resetBuffer = null;
     private File fileControlPort, filePid;
-    private boolean mConnectivity = true;
     private NotificationManager mNotificationManager = null;
     private NotificationCompat.Builder mNotifyBuilder;
-    private Notification mNotification;
     private boolean mNotificationShowing = false;
-    private ExecutorService mExecutor = Executors.newFixedThreadPool(3);
+    private final ExecutorService mExecutor = Executors.newFixedThreadPool(3);
     private File mHSBasePath;
     private ArrayList<Bridge> alBridges = null;
-    private String[] hsProjection = new String[]{
+    private final String[] hsProjection = new String[]{
             HiddenService._ID,
             HiddenService.NAME,
             HiddenService.DOMAIN,
@@ -131,7 +130,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             HiddenService.AUTH_COOKIE_VALUE,
             HiddenService.ONION_PORT,
             HiddenService.ENABLED};
-    private String[] cookieProjection = new String[]{
+    private final String[] cookieProjection = new String[]{
             ClientCookie._ID,
             ClientCookie.DOMAIN,
             ClientCookie.AUTH_COOKIE_VALUE,
@@ -170,6 +169,10 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
 
     }
 
+    private void showConnectedToTorNetworkNotification() {
+        showToolbarNotification(getString(R.string.status_activated), NOTIFY_ID, R.drawable.ic_stat_tor);
+    }
+
     private boolean findExistingTorDaemon() {
         try {
             mLastProcessId = initControlConnection(3, true);
@@ -177,8 +180,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             if (mLastProcessId != -1 && conn != null) {
                 sendCallbackLogMessage(getString(R.string.found_existing_tor_process));
                 sendCallbackStatus(STATUS_ON);
-                showToolbarNotification(getString(R.string.status_activated), NOTIFY_ID, R.drawable.ic_stat_tor);
-
+                showConnectedToTorNetworkNotification();
                 return true;
             }
         } catch (Exception e) {
@@ -223,64 +225,45 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
         mNotificationManager.createNotificationChannel(mChannel);
     }
 
-    @SuppressLint("NewApi")
+    @SuppressLint({"NewApi", "RestrictedApi"})
     protected void showToolbarNotification(String notifyMsg, int notifyType, int icon) {
-
-        //Reusable code.
         PackageManager pm = getPackageManager();
         Intent intent = pm.getLaunchIntentForPackage(getPackageName());
         PendingIntent pendIntent = PendingIntent.getActivity(OrbotService.this, 0, intent, 0);
 
         if (mNotifyBuilder == null) {
-
             mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+            mNotifyBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
+                    .setContentTitle(getString(R.string.app_name))
+                    .setSmallIcon(R.drawable.ic_stat_tor)
+                    .setContentIntent(pendIntent)
+                    .setCategory(Notification.CATEGORY_SERVICE)
+                    .setOngoing(Prefs.persistNotifications());
+        }
 
-            if (mNotifyBuilder == null) {
-                mNotifyBuilder = new NotificationCompat.Builder(this)
-                        .setContentTitle(getString(R.string.app_name))
-                        .setSmallIcon(R.drawable.ic_stat_tor);
-
-                mNotifyBuilder.setContentIntent(pendIntent);
-
-            }
-
-
-            mNotifyBuilder.setCategory(Notification.CATEGORY_SERVICE);
-
-            mNotifyBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
-
-
-            Intent intentRefresh = new Intent();
-            intentRefresh.setAction(CMD_NEWNYM);
+        mNotifyBuilder.mActions.clear(); // clear out NEWNYM action
+        if (conn != null) { // only add new identity action when there is a connection
+            Intent intentRefresh = new Intent(CMD_NEWNYM);
             PendingIntent pendingIntentNewNym = PendingIntent.getBroadcast(this, 0, intentRefresh, PendingIntent.FLAG_UPDATE_CURRENT);
-            mNotifyBuilder.addAction(R.drawable.ic_refresh_white_24dp, getString(R.string.menu_new_identity),
-                    pendingIntentNewNym);
-
-            mNotifyBuilder.setOngoing(Prefs.persistNotifications());
-
+            mNotifyBuilder.addAction(R.drawable.ic_refresh_white_24dp, getString(R.string.menu_new_identity), pendingIntentNewNym);
         }
 
-        mNotifyBuilder.setContentText(notifyMsg);
-        mNotifyBuilder.setSmallIcon(icon);
-
-        if (notifyType != NOTIFY_ID) {
-            mNotifyBuilder.setTicker(notifyMsg);
-        } else {
-            mNotifyBuilder.setTicker(null);
-        }
+        mNotifyBuilder.setContentText(notifyMsg)
+                .setSmallIcon(icon)
+                .setTicker(notifyType != NOTIFY_ID ? notifyMsg : null);
 
         if (!Prefs.persistNotifications())
             mNotifyBuilder.setPriority(Notification.PRIORITY_LOW);
 
-        mNotification = mNotifyBuilder.build();
+        Notification notification = mNotifyBuilder.build();
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            startForeground(NOTIFY_ID, mNotification);
+            startForeground(NOTIFY_ID, notification);
         } else if (Prefs.persistNotifications() && (!mNotificationShowing)) {
-            startForeground(NOTIFY_ID, mNotification);
+            startForeground(NOTIFY_ID, notification);
             logNotice("Set background service to FOREGROUND");
         } else {
-            mNotificationManager.notify(NOTIFY_ID, mNotification);
+            mNotificationManager.notify(NOTIFY_ID, notification);
         }
 
         mNotificationShowing = true;
@@ -364,8 +347,6 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
 
             conn = null;
         }
-
-
     }
 
     private void requestTorRereadConfig() {
@@ -728,7 +709,7 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
                 sendCallbackLogMessage("Ignoring start request, currently " + mCurrentStatus);
                 return;
             } else if (mCurrentStatus == STATUS_ON && (torProcId != null)) {
-
+                showConnectedToTorNetworkNotification();
                 sendCallbackLogMessage("Ignoring start request, already started.");
                 // setTorNetworkEnabled (true);
 
@@ -1178,19 +1159,15 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
             new Thread() {
                 public void run() {
                     try {
-
-
                         int iconId = R.drawable.ic_stat_tor;
 
-                        if (hasConnectivity() && Prefs.expandedNotifications())
+                        if (conn != null && mCurrentStatus == STATUS_ON && Prefs.expandedNotifications())
                             showToolbarNotification(getString(R.string.newnym), getNotifyId(), iconId);
 
-                        conn.signal("NEWNYM");
+                        conn.signal(TorControlCommands.SIGNAL_NEWNYM);
 
                     } catch (Exception ioe) {
-
                         debug("error requesting newnym: " + ioe.getLocalizedMessage());
-
                     }
                 }
             }.start();
@@ -1285,10 +1262,8 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
     protected void sendCallbackStatus(String currentStatus) {
         mCurrentStatus = currentStatus;
         Intent intent = getActionStatusIntent(currentStatus);
-        // send for Orbot internals, using secure local broadcast
-        sendBroadcastOnlyToOrbot(intent);
-        // send for any apps that are interested
-        sendBroadcast(intent);
+        sendBroadcastOnlyToOrbot(intent); // send for Orbot internals, using secure local broadcast
+        sendBroadcast(intent); // send for any apps that are interested
     }
 
     /**
@@ -1685,14 +1660,9 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
 
     }
 
-    public boolean hasConnectivity() {
-        return mConnectivity;
-    }
-
     public int getNotifyId() {
         return NOTIFY_ID;
     }
-
     private void loadBridgeDefaults() {
         if (alBridges == null) {
             alBridges = new ArrayList<>();
@@ -1776,6 +1746,12 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
         }
     }
 
+    // for bridge loading from the assets default bridges.txt file
+    static class Bridge {
+        String type;
+        String config;
+    }
+
     private class IncomingIntentRouter implements Runnable {
         Intent mIntent;
 
@@ -1846,12 +1822,6 @@ public class OrbotService extends VpnService implements TorServiceConstants, Orb
         }
     }
 
-    // for bridge loading from the assets default bridges.txt file
-    static class Bridge {
-        String type;
-        String config;
-    }
-
     private class ActionBroadcastReceiver extends BroadcastReceiver {
         public void onReceive(Context context, Intent intent) {
             switch (intent.getAction()) {





More information about the tor-commits mailing list