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..ddf05cd91f2ec55de64c517939c92a92496e220b 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,16 @@ 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.ui.gfx.DeviceDisplayInfo; |
+import java.util.Set; |
+ |
/** |
* 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 +71,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 |
@@ -113,8 +113,8 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
@Override |
public void onConfigurationChanged(Configuration newConfig) { |
updateDeviceDisplayInfo(); |
- mIdMap.get(mMainSdkDisplayId).updateFromDisplay( |
- getDefaultDisplayForContext(getContext())); |
+ updateDisplayAndroidFromDisplay( |
+ mIdMap.get(mMainSdkDisplayId), getDefaultDisplayForContext(getContext())); |
} |
@Override |
@@ -159,21 +159,28 @@ 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); |
} |
@Override |
public void onDisplayChanged(int sdkDisplayId) { |
updateDeviceDisplayInfo(); |
- DisplayAndroid displayAndroid = mIdMap.get(sdkDisplayId); |
- if (displayAndroid != null) { |
- displayAndroid.updateFromDisplay(getDisplayManager().getDisplay(sdkDisplayId)); |
- } |
+ updateDisplayAndroidFromDisplay( |
+ mIdMap.get(sdkDisplayId), getDisplayManager().getDisplay(sdkDisplayId)); |
} |
} |
private static DisplayAndroidManager sDisplayAndroidManager; |
+ private long mNativePointer; |
+ private int mMainSdkDisplayId; |
private SparseArray<DisplayAndroid> mIdMap; |
private final DisplayListenerBackend mBackend; |
@@ -206,15 +213,44 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
DeviceDisplayInfo.create(getContext()).updateNativeSharedDisplayInfo(); |
} |
+ @CalledByNative |
+ private static void onNativeSideCreated(long nativePointer) { |
+ DisplayAndroidManager singleton = getInstance(); |
+ singleton.setNativePointer(nativePointer); |
+ } |
+ |
private DisplayAndroidManager() { |
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(); |
} |
@@ -239,6 +275,35 @@ import org.chromium.ui.gfx.DeviceDisplayInfo; |
int sdkDisplayId = display.getDisplayId(); |
DisplayAndroid displayAndroid = new DisplayAndroid(display); |
mIdMap.put(sdkDisplayId, displayAndroid); |
+ |
+ displayAndroid.updateFromDisplay(display); |
+ updateDisplayOnNativeSide(displayAndroid); |
return displayAndroid; |
} |
+ |
+ private void updateDisplayAndroidFromDisplay(DisplayAndroid displayAndroid, Display display) { |
+ if (displayAndroid == null || display == null) return; |
+ |
+ Set<DisplayAndroid.PropertyChange> changes = displayAndroid.updateFromDisplay(display); |
+ if (changes.isEmpty()) return; |
+ |
+ updateDisplayOnNativeSide(displayAndroid); |
+ displayAndroid.notifyObservers(changes); |
+ } |
+ |
+ private 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); |
} |