Bug 1359531 - Part 8 - Handle tabs selected while all GeckoApps were in background. r?sebastian,walkingice draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Fri, 05 May 2017 21:07:29 +0200
changeset 582516 1e917efd731c8721a91c983d77110942bb6aaf54
parent 582515 cc45edff37ea657a45346e14eb88934a5fd29978
child 629806 3099733967d4076dc9cfff587ad26205ce8311a6
push id60121
push usermozilla@buttercookie.de
push dateMon, 22 May 2017 19:37:24 +0000
reviewerssebastian, walkingice
bugs1359531
milestone55.0a1
Bug 1359531 - Part 8 - Handle tabs selected while all GeckoApps were in background. r?sebastian,walkingice Activity switching is now handled by the currently active GeckoApp instance, which obviously doesn't work if all of them are currently backgrounded. To fix this, we track for each tab whether its selection was handled by a foregrounded GeckoApp instance. If it wasn't, we catch up with any possibly necessary activity switches during the next resume. MozReview-Commit-ID: JEjQUuDJw5Q
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/Tab.java
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -1176,23 +1176,16 @@ public class BrowserApp extends GeckoApp
 
         for (BrowserAppDelegate delegate : delegates) {
             delegate.onResume(this);
         }
     }
 
     @Override
     protected void restoreLastSelectedTab() {
-        if (mIgnoreLastSelectedTab) {
-            // We're either the first activity to run, so our startup code will (have) handle(d) tab
-            // selection, or else we've received a new intent and want to open and select a new tab
-            // as well.
-            return;
-        }
-
         if (mLastSelectedTabId < 0) {
             // Normally, session restore will select the correct tab when starting up, however this
             // is linked to Gecko powering up. If we're not the first activity to launch, the
             // previously running activity might have already overwritten this by selecting a tab of
             // its own.
             // Therefore we check whether the session file parser has left a note for us with the
             // correct tab to be initially selected on *BrowserApp* startup.
             SharedPreferences prefs = getSharedPreferencesForProfile();
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -432,16 +432,20 @@ public abstract class GeckoApp extends G
                     resetFormAssistPopup();
                 }
                 break;
 
             case SELECTED:
                 resetOptionsMenu();
                 resetFormAssistPopup();
 
+                if (foregrounded) {
+                    tab.setWasSelectedInForeground(true);
+                }
+
                 if (mLastSelectedTabId != INVALID_TAB_ID && foregrounded &&
                         // mSuppressActivitySwitch implies that we want to defer a pending
                         // activity switch because we're actually about to leave the app.
                         !mSuppressActivitySwitch && !tab.matchesActivity(this)) {
                     startActivity(IntentHelper.getTabSwitchIntent(tab));
                 } else if (saveAsLastSelectedTab(tab)) {
                     mLastSelectedTabId = tab.getId();
                     mLastSessionUUID = GeckoApplication.getSessionUUID();
@@ -2279,26 +2283,41 @@ public abstract class GeckoApp extends G
             return;
         }
 
         foregrounded = true;
 
         GeckoAppShell.setGeckoInterface(this);
         GeckoAppShell.setScreenOrientationDelegate(this);
 
-        // When backing out of the app triggers a tab close and therefore selects another tab, we
-        // don't switch activities even if the new selected tab is of a different type, because
-        // doing so would bring us into the foreground again.
-        // As this means that the currently selected tab doesn't match the last active GeckoApp, we
-        // need to check mSuppressActivitySwitch as well here.
-        if (mLastActiveGeckoApp == null || mLastActiveGeckoApp.get() != this ||
-                mSuppressActivitySwitch) {
-            mSuppressActivitySwitch = false;
-            restoreLastSelectedTab();
+        // If mIgnoreLastSelectedTab is set, we're either the first activity to run, so our startup
+        // code will (have) handle(d) tab selection, or else we've received a new intent and want to
+        // open and select a new tab as well.
+        if (!mIgnoreLastSelectedTab) {
+            Tab selectedTab = Tabs.getInstance().getSelectedTab();
+
+            // We need to check if we've selected a different tab while no GeckoApp-based activity
+            // was in foreground and catch up with any activity switches that might be needed.
+            if (selectedTab != null && !selectedTab.getWasSelectedInForeground()) {
+                selectedTab.setWasSelectedInForeground(true);
+                if (!selectedTab.matchesActivity(this)) {
+                    startActivity(IntentHelper.getTabSwitchIntent(selectedTab));
+                }
+
+                // When backing out of the app closes the current tab and therefore selects
+                // another tab, we don't switch activities even if the newly selected tab has a
+                // different type, because doing so would bring us into the foreground again.
+                // As this means that the currently selected tab doesn't match the last active
+                // GeckoApp, we need to check mSuppressActivitySwitch here as well.
+            } else if (mLastActiveGeckoApp == null || mLastActiveGeckoApp.get() != this ||
+                    mSuppressActivitySwitch) {
+                restoreLastSelectedTab();
+            }
         }
+        mSuppressActivitySwitch = false;
         mIgnoreLastSelectedTab = false;
 
         int newOrientation = getResources().getConfiguration().orientation;
         if (GeckoScreenOrientation.getInstance().update(newOrientation)) {
             refreshChrome();
         }
 
         if (mAppStateListeners != null) {
--- a/mobile/android/base/java/org/mozilla/gecko/Tab.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tab.java
@@ -85,16 +85,17 @@ public class Tab {
     private final Context mAppContext;
     private ErrorType mErrorType = ErrorType.NONE;
     private volatile int mLoadProgress;
     private volatile int mRecordingCount;
     private volatile boolean mIsAudioPlaying;
     private volatile boolean mIsMediaPlaying;
     private String mMostRecentHomePanel;
     private boolean mShouldShowToolbarWithoutAnimationOnFirstSelection;
+    private boolean mWasSelectedInForeground;
 
     /*
      * Bundle containing restore data for the panel referenced in mMostRecentHomePanel. This can be
      * e.g. the most recent folder for the bookmarks panel, or any other state that should be
      * persisted. This is then used e.g. when returning to homepanels via history.
      */
     private Bundle mMostRecentHomePanelData;
 
@@ -788,16 +789,24 @@ public class Tab {
     public boolean getDesktopMode() {
         return mDesktopMode;
     }
 
     public boolean isPrivate() {
         return false;
     }
 
+    public void setWasSelectedInForeground(boolean state) {
+        mWasSelectedInForeground = state;
+    }
+
+    public boolean getWasSelectedInForeground() {
+        return mWasSelectedInForeground;
+    }
+
     public TabType getType() {
         return mType;
     }
 
     public enum TabType {
         BROWSING,
         CUSTOMTAB,
         WEBAPP