Bug 1336734 - Part 1 - Have GeckoPreferences properly support GeckoActivityStatus. r?sebastian draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Sun, 05 Feb 2017 15:35:00 +0100
changeset 479463 e37983b61517ff11b220365b8710d993af48159d
parent 479101 f26c222a5fff502a64ccfccdb101a78280329a53
child 479464 1838c30e259032f193138f866330f9570151b417
child 479510 2c6dc9721c25fd660293e619092be8c531fb54c7
push id44266
push usermozilla@buttercookie.de
push dateMon, 06 Feb 2017 19:35:12 +0000
reviewerssebastian
bugs1336734
milestone54.0a1
Bug 1336734 - Part 1 - Have GeckoPreferences properly support GeckoActivityStatus. r?sebastian Currently, GeckoPreferences always returns "false" for isGeckoActivityOpened(), which means that when we're e.g. opening a new settings screen, GeckoApplication's onActivityPause() code assumes that Firefox is being backgrounded for real, calling GeckoThread.onPause(). This is then immediately followed by a call to onActivityResume() which unpauses Gecko again. To avoid this, GeckoPreferences needs to properly implement support for GeckoActivityStatus and check the target of outgoing intents along the lines of the implementation in GeckoActivity. MozReview-Commit-ID: UfPNAic5os
mobile/android/base/java/org/mozilla/gecko/GeckoActivity.java
mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoActivity.java
@@ -4,17 +4,17 @@
 
 package org.mozilla.gecko;
 
 import android.content.ComponentName;
 import android.content.Intent;
 import android.support.v7.app.AppCompatActivity;
 
 public abstract class GeckoActivity extends AppCompatActivity implements GeckoActivityStatus {
-    // has this activity recently started another Gecko activity?
+    // Has this activity recently started another Gecko activity?
     private boolean mGeckoActivityOpened;
 
     /**
      * Display any resources that show strings or encompass locale-specific
      * representations.
      *
      * onLocaleReady must always be called on the UI thread.
      */
@@ -63,23 +63,27 @@ public abstract class GeckoActivity exte
     }
 
     @Override
     public void startActivityForResult(Intent intent, int request) {
         mGeckoActivityOpened = checkIfGeckoActivity(intent);
         super.startActivityForResult(intent, request);
     }
 
