| Index: content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java
|
| diff --git a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java
|
| index 79b8ddbb7b366045c553d47fd21c89c4c55d0211..7df980c1c137dce344fcd8aabd4e83fcaf9efb95 100644
|
| --- a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java
|
| +++ b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationListener.java
|
| @@ -18,7 +18,11 @@ import android.view.WindowManager;
|
| import org.chromium.base.ObserverList;
|
| import org.chromium.base.ThreadUtils;
|
| import org.chromium.base.VisibleForTesting;
|
| -import org.chromium.ui.gfx.DeviceDisplayInfo;
|
| +
|
| +import java.lang.ref.WeakReference;
|
| +import java.util.Collections;
|
| +import java.util.Set;
|
| +import java.util.WeakHashMap;
|
|
|
| /**
|
| * ScreenOrientationListener is a class that informs its observers when the
|
| @@ -59,19 +63,6 @@ public class ScreenOrientationListener {
|
| * when the last observer is removed.
|
| */
|
| void stopListening();
|
| -
|
| - /**
|
| - * Toggle the accurate mode if it wasn't already doing so. The backend
|
| - * will keep track of the number of times this has been called.
|
| - */
|
| - void startAccurateListening();
|
| -
|
| - /**
|
| - * Request to stop the accurate mode. It will effectively be stopped
|
| - * only if this method is called as many times as
|
| - * startAccurateListening().
|
| - */
|
| - void stopAccurateListening();
|
| }
|
|
|
| /**
|
| @@ -89,46 +80,20 @@ public class ScreenOrientationListener {
|
|
|
| private static final long POLLING_DELAY = 500;
|
|
|
| - private int mAccurateCount = 0;
|
| -
|
| // ScreenOrientationListenerBackend implementation:
|
|
|
| @Override
|
| public void startListening() {
|
| - mAppContext.registerComponentCallbacks(this);
|
| + Context context = mContext.get();
|
| + if (context != null) context.registerComponentCallbacks(this);
|
| }
|
|
|
| @Override
|
| public void stopListening() {
|
| - mAppContext.unregisterComponentCallbacks(this);
|
| - }
|
| -
|
| - @Override
|
| - public void startAccurateListening() {
|
| - ++mAccurateCount;
|
| -
|
| - if (mAccurateCount > 1) return;
|
| -
|
| - // Start polling if we went from 0 to 1. The polling will
|
| - // automatically stop when mAccurateCount reaches 0.
|
| - final ScreenOrientationConfigurationListener self = this;
|
| - ThreadUtils.postOnUiThreadDelayed(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - self.onConfigurationChanged(null);
|
| -
|
| - if (self.mAccurateCount < 1) return;
|
| -
|
| - ThreadUtils.postOnUiThreadDelayed(this,
|
| - ScreenOrientationConfigurationListener.POLLING_DELAY);
|
| - }
|
| - }, POLLING_DELAY);
|
| - }
|
| -
|
| - @Override
|
| - public void stopAccurateListening() {
|
| - --mAccurateCount;
|
| - assert mAccurateCount >= 0;
|
| + Context context = mContext.get();
|
| + if (context != null) context.unregisterComponentCallbacks(this);
|
| + // TODO(gsennton) what if the context has already been destroyed (and we can't
|
| + // unregister the callback)?
|
| }
|
|
|
| // ComponentCallbacks implementation:
|
| @@ -157,28 +122,25 @@ public class ScreenOrientationListener {
|
|
|
| @Override
|
| public void startListening() {
|
| + Context context = mContext.get();
|
| + if (context == null) return;
|
| +
|
| DisplayManager displayManager =
|
| - (DisplayManager) mAppContext.getSystemService(Context.DISPLAY_SERVICE);
|
| + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
| displayManager.registerDisplayListener(this, null);
|
| }
|
|
|
| @Override
|
| public void stopListening() {
|
| + Context context = mContext.get();
|
| + if (context == null) return;
|
| + // TODO(gsennton) what if the context has already been destroyed (and we can't
|
| + // unregister the display listener)?
|
| DisplayManager displayManager =
|
| - (DisplayManager) mAppContext.getSystemService(Context.DISPLAY_SERVICE);
|
| + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
|
| displayManager.unregisterDisplayListener(this);
|
| }
|
|
|
| - @Override
|
| - public void startAccurateListening() {
|
| - // Always accurate. Do nothing.
|
| - }
|
| -
|
| - @Override
|
| - public void stopAccurateListening() {
|
| - // Always accurate. Do nothing.
|
| - }
|
| -
|
| // DisplayListener implementation:
|
|
|
| @Override
|
| @@ -207,31 +169,23 @@ public class ScreenOrientationListener {
|
| // starting to listen again.
|
| private int mOrientation;
|
|
|
| - // Current application context derived from the first context being received.
|
| - private Context mAppContext;
|
| + private WeakReference<Context> mContext;
|
|
|
| private ScreenOrientationListenerBackend mBackend;
|
|
|
| - private static ScreenOrientationListener sInstance;
|
| -
|
| - /**
|
| - * Returns a ScreenOrientationListener implementation based on the device's
|
| - * supported API level.
|
| - */
|
| - public static ScreenOrientationListener getInstance() {
|
| - ThreadUtils.assertOnUiThread();
|
| -
|
| - if (sInstance == null) {
|
| - sInstance = new ScreenOrientationListener();
|
| - }
|
| -
|
| - return sInstance;
|
| - }
|
| + private static Set<ScreenOrientationListener> sListeners =
|
| + Collections.newSetFromMap(new WeakHashMap<ScreenOrientationListener, Boolean>());
|
| + private static int sAccurateCount = 0;
|
|
|
| - private ScreenOrientationListener() {
|
| + public ScreenOrientationListener(Context context) {
|
| + mContext = new WeakReference<Context>(context);
|
| mBackend = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
|
| ? new ScreenOrientationDisplayListener()
|
| : new ScreenOrientationConfigurationListener();
|
| + // TODO(gsennton) is sListeners thread safe? Does it need to be?
|
| +
|
| + // Only add a listener for polling if it is not already accurate enough
|
| + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) sListeners.add(this);
|
| }
|
|
|
| /**
|
| @@ -240,16 +194,8 @@ public class ScreenOrientationListener {
|
| * orientation value.
|
| *
|
| * @param observer The observer that will get notified.
|
| - * @param context The context associated with this observer.
|
| */
|
| - public void addObserver(ScreenOrientationObserver observer, Context context) {
|
| - if (mAppContext == null) {
|
| - mAppContext = context.getApplicationContext();
|
| - }
|
| -
|
| - assert mAppContext == context.getApplicationContext();
|
| - assert mAppContext != null;
|
| -
|
| + public void addObserver(ScreenOrientationObserver observer) {
|
| if (!mObservers.addObserver(observer)) {
|
| Log.w(TAG, "Adding an observer that is already present!");
|
| return;
|
| @@ -291,22 +237,6 @@ public class ScreenOrientationListener {
|
| }
|
|
|
| /**
|
| - * Toggle the accurate mode if it wasn't already doing so. The backend will
|
| - * keep track of the number of times this has been called.
|
| - */
|
| - public void startAccurateListening() {
|
| - mBackend.startAccurateListening();
|
| - }
|
| -
|
| - /**
|
| - * Request to stop the accurate mode. It will effectively be stopped only if
|
| - * this method is called as many times as startAccurateListening().
|
| - */
|
| - public void stopAccurateListening() {
|
| - mBackend.stopAccurateListening();
|
| - }
|
| -
|
| - /**
|
| * This should be called by classes extending ScreenOrientationListener when
|
| * it is possible that there is a screen orientation change. If there is an
|
| * actual change, the observers will get notified.
|
| @@ -319,7 +249,8 @@ public class ScreenOrientationListener {
|
| return;
|
| }
|
|
|
| - DeviceDisplayInfo.create(mAppContext).updateNativeSharedDisplayInfo();
|
| + // TODO(gsennton) if we cache a shared instance of
|
| + // DeviceDisplayInfo then update the cache here (or add that instance as an observer)
|
|
|
| for (ScreenOrientationObserver observer : mObservers) {
|
| observer.onScreenOrientationChanged(mOrientation);
|
| @@ -330,8 +261,11 @@ public class ScreenOrientationListener {
|
| * Updates |mOrientation| based on the default display rotation.
|
| */
|
| private void updateOrientation() {
|
| + Context context = mContext.get();
|
| + if (context == null) return;
|
| +
|
| WindowManager windowManager =
|
| - (WindowManager) mAppContext.getSystemService(Context.WINDOW_SERVICE);
|
| + (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
|
|
| switch (windowManager.getDefaultDisplay().getRotation()) {
|
| case Surface.ROTATION_0:
|
| @@ -351,4 +285,29 @@ public class ScreenOrientationListener {
|
| "Display.getRotation() shouldn't return that value");
|
| }
|
| }
|
| +
|
| + public static void startAccurateListening() {
|
| + sAccurateCount++;
|
| + if (sAccurateCount > 1) return;
|
| +
|
| + ThreadUtils.postOnUiThreadDelayed(new Runnable() {
|
| + @Override
|
| + public void run() {
|
| + for (ScreenOrientationListener listener : sListeners) {
|
| + if (listener != null) listener.notifyObservers();
|
| + }
|
| +
|
| + if (sAccurateCount < 1) return;
|
| +
|
| + ThreadUtils.postOnUiThreadDelayed(
|
| + this, ScreenOrientationConfigurationListener.POLLING_DELAY);
|
| + }
|
| + }, ScreenOrientationConfigurationListener.POLLING_DELAY);
|
| + }
|
| +
|
| + public static void stopAccurateListening() {
|
| + sAccurateCount--;
|
| + if (sAccurateCount > 0) return;
|
| + assert sAccurateCount == 0;
|
| + }
|
| }
|
|
|