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
--- 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