-    private static boolean checkIfGeckoActivity(Intent intent) {
-        // Whenever we call our own activity, the component and its package name is set.
+    public static boolean checkIfGeckoActivity(Intent intent) {
+        // Whenever we call our own activity, either the component and its package name is set,
+        // or else the intent is for an action where we know that we'll stay within our app.
         // If we call an activity from another package, or an open intent (leaving android to resolve)
         // component has a different package name or it is null.
         ComponentName component = intent.getComponent();
+        String action = intent.getAction();
         return (component != null &&
-                AppConstants.ANDROID_PACKAGE_NAME.equals(component.getPackageName()));
+                AppConstants.ANDROID_PACKAGE_NAME.equals(component.getPackageName()) ||
+                action != null &&
+                action.startsWith(AppConstants.ANDROID_PACKAGE_NAME + ".ACTION_FXA_"));
     }
 
     @Override
     public boolean isGeckoActivityOpened() {
         return mGeckoActivityOpened;
     }
 
     public boolean isApplicationInBackground() {
--- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
+++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java
@@ -10,16 +10,17 @@ import org.mozilla.gecko.AboutPages;
 import org.mozilla.gecko.AdjustConstants;
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.BrowserApp;
 import org.mozilla.gecko.BrowserLocaleManager;
 import org.mozilla.gecko.DataReportingNotification;
 import org.mozilla.gecko.DynamicToolbar;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.Experiments;
+import org.mozilla.gecko.GeckoActivity;
 import org.mozilla.gecko.GeckoActivityStatus;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoApplication;
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.GeckoSharedPrefs;
 import org.mozilla.gecko.LocaleManager;
 import org.mozilla.gecko.Locales;
 import org.mozilla.gecko.PrefsHelper;
@@ -117,16 +118,19 @@ public class GeckoPreferences
     private static final int NO_SUCH_ID = 0;
 
     public static final String NON_PREF_PREFIX = "android.not_a_preference.";
     public static final String INTENT_EXTRA_RESOURCES = "resource";
     public static final String PREFS_TRACKING_PROTECTION_PROMPT_SHOWN = NON_PREF_PREFIX + "trackingProtectionPromptShown";
     public static final String PREFS_HEALTHREPORT_UPLOAD_ENABLED = NON_PREF_PREFIX + "healthreport.uploadEnabled";
     public static final String PREFS_SYNC = NON_PREF_PREFIX + "sync";
 
+    // Has this activity recently started another Gecko activity?
+    private boolean mGeckoActivityOpened;
+
     private static boolean sIsCharEncodingEnabled;
     private boolean mInitialized;
     private PrefsHelper.PrefHandler mPrefsRequest;
     private List<Header> mHeaders;
 
     // These match keys in resources/xml*/preferences*.xml
     private static final String PREFS_SEARCH_RESTORE_DEFAULTS = NON_PREF_PREFIX + "search.restore_defaults";
     private static final String PREFS_DATA_REPORTING_PREFERENCES = NON_PREF_PREFIX + "datareporting.preferences";
@@ -542,16 +546,17 @@ public class GeckoPreferences
     @Override
     public void onResume() {
         super.onResume();
 
         EventDispatcher.getInstance().registerUiThreadListener(this, "Snackbar:Show");
 
         if (getApplication() instanceof GeckoApplication) {
             ((GeckoApplication) getApplication()).onActivityResume(this);
+            mGeckoActivityOpened = false;
         }
 
         // Watch prefs, otherwise we don't reliably get told when they change.
         // See documentation for onSharedPreferenceChange for more.
         // Inexplicably only needed on tablet.
         if (isMultiPane()) {
             SharedPreferences prefs = GeckoSharedPrefs.forApp(this);
             prefs.registerOnSharedPreferenceChangeListener(this);
@@ -565,25 +570,32 @@ public class GeckoPreferences
         // Specifically, when we open a link, we want to back out of all
         // the settings screens.
         // We need to start nested PreferenceScreens withStartActivityForResult().
         // Android doesn't let us do that (see Preference.onClick), so we're overriding here.
         startActivityForResultChoosingTransition(intent, REQUEST_CODE_PREF_SCREEN);
     }
 
     @Override
+    public void startActivityForResult(Intent intent, int request) {
+        mGeckoActivityOpened = GeckoActivity.checkIfGeckoActivity(intent);
+        super.startActivityForResult(intent, request);
+    }
+
+    @Override
     public void startWithFragment(String fragmentName, Bundle args,
             Fragment resultTo, int resultRequestCode, int titleRes, int shortTitleRes) {
         Log.v(LOGTAG, "Starting with fragment: " + fragmentName + ", title " + titleRes);
 
         // Overriding because we want to use startActivityForResult for Fragment intents.
         Intent intent = onBuildStartFragmentIntent(fragmentName, args, titleRes, shortTitleRes);
         if (resultTo == null) {
             startActivityForResultChoosingTransition(intent, REQUEST_CODE_PREF_SCREEN);
         } else {
+            mGeckoActivityOpened = GeckoActivity.checkIfGeckoActivity(intent);
             resultTo.startActivityForResult(intent, resultRequestCode);
             if (NO_TRANSITIONS) {
                 overridePendingTransition(0, 0);
             }
         }
     }
 
     @Override
@@ -1492,17 +1504,17 @@ public class GeckoPreferences
         final PrefsHelper.PrefHandler prefHandler = new PrefCallbacks(screen);
         final String[] prefNames = prefs.toArray(new String[prefs.size()]);
         PrefsHelper.addObserver(prefNames, prefHandler);
         return prefHandler;
     }
 
     @Override
     public boolean isGeckoActivityOpened() {
-        return false;
+        return mGeckoActivityOpened;
     }
 
     /**
      * Given an Intent instance, add extras to specify which settings section to
      * open.
      *
      * resource should be a valid Android XML resource identifier.
      *