| Index: ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
|
| diff --git a/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6ec2ea29d75adee514ff86fda5e32d6b87c57ea7
|
| --- /dev/null
|
| +++ b/ui/android/java/src/org/chromium/ui/display/DisplayAndroid.java
|
| @@ -0,0 +1,156 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.ui.display;
|
| +
|
| +import android.annotation.TargetApi;
|
| +import android.content.Context;
|
| +import android.graphics.Point;
|
| +import android.os.Build;
|
| +import android.view.Display;
|
| +
|
| +import java.util.WeakHashMap;
|
| +
|
| +/**
|
| + * Chromium's object for android.view.Display. Instances of this object should be obtained
|
| + * from WindowAndroid.
|
| + * This class is designed to avoid leaks. It is ok to hold a strong ref of this class from
|
| + * anywhere, as long as the corresponding WindowAndroids are destroyed. The observers are
|
| + * held weakly so to not lead to leaks.
|
| + */
|
| +public class DisplayAndroid {
|
| + /**
|
| + * DisplayAndroidObserver interface for changes to this Display.
|
| + */
|
| + public interface DisplayAndroidObserver {
|
| + /**
|
| + * Called whenever the screen orientation changes.
|
| + *
|
| + * @param orientation One of Surface.ROTATION_* values.
|
| + */
|
| + void onRotationChanged(int rotation);
|
| + }
|
| +
|
| + private static final DisplayAndroidObserver[] EMPTY_OBSERVER_ARRAY =
|
| + new DisplayAndroidObserver[0];
|
| +
|
| + private final int mSdkDisplayId;
|
| + private final WeakHashMap<DisplayAndroidObserver, Object /* null */> mObservers;
|
| + // Do NOT add strong references to objects with potentially complex lifetime, like Context.
|
| +
|
| + // Updated by updateFromDisplay.
|
| + private final Point mSize;
|
| + private final Point mPhysicalSize;
|
| + private int mRotation;
|
| +
|
| + private static DisplayAndroidManager getManager() {
|
| + return DisplayAndroidManager.getInstance();
|
| + }
|
| +
|
| + // Internal implementation. Should not be called outside of UI.
|
| + public static DisplayAndroid get(Context context) {
|
| + Display display = DisplayAndroidManager.getDisplayFromContext(context);
|
| + int id = display.getDisplayId();
|
| + return getManager().getDisplayAndroid(id);
|
| + }
|
| +
|
| + /**
|
| + * @return Display height in physical pixels.
|
| + */
|
| + public int getDisplayHeight() {
|
| + return mSize.y;
|
| + }
|
| +
|
| + /**
|
| + * @return Display width in physical pixels.
|
| + */
|
| + public int getDisplayWidth() {
|
| + return mSize.x;
|
| + }
|
| +
|
| + /**
|
| + * @return Real physical display height in physical pixels. Or 0 if not supported.
|
| + */
|
| + public int getPhysicalDisplayHeight() {
|
| + return mPhysicalSize.y;
|
| + }
|
| +
|
| + /**
|
| + * @return Real physical display width in physical pixels. Or 0 if not supported.
|
| + */
|
| + public int getPhysicalDisplayWidth() {
|
| + return mPhysicalSize.x;
|
| + }
|
| +
|
| + /**
|
| + * @return current orientation. One of Surface.ORIENTATION_* values.
|
| + */
|
| + public int getRotation() {
|
| + return mRotation;
|
| + }
|
| +
|
| + /**
|
| + * Add observer. Note repeat observers will be called only one.
|
| + * Observers are held only weakly by Display.
|
| + */
|
| + public void addObserver(DisplayAndroidObserver observer) {
|
| + mObservers.put(observer, null);
|
| + }
|
| +
|
| + /**
|
| + * Remove observer.
|
| + */
|
| + public void removeObserver(DisplayAndroidObserver observer) {
|
| + mObservers.remove(observer);
|
| + }
|
| +
|
| + /**
|
| + * 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 static void startAccurateListening() {
|
| + getManager().startAccurateListening();
|
| + }
|
| +
|
| + /**
|
| + * Request to stop the accurate mode. It will effectively be stopped only if
|
| + * this method is called as many times as startAccurateListening().
|
| + */
|
| + public static void stopAccurateListening() {
|
| + getManager().startAccurateListening();
|
| + }
|
| +
|
| + /* package */ DisplayAndroid(Display display) {
|
| + mSdkDisplayId = display.getDisplayId();
|
| + mObservers = new WeakHashMap<>();
|
| + mSize = new Point();
|
| + mPhysicalSize = new Point();
|
| + updateFromDisplay(display);
|
| + }
|
| +
|
| + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
| + /* package */ void updateFromDisplay(Display display) {
|
| + display.getSize(mSize);
|
| +
|
| + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
| + display.getRealSize(mPhysicalSize);
|
| + }
|
| +
|
| + int newRotation = display.getRotation();
|
| + boolean rotationChanged = newRotation != mRotation;
|
| + mRotation = newRotation;
|
| +
|
| + if (rotationChanged) {
|
| + DisplayAndroidObserver[] observers = getObservers();
|
| + for (DisplayAndroidObserver o : observers) {
|
| + o.onRotationChanged(mRotation);
|
| + }
|
| + }
|
| + }
|
| +
|
| + private DisplayAndroidObserver[] getObservers() {
|
| + // Makes a copy to allow concurrent edit.
|
| + return mObservers.keySet().toArray(EMPTY_OBSERVER_ARRAY);
|
| + }
|
| +}
|
|
|