Bug 1338673 - Implement GeckoActivityStatus for the FxAccountStatusActivity. r?sebastian draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Mon, 06 Feb 2017 20:30:20 +0100
changeset 482053 1e8cdce166c28ac7dde4e4ed334d863d7f2c4005
parent 482043 e76de64093c529729c021781e09cbbffe7d6834f
child 545351 7aa8f94583bbfc27d4a439f61f9c99d1e6566377
push id44993
push usermozilla@buttercookie.de
push dateFri, 10 Feb 2017 22:00:14 +0000
reviewerssebastian
bugs1338673
milestone54.0a1
Bug 1338673 - Implement GeckoActivityStatus for the FxAccountStatusActivity. r?sebastian Since we want to avoid pausing Gecko when entering this activity, it must implement this interface so we can still properly pause Gecko if we get backgrounded while on the Sync preferences screen. Most actions here are actually done via the application context (i.e. GeckoApplication), so overriding startActivity et al. and using mGeckoActivityOpened doesn't achieve all that much for most cases, but since we currently at most exit the screen (activity is finishing, so won't trigger a GeckoThread.onPause() call) and stay within our application (open a new tab in Firefox), we're still fine for now. MozReview-Commit-ID: 3760hXMjckX
mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IntentUtils.java
mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IntentUtils.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/IntentUtils.java
@@ -112,16 +112,20 @@ public class IntentUtils {
     /**
      * Checks whether the target of the passed intent will result in us opening one
      * of our own activities or not.
      *
      * @param intent The intent to be checked.
      * @return True if the intent target is within our app.
      */
     public static boolean checkIfGeckoActivity(Intent intent) {
-        // Whenever we call our own activity, the component and its package name is set.
+        // 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_"));
     }
 }
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusActivity.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusActivity.java
@@ -22,31 +22,37 @@ import android.support.v7.widget.Toolbar
 import android.util.TypedValue;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.Window;
 import android.widget.Toast;
 import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.GeckoActivityStatus;
+import org.mozilla.gecko.GeckoApplication;
+import org.mozilla.gecko.util.IntentUtils;
 import org.mozilla.gecko.Locales.LocaleAwareAppCompatActivity;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.background.fxa.FxAccountUtils;
 import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.sync.Utils;
 
 /**
  * Activity which displays account status.
  */
-public class FxAccountStatusActivity extends LocaleAwareAppCompatActivity {
+public class FxAccountStatusActivity extends LocaleAwareAppCompatActivity implements GeckoActivityStatus {
   private static final String LOG_TAG = FxAccountStatusActivity.class.getSimpleName();
 
+  // Has this activity recently started another Gecko activity?
+  private boolean mGeckoActivityOpened;
+
   protected FxAccountStatusFragment statusFragment;
 
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
 
     // Display the fragment as the content.
     statusFragment = new FxAccountStatusFragment();
@@ -76,19 +82,33 @@ public class FxAccountStatusActivity ext
       actionBar.setHomeButtonEnabled(true);
       actionBar.setDisplayHomeAsUpEnabled(true);
       return;
     }
     Logger.debug(LOG_TAG, "Not enabling home button.");
   }
 
   @Override
+  public void onPause() {
+    super.onPause();
+
+    if (getApplication() instanceof GeckoApplication) {
+      ((GeckoApplication) getApplication()).onActivityPause(this);
+    }
+  }
+
+  @Override
   public void onResume() {
     super.onResume();
 
+    if (getApplication() instanceof GeckoApplication) {
+      ((GeckoApplication) getApplication()).onActivityResume(this);
+      mGeckoActivityOpened = false;
+    }
+
     final AndroidFxAccount fxAccount = getAndroidFxAccount();
     if (fxAccount == null) {
       Logger.warn(LOG_TAG, "Could not get Firefox Account.");
 
       // Gracefully redirect to get started.
       final Intent intent = new Intent(FxAccountConstants.ACTION_FXA_GET_STARTED);
       // Per http://stackoverflow.com/a/8992365, this triggers a known bug with
       // the soft keyboard not being shown for the started activity. Why, Android, why?
@@ -97,16 +117,28 @@ public class FxAccountStatusActivity ext
 
       setResult(RESULT_CANCELED);
       finish();
       return;
     }
     statusFragment.refresh(fxAccount);
   }
 
+  @Override
+  public void startActivity(Intent intent) {
+    mGeckoActivityOpened = IntentUtils.checkIfGeckoActivity(intent);
+    super.startActivity(intent);
+  }
+
+  @Override
+  public void startActivityForResult(Intent intent, int request) {
+    mGeckoActivityOpened = IntentUtils.checkIfGeckoActivity(intent);
+    super.startActivityForResult(intent, request);
+  }
+
   /**
    * Helper to fetch (unique) Android Firefox Account if one exists, or return null.
    */
   protected AndroidFxAccount getAndroidFxAccount() {
     Account account = FirefoxAccounts.getFirefoxAccount(this);
     if (account == null) {
       return null;
     }
@@ -200,17 +232,17 @@ public class FxAccountStatusActivity ext
     } else {
       final MenuItem debugModeItem = menu.findItem(R.id.enable_debug_mode);
       if (debugModeItem != null) {
         // Update checked state based on internal flag.
         menu.findItem(R.id.enable_debug_mode).setChecked(FxAccountUtils.LOG_PERSONAL_INFORMATION);
       }
     }
     return super.onCreateOptionsMenu(menu);
-  };
+  }
 
   @Override
   public void openOptionsMenu() {
     // This is a workaround of an Android bug:
     // https://code.google.com/p/android/issues/detail?id=185217
     // openOptionsMenu isn't overriden by WindowDecorActionBar, which is used by AppCompatActivity,
     // meaning getSupportActionbar().openOptionsMenu doesn't work.
     // Based loosely on the code in:
@@ -220,9 +252,14 @@ public class FxAccountStatusActivity ext
     final View decor = window.getDecorView();
     final View view = decor.findViewById(R.id.action_bar);
 
     if (view instanceof Toolbar) {
       final Toolbar toolbar = (Toolbar) view;
       toolbar.showOverflowMenu();
     }
   }
+
+  @Override
+  public boolean isGeckoActivityOpened() {
+    return mGeckoActivityOpened;
+  }
 }
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java
@@ -224,16 +224,21 @@ public class FxAccountStatusFragment
    * We intentionally don't refresh here. Our owning activity is responsible for
    * providing an AndroidFxAccount to our refresh method in its onResume method.
    */
   @Override
   public void onResume() {
     super.onResume();
   }
 
+  /**
+   * Note: If we ever start doing anything more fancy here with the application context
+   * than just opening new tabs in Fennec, we need to revisit FxAccountStatusActivity's
+   * GeckoActivityStatus implementation (see bug 1336734/1338673 for history).
+   */
   @Override
   public boolean onPreferenceClick(Preference preference) {
     if (preference == profilePreference) {
       ActivityUtils.openURLInFennec(getActivity().getApplicationContext(), "about:accounts?action=avatar");
       return true;
     }
 
     if (preference == manageAccountPreference) {