Chromium Code Reviews| Index: ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java |
| diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java |
| index 11911f02092b1efd12fe7596774c8f784217cee2..94a3122a11189462ce33a8d8b38bc2485052021c 100644 |
| --- a/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java |
| +++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroidManager.java |
| @@ -17,11 +17,15 @@ import android.view.WindowManager; |
| import org.chromium.base.ContextUtils; |
| import org.chromium.base.ThreadUtils; |
| +import org.chromium.base.annotations.CalledByNative; |
| +import org.chromium.base.annotations.JNINamespace; |
| +import org.chromium.base.annotations.SuppressFBWarnings; |
| import org.chromium.ui.gfx.DeviceDisplayInfo; |
| /** |
| * DisplayAndroidManager is a class that informs its observers Display changes. |
| */ |
| +@JNINamespace("ui") |
| /* package */ class DisplayAndroidManager { |
| /** |
| * DisplayListenerBackend is an interface that abstract the mechanism used for the actual |
| @@ -66,13 +70,8 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
| private static final long POLLING_DELAY = 500; |
| - private int mMainSdkDisplayId; |
| private int mAccurateCount; |
| - public DisplayListenerAPI16(int sdkDisplayId) { |
| - mMainSdkDisplayId = sdkDisplayId; |
| - } |
| - |
| // DisplayListenerBackend implementation: |
| @Override |
| @@ -159,6 +158,13 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
| @Override |
| public void onDisplayRemoved(int sdkDisplayId) { |
| + // Never remove the primary display. |
| + if (sdkDisplayId == mMainSdkDisplayId) return; |
| + |
| + DisplayAndroid displayAndroid = mIdMap.get(sdkDisplayId); |
| + if (displayAndroid == null) return; |
| + |
| + if (mNativePointer != 0) nativeRemoveDisplay(mNativePointer, sdkDisplayId); |
| mIdMap.remove(sdkDisplayId); |
| } |
| @@ -174,12 +180,18 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
| private static DisplayAndroidManager sDisplayAndroidManager; |
| + private long mNativePointer; |
| + private int mMainSdkDisplayId; |
| private SparseArray<DisplayAndroid> mIdMap; |
| - private final DisplayListenerBackend mBackend; |
| + private DisplayListenerBackend mBackend; |
| + @SuppressFBWarnings("LI_LAZY_INIT_UPDATE_STATIC") |
| /* package */ static DisplayAndroidManager getInstance() { |
| if (sDisplayAndroidManager == null) { |
| + // Split between creation and initialization to allow for calls |
| + // from DisplayAndroid to DisplayAndroidManager during initialize(). |
| sDisplayAndroidManager = new DisplayAndroidManager(); |
| + sDisplayAndroidManager.initialize(); |
| } |
| return sDisplayAndroidManager; |
| } |
| @@ -206,15 +218,46 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
| DeviceDisplayInfo.create(getContext()).updateNativeSharedDisplayInfo(); |
| } |
| - private DisplayAndroidManager() { |
| + @CalledByNative |
| + private static void onNativeSideCreated(long nativePointer) { |
| + DisplayAndroidManager singleton = getInstance(); |
| + singleton.setNativePointer(nativePointer); |
| + } |
| + |
| + private DisplayAndroidManager() {} |
| + |
| + private void initialize() { |
| mIdMap = new SparseArray<>(); |
| + Display display; |
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { |
| mBackend = new DisplayListenerBackendImpl(); |
| + // Make sure the display map contains the built-in primary display. |
| + // The primary display is never removed. |
| + display = getDisplayManager().getDisplay(Display.DEFAULT_DISPLAY); |
| + |
| + // Android documentation on Display.DEFAULT_DISPLAY suggests that the above |
| + // method might return null. In that case we retrieve the default display |
| + // from the application context and take it as the primary display. |
| + if (display == null) display = getDefaultDisplayForContext(getContext()); |
| } else { |
| - Display display = getDefaultDisplayForContext(getContext()); |
| - mBackend = new DisplayListenerAPI16(display.getDisplayId()); |
| - addDisplay(display); // Note this display is never removed. |
| + mBackend = new DisplayListenerAPI16(); |
| + display = getDefaultDisplayForContext(getContext()); |
| } |
| + |
| + mMainSdkDisplayId = display.getDisplayId(); |
| + addDisplay(display); // Note this display is never removed. |
| + |
| + // Defer the listening until the native side is initialized. |
| + } |
| + |
| + private void setNativePointer(long nativePointer) { |
| + mNativePointer = nativePointer; |
| + nativeSetPrimaryDisplayId(mNativePointer, mMainSdkDisplayId); |
| + |
| + for (int i = 0; i < mIdMap.size(); ++i) { |
| + updateDisplayOnNativeSide(mIdMap.valueAt(i)); |
| + } |
| + |
| mBackend.startListening(); |
|
boliu
2016/11/12 00:34:13
hmm... this can still happen in initialize, right?
Tima Vaisburd
2016/11/12 01:57:27
yes, I think it would work either way. Moved up.
|
| } |
| @@ -239,6 +282,24 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
| int sdkDisplayId = display.getDisplayId(); |
| DisplayAndroid displayAndroid = new DisplayAndroid(display); |
| mIdMap.put(sdkDisplayId, displayAndroid); |
| + |
| + displayAndroid.updateFromDisplay(display); |
| return displayAndroid; |
| } |
| + |
| + /* package */ void updateDisplayOnNativeSide(DisplayAndroid displayAndroid) { |
| + if (mNativePointer == 0) return; |
| + nativeUpdateDisplay(mNativePointer, displayAndroid.getSdkDisplayId(), |
| + displayAndroid.getPhysicalDisplayWidth(), displayAndroid.getPhysicalDisplayHeight(), |
| + displayAndroid.getDisplayWidth(), displayAndroid.getDisplayHeight(), |
| + displayAndroid.getDipScale(), displayAndroid.getRotationDegrees(), |
| + displayAndroid.getBitsPerPixel(), displayAndroid.getBitsPerComponent()); |
| + } |
| + |
| + private native void nativeUpdateDisplay(long nativeDisplayAndroidManager, int sdkDisplayId, |
| + int physicalWidth, int physicalHeight, int width, int height, float dipScale, |
| + int rotationDegrees, int bitsPerPixel, int bitsPerComponent); |
| + private native void nativeRemoveDisplay(long nativeDisplayAndroidManager, int sdkDisplayId); |
| + private native void nativeSetPrimaryDisplayId( |
| + long nativeDisplayAndroidManager, int sdkDisplayId); |
| } |