Bug 1476106 - Part 1 - Make it possible to notify Java listeners from GeckoScreenOrientation, too. r=snorp
☠☠ backed out by b7cd9638d4a4 ☠ ☠
authorJan Henning <jh+bugzilla@buttercookie.de>
Thu, 02 Aug 2018 21:10:33 +0200
changeset 430555 3b1084efc943a6819dfb067437918010d17d4a25
parent 430554 6d885f08136bb257b5a3a1e4758db3a2198ce351
child 430556 deb22f602d59ebe947e568749d4075ed2d563640
push id67508
push usermozilla@buttercookie.de
push dateWed, 08 Aug 2018 14:45:07 +0000
treeherderautoland@bf1f28e2b46d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1476106
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1476106 - Part 1 - Make it possible to notify Java listeners from GeckoScreenOrientation, too. r=snorp Once responsibility for notifying GeckoScreenOrientation of potentially changed screen orientations moves from GeckoApp into GeckoView, the former will no longer be able to benefit from the return value of calling GeckoScreen- Orientation.update(), indicating whether the orientation actually changed or in fact remained the same. GeckoApp however requires that information in order to reset/refresh parts of the UI when the orientation changes, and since GeckoScreenOrientation is already doing all the work of tracking screen orientation changes, we don't want to have to partially duplicate those efforts again in GeckoApp. Instead, we introduce a mechanism for GeckoScreenOrientation to notify interested parties on the Android app side as well. The GeckoScreenOrientation.update() call in GeckoApp.onResume() is removed completely (as opposed to merely removing the refreshChrome() bit) at this stage already because it is unnecessary. If any screen rotation happened while the activity was in background, it will receive an onConfigurationChanged() call anyway before being resumed again. MozReview-Commit-ID: Ila1evcj8Ud
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoScreenOrientation.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import org.mozilla.gecko.AppConstants.Versions;
 import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
+import org.mozilla.gecko.GeckoScreenOrientation.ScreenOrientation;
 import org.mozilla.gecko.annotation.RobocopTarget;
 import org.mozilla.gecko.annotation.WrapForJNI;
 import org.mozilla.gecko.health.HealthRecorder;
 import org.mozilla.gecko.health.SessionInformation;
 import org.mozilla.gecko.health.StubbedHealthRecorder;
 import org.mozilla.gecko.home.HomeConfig.PanelType;
 import org.mozilla.gecko.menu.GeckoMenu;
 import org.mozilla.gecko.menu.GeckoMenuInflater;
@@ -107,16 +108,17 @@ import static org.mozilla.gecko.Tabs.INV
 import static org.mozilla.gecko.mma.MmaDelegate.DOWNLOAD_MEDIA_SAVED_IMAGE;
 import static org.mozilla.gecko.mma.MmaDelegate.READER_AVAILABLE;
 
 public abstract class GeckoApp extends GeckoActivity
                                implements AnchoredPopup.OnVisibilityChangeListener,
                                           BundleEventListener,
                                           GeckoMenu.Callback,
                                           GeckoMenu.MenuPresenter,
+                                          GeckoScreenOrientation.OrientationChangeListener,
                                           GeckoSession.ContentDelegate,
                                           ScreenOrientationDelegate,
                                           Tabs.OnTabsChangedListener,
                                           ViewTreeObserver.OnGlobalLayoutListener {
 
     private static final String LOGTAG = "GeckoApp";
     private static final long ONE_DAY_MS = TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS);
 
@@ -976,16 +978,17 @@ public abstract class GeckoApp extends G
         earlyStartJavaSampler(intent);
 
         // Workaround for <http://code.google.com/p/android/issues/detail?id=20915>.
         try {
             Class.forName("android.os.AsyncTask");
         } catch (ClassNotFoundException e) { }
 
         GeckoAppShell.setScreenOrientationDelegate(this);
+        GeckoScreenOrientation.getInstance().addListener(this);
 
         // Tell Stumbler to register a local broadcast listener to listen for preference intents.
         // We do this via intents since we can't easily access Stumbler directly,
         // as it might be compiled outside of Fennec.
         final Intent stumblerIntent = new Intent(getApplicationContext(), SafeReceiver.class);
         stumblerIntent.setAction(INTENT_REGISTER_STUMBLER_LISTENER);
         getApplicationContext().sendBroadcast(stumblerIntent);
 
@@ -1924,21 +1927,16 @@ public abstract class GeckoApp extends G
         if (mIsAbortingAppLaunch) {
             return;
         }
 
         foregrounded = true;
 
         GeckoAppShell.setScreenOrientationDelegate(this);
 
-        int newOrientation = getResources().getConfiguration().orientation;
-        if (GeckoScreenOrientation.getInstance().update(newOrientation)) {
-            refreshChrome();
-        }
-
         // We use two times: a pseudo-unique wall-clock time to identify the
         // current session across power cycles, and the elapsed realtime to
         // track the duration of the session.
         final long now = System.currentTimeMillis();
         final long realTime = android.os.SystemClock.elapsedRealtime();
 
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
@@ -2128,16 +2126,18 @@ public abstract class GeckoApp extends G
             });
         }
 
         super.onDestroy();
 
         Tabs.unregisterOnTabsChangedListener(this);
         Tabs.getInstance().detachFromContext();
 
+        GeckoScreenOrientation.getInstance().removeListener(this);
+
         if (mShutdownOnDestroy) {
             GeckoApplication.shutdown(!mRestartOnShutdown ? null : new Intent(
                     Intent.ACTION_MAIN, /* uri */ null, getApplicationContext(), getClass()));
         }
     }
 
     public void showSDKVersionError() {
         final String message = getString(R.string.unsupported_sdk_version,
@@ -2175,21 +2175,17 @@ public abstract class GeckoApp extends G
         final Locale changed = localeManager.onSystemConfigurationChanged(this, getResources(), newConfig, mLastLocale);
         if (changed != null) {
             onLocaleChanged(Locales.getLanguageTag(changed));
         }
 
         // onConfigurationChanged is not called for 180 degree orientation changes,
         // we will miss such rotations and the screen orientation will not be
         // updated.
-        if (GeckoScreenOrientation.getInstance().update(newConfig.orientation)) {
-            if (mFormAssistPopup != null)
-                mFormAssistPopup.hide();
-            refreshChrome();
-        }
+        GeckoScreenOrientation.getInstance().update(newConfig.orientation);
 
         if (mPromptService != null) {
             mPromptService.changePromptOrientation(newConfig.orientation);
         }
 
         super.onConfigurationChanged(newConfig);
     }
 
@@ -2522,9 +2518,17 @@ public abstract class GeckoApp extends G
         // We want to support the Screen Orientation API, and it always makes sense to lock the
         // orientation of a browser Activity, so we support locking.
         if (getRequestedOrientation() == requestedActivityInfoOrientation) {
             return false;
         }
         setRequestedOrientation(requestedActivityInfoOrientation);
         return true;
     }
+
+    @Override
+    public void onScreenOrientationChanged(ScreenOrientation newOrientation) {
+        if (mFormAssistPopup != null) {
+            mFormAssistPopup.hide();
+        }
+        refreshChrome();
+    }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoScreenOrientation.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoScreenOrientation.java
@@ -9,16 +9,17 @@ import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.util.Log;
 import android.view.Surface;
 import android.view.WindowManager;
 
 import org.mozilla.gecko.annotation.WrapForJNI;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 /*
  * Updates, locks and unlocks the screen orientation.
  *
  * Note: Replaces the OnOrientationChangeListener to avoid redundant rotation
  * event handling.
@@ -59,27 +60,48 @@ public class GeckoScreenOrientation {
     private static GeckoScreenOrientation sInstance;
     // Default rotation, used when device rotation is unknown.
     private static final int DEFAULT_ROTATION = Surface.ROTATION_0;
     // Last updated screen orientation.
     private ScreenOrientation mScreenOrientation;
     // Whether the update should notify Gecko about screen orientation changes.
     private boolean mShouldNotify = true;
 
+    public interface OrientationChangeListener {
+        void onScreenOrientationChanged(ScreenOrientation newOrientation);
+    }
+
+    private final List<OrientationChangeListener> mListeners;
+
     public static GeckoScreenOrientation getInstance() {
         if (sInstance == null) {
             sInstance = new GeckoScreenOrientation();
         }
         return sInstance;
     }
 
     private GeckoScreenOrientation() {
+        mListeners = new ArrayList<>();
         update();
     }
 
+    /**
+     * Add a listener that will be notified when the screen orientation has changed.
+     */
+    public void addListener(OrientationChangeListener aListener) {
+        mListeners.add(aListener);
+    }
+
+    /**
+     * Remove a OrientationChangeListener again.
+     */
+    public void removeListener(OrientationChangeListener aListener) {
+        mListeners.remove(aListener);
+    }
+
     /*
      * Enable Gecko screen orientation events on update.
      */
     public void enableNotifications() {
         update();
         mShouldNotify = true;
     }
 
@@ -130,16 +152,19 @@ public class GeckoScreenOrientation {
      * @return Whether the screen orientation has changed.
      */
     public boolean update(ScreenOrientation aScreenOrientation) {
         if (mScreenOrientation == aScreenOrientation) {
             return false;
         }
         mScreenOrientation = aScreenOrientation;
         Log.d(LOGTAG, "updating to new orientation " + mScreenOrientation);
+        for (OrientationChangeListener listener : mListeners) {
+            listener.onScreenOrientationChanged(mScreenOrientation);
+        }
         if (mShouldNotify) {
             // Gecko expects a definite screen orientation, so we default to the
             // primary orientations.
             if (aScreenOrientation == ScreenOrientation.PORTRAIT) {
                 aScreenOrientation = ScreenOrientation.PORTRAIT_PRIMARY;
             } else if (aScreenOrientation == ScreenOrientation.LANDSCAPE) {
                 aScreenOrientation = ScreenOrientation.LANDSCAPE_PRIMARY;
             }