mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-04 09:56:49 +00:00
Merge "Use normalized CachedDisplayInfo as key" into tm-qpr-dev am: cbde3a3a8d
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/18754331 Change-Id: I4a84ca5e6752c936538288fae986da2edad4711f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -15,11 +15,20 @@
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Display;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowMetrics;
|
||||
|
||||
import com.android.launcher3.util.WindowBounds;
|
||||
import com.android.launcher3.util.window.CachedDisplayInfo;
|
||||
import com.android.launcher3.util.window.WindowManagerProxy;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Extension of {@link WindowManagerProxy} with some assumption for the default system Launcher
|
||||
*/
|
||||
@@ -30,17 +39,23 @@ public class SystemWindowManagerProxy extends WindowManagerProxy {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDisplayId(Display display) {
|
||||
return display.getUniqueId();
|
||||
public int getRotation(Context displayInfoContext) {
|
||||
return displayInfoContext.getResources().getConfiguration().windowConfiguration
|
||||
.getRotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternalDisplay(Display display) {
|
||||
return display.getType() == Display.TYPE_INTERNAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRotation(Context context) {
|
||||
return context.getResources().getConfiguration().windowConfiguration.getRotation();
|
||||
public ArrayMap<CachedDisplayInfo, WindowBounds[]> estimateInternalDisplayBounds(
|
||||
Context displayInfoContext) {
|
||||
ArrayMap<CachedDisplayInfo, WindowBounds[]> result = new ArrayMap<>();
|
||||
WindowManager windowManager = displayInfoContext.getSystemService(WindowManager.class);
|
||||
Set<WindowMetrics> possibleMaximumWindowMetrics =
|
||||
windowManager.getPossibleMaximumWindowMetrics(DEFAULT_DISPLAY);
|
||||
for (WindowMetrics windowMetrics : possibleMaximumWindowMetrics) {
|
||||
CachedDisplayInfo info = getDisplayInfo(windowMetrics, Surface.ROTATION_0);
|
||||
WindowBounds[] bounds = estimateWindowBounds(displayInfoContext, info);
|
||||
result.put(info, bounds);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import android.graphics.Rect;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Size;
|
||||
import android.view.Display;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
|
||||
@@ -290,15 +289,17 @@ public class OrientationTouchTransformerTest {
|
||||
private DisplayController.Info createDisplayInfo(Size screenSize, int rotation) {
|
||||
Point displaySize = new Point(screenSize.getWidth(), screenSize.getHeight());
|
||||
RotationUtils.rotateSize(displaySize, rotation);
|
||||
CachedDisplayInfo cdi = new CachedDisplayInfo(displaySize, rotation);
|
||||
WindowBounds wm = new WindowBounds(
|
||||
CachedDisplayInfo cachedDisplayInfo = new CachedDisplayInfo(displaySize, rotation);
|
||||
WindowBounds windowBounds = new WindowBounds(
|
||||
new Rect(0, 0, displaySize.x, displaySize.y),
|
||||
new Rect());
|
||||
WindowManagerProxy wmProxy = mock(WindowManagerProxy.class);
|
||||
doReturn(cdi).when(wmProxy).getDisplayInfo(any(), any());
|
||||
doReturn(wm).when(wmProxy).getRealBounds(any(), any(), any());
|
||||
doReturn(cachedDisplayInfo).when(wmProxy).getDisplayInfo(any());
|
||||
doReturn(windowBounds).when(wmProxy).getRealBounds(any(), any());
|
||||
ArrayMap<CachedDisplayInfo, WindowBounds[]> internalDisplayBounds = new ArrayMap<>();
|
||||
doReturn(internalDisplayBounds).when(wmProxy).estimateInternalDisplayBounds(any());
|
||||
return new DisplayController.Info(
|
||||
getApplicationContext(), mock(Display.class), wmProxy, new ArrayMap<>());
|
||||
getApplicationContext(), wmProxy, new ArrayMap<>());
|
||||
}
|
||||
|
||||
private float generateTouchRegionHeight(Size screenSize, int rotation) {
|
||||
|
||||
@@ -23,8 +23,6 @@ import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Pair;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
@@ -148,7 +146,7 @@ public class TaskViewSimulatorTest {
|
||||
int rotation = mDisplaySize.x > mDisplaySize.y
|
||||
? Surface.ROTATION_90 : Surface.ROTATION_0;
|
||||
CachedDisplayInfo cdi =
|
||||
new CachedDisplayInfo("test-display", mDisplaySize, rotation , new Rect());
|
||||
new CachedDisplayInfo(mDisplaySize, rotation, new Rect());
|
||||
WindowBounds wm = new WindowBounds(
|
||||
new Rect(0, 0, mDisplaySize.x, mDisplaySize.y),
|
||||
mDisplayInsets);
|
||||
@@ -164,15 +162,15 @@ public class TaskViewSimulatorTest {
|
||||
}
|
||||
|
||||
WindowManagerProxy wmProxy = mock(WindowManagerProxy.class);
|
||||
doReturn(cdi).when(wmProxy).getDisplayInfo(any(), any());
|
||||
doReturn(wm).when(wmProxy).getRealBounds(any(), any(), any());
|
||||
doReturn(cdi).when(wmProxy).getDisplayInfo(any());
|
||||
doReturn(wm).when(wmProxy).getRealBounds(any(), any());
|
||||
|
||||
ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> perDisplayBoundsCache =
|
||||
ArrayMap<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache =
|
||||
new ArrayMap<>();
|
||||
perDisplayBoundsCache.put(cdi.id, Pair.create(cdi.normalize(), allBounds));
|
||||
perDisplayBoundsCache.put(cdi.normalize(), allBounds);
|
||||
|
||||
DisplayController.Info mockInfo = new Info(
|
||||
helper.sandboxContext, mock(Display.class), wmProxy, perDisplayBoundsCache);
|
||||
helper.sandboxContext, wmProxy, perDisplayBoundsCache);
|
||||
|
||||
DisplayController controller =
|
||||
DisplayController.INSTANCE.get(helper.sandboxContext);
|
||||
|
||||
@@ -234,7 +234,8 @@ public class InvariantDeviceProfile {
|
||||
/*allowDisabledGrid=*/false),
|
||||
defaultDeviceType);
|
||||
|
||||
Info myInfo = new Info(context, display);
|
||||
Context displayContext = context.createDisplayContext(display);
|
||||
Info myInfo = new Info(displayContext);
|
||||
@DeviceType int deviceType = getDeviceType(myInfo);
|
||||
DisplayOption myDisplayOption = invDistWeightedInterpolate(
|
||||
myInfo,
|
||||
@@ -642,7 +643,7 @@ public class InvariantDeviceProfile {
|
||||
+ "\nconfig: " + config
|
||||
+ "\ndisplayMetrics: " + res.getDisplayMetrics()
|
||||
+ "\nrotation: " + rotation
|
||||
+ "\n" + stringWriter.toString(),
|
||||
+ "\n" + stringWriter,
|
||||
new Exception());
|
||||
}
|
||||
return getBestMatch(screenWidth, screenHeight, rotation);
|
||||
|
||||
@@ -41,7 +41,6 @@ import android.os.Build;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.view.Display;
|
||||
|
||||
import androidx.annotation.AnyThread;
|
||||
@@ -117,8 +116,9 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
|
||||
getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
|
||||
|
||||
WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(context);
|
||||
mInfo = new Info(getDisplayInfoContext(display), display,
|
||||
wmProxy, wmProxy.estimateInternalDisplayBounds(context));
|
||||
Context displayInfoContext = getDisplayInfoContext(display);
|
||||
mInfo = new Info(displayInfoContext, wmProxy,
|
||||
wmProxy.estimateInternalDisplayBounds(displayInfoContext));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,18 +216,18 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
|
||||
WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(mContext);
|
||||
Info oldInfo = mInfo;
|
||||
|
||||
Context displayContext = getDisplayInfoContext(display);
|
||||
Info newInfo = new Info(displayContext, display, wmProxy, oldInfo.mPerDisplayBounds);
|
||||
Context displayInfoContext = getDisplayInfoContext(display);
|
||||
Info newInfo = new Info(displayInfoContext, wmProxy, oldInfo.mPerDisplayBounds);
|
||||
|
||||
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale
|
||||
|| newInfo.navigationMode != oldInfo.navigationMode) {
|
||||
// Cache may not be valid anymore, recreate without cache
|
||||
newInfo = new Info(displayContext, display, wmProxy,
|
||||
wmProxy.estimateInternalDisplayBounds(displayContext));
|
||||
newInfo = new Info(displayInfoContext, wmProxy,
|
||||
wmProxy.estimateInternalDisplayBounds(displayInfoContext));
|
||||
}
|
||||
|
||||
int change = 0;
|
||||
if (!newInfo.displayId.equals(oldInfo.displayId)) {
|
||||
if (!newInfo.normalizedDisplayInfo.equals(oldInfo.normalizedDisplayInfo)) {
|
||||
change |= CHANGE_ACTIVE_SCREEN;
|
||||
}
|
||||
if (newInfo.rotation != oldInfo.rotation) {
|
||||
@@ -242,35 +242,16 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
|
||||
if (!newInfo.supportedBounds.equals(oldInfo.supportedBounds)
|
||||
|| !newInfo.mPerDisplayBounds.equals(oldInfo.mPerDisplayBounds)) {
|
||||
change |= CHANGE_SUPPORTED_BOUNDS;
|
||||
|
||||
Point currentS = newInfo.currentSize;
|
||||
Pair<CachedDisplayInfo, WindowBounds[]> cachedBounds =
|
||||
oldInfo.mPerDisplayBounds.get(newInfo.displayId);
|
||||
Point expectedS = cachedBounds == null ? null : cachedBounds.first.size;
|
||||
if (newInfo.supportedBounds.size() != oldInfo.supportedBounds.size()) {
|
||||
Log.e("b/198965093",
|
||||
"Inconsistent number of displays"
|
||||
+ "\ndisplay state: " + display.getState()
|
||||
+ "\noldInfo.supportedBounds: " + oldInfo.supportedBounds
|
||||
+ "\nnewInfo.supportedBounds: " + newInfo.supportedBounds);
|
||||
}
|
||||
if (expectedS != null
|
||||
&& (Math.min(currentS.x, currentS.y) != Math.min(expectedS.x, expectedS.y)
|
||||
|| Math.max(currentS.x, currentS.y) != Math.max(expectedS.x, expectedS.y))
|
||||
&& display.getState() == Display.STATE_OFF) {
|
||||
Log.e("b/198965093",
|
||||
"Display size changed while display is off, ignoring change");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Log.d("b/198965093", "handleInfoChange"
|
||||
+ "\n\tchange: " + change
|
||||
+ "\n\tConfiguration diff: " + newInfo.mConfiguration.diff(oldInfo.mConfiguration));
|
||||
+ "\n\tchange: 0b" + Integer.toBinaryString(change)
|
||||
+ "\n\tConfiguration diff: 0x" + Integer.toHexString(
|
||||
newInfo.mConfiguration.diff(oldInfo.mConfiguration)));
|
||||
|
||||
if (change != 0) {
|
||||
mInfo = newInfo;
|
||||
final int flags = change;
|
||||
MAIN_EXECUTOR.execute(() -> notifyChange(displayContext, flags));
|
||||
MAIN_EXECUTOR.execute(() -> notifyChange(displayInfoContext, flags));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,8 +269,8 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
|
||||
public static class Info {
|
||||
|
||||
// Cached property
|
||||
public final CachedDisplayInfo normalizedDisplayInfo;
|
||||
public final int rotation;
|
||||
public final String displayId;
|
||||
public final Point currentSize;
|
||||
public final Rect cutout;
|
||||
|
||||
@@ -302,60 +283,71 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
|
||||
|
||||
public final Set<WindowBounds> supportedBounds = new ArraySet<>();
|
||||
|
||||
private final ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> mPerDisplayBounds =
|
||||
private final ArrayMap<CachedDisplayInfo, WindowBounds[]> mPerDisplayBounds =
|
||||
new ArrayMap<>();
|
||||
|
||||
// TODO(b/198965093): Remove after investigation
|
||||
private Configuration mConfiguration;
|
||||
|
||||
public Info(Context context, Display display) {
|
||||
public Info(Context displayInfoContext) {
|
||||
/* don't need system overrides for external displays */
|
||||
this(context, display, new WindowManagerProxy(), new ArrayMap<>());
|
||||
this(displayInfoContext, new WindowManagerProxy(), new ArrayMap<>());
|
||||
}
|
||||
|
||||
// Used for testing
|
||||
public Info(Context context, Display display,
|
||||
public Info(Context displayInfoContext,
|
||||
WindowManagerProxy wmProxy,
|
||||
ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> perDisplayBoundsCache) {
|
||||
CachedDisplayInfo displayInfo = wmProxy.getDisplayInfo(context, display);
|
||||
ArrayMap<CachedDisplayInfo, WindowBounds[]> perDisplayBoundsCache) {
|
||||
CachedDisplayInfo displayInfo = wmProxy.getDisplayInfo(displayInfoContext);
|
||||
normalizedDisplayInfo = displayInfo.normalize();
|
||||
rotation = displayInfo.rotation;
|
||||
currentSize = displayInfo.size;
|
||||
displayId = displayInfo.id;
|
||||
cutout = displayInfo.cutout;
|
||||
|
||||
Configuration config = context.getResources().getConfiguration();
|
||||
Configuration config = displayInfoContext.getResources().getConfiguration();
|
||||
fontScale = config.fontScale;
|
||||
densityDpi = config.densityDpi;
|
||||
mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
|
||||
navigationMode = parseNavigationMode(context);
|
||||
navigationMode = parseNavigationMode(displayInfoContext);
|
||||
|
||||
// TODO(b/198965093): Remove after investigation
|
||||
mConfiguration = config;
|
||||
|
||||
mPerDisplayBounds.putAll(perDisplayBoundsCache);
|
||||
Pair<CachedDisplayInfo, WindowBounds[]> cachedValue = mPerDisplayBounds.get(displayId);
|
||||
WindowBounds[] cachedValue = mPerDisplayBounds.get(normalizedDisplayInfo);
|
||||
|
||||
WindowBounds realBounds = wmProxy.getRealBounds(context, display, displayInfo);
|
||||
WindowBounds realBounds = wmProxy.getRealBounds(displayInfoContext, displayInfo);
|
||||
if (cachedValue == null) {
|
||||
supportedBounds.add(realBounds);
|
||||
} else {
|
||||
// Unexpected normalizedDisplayInfo is found, recreate the cache
|
||||
Log.e("b/198965093", "Unexpected normalizedDisplayInfo found, invalidating cache");
|
||||
mPerDisplayBounds.clear();
|
||||
mPerDisplayBounds.putAll(wmProxy.estimateInternalDisplayBounds(displayInfoContext));
|
||||
cachedValue = mPerDisplayBounds.get(normalizedDisplayInfo);
|
||||
if (cachedValue == null) {
|
||||
Log.e("b/198965093", "normalizedDisplayInfo not found in estimation: "
|
||||
+ normalizedDisplayInfo);
|
||||
supportedBounds.add(realBounds);
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedValue != null) {
|
||||
// Verify that the real bounds are a match
|
||||
WindowBounds expectedBounds = cachedValue.second[displayInfo.rotation];
|
||||
WindowBounds expectedBounds = cachedValue[displayInfo.rotation];
|
||||
if (!realBounds.equals(expectedBounds)) {
|
||||
WindowBounds[] clone = new WindowBounds[4];
|
||||
System.arraycopy(cachedValue.second, 0, clone, 0, 4);
|
||||
System.arraycopy(cachedValue, 0, clone, 0, 4);
|
||||
clone[displayInfo.rotation] = realBounds;
|
||||
cachedValue = Pair.create(displayInfo.normalize(), clone);
|
||||
mPerDisplayBounds.put(displayId, cachedValue);
|
||||
mPerDisplayBounds.put(normalizedDisplayInfo, clone);
|
||||
}
|
||||
}
|
||||
mPerDisplayBounds.values().forEach(
|
||||
pair -> Collections.addAll(supportedBounds, pair.second));
|
||||
windowBounds -> Collections.addAll(supportedBounds, windowBounds));
|
||||
Log.e("b/198965093", "mConfiguration: " + mConfiguration);
|
||||
Log.d("b/198965093", "displayInfo: " + displayInfo);
|
||||
Log.d("b/198965093", "realBounds: " + realBounds);
|
||||
mPerDisplayBounds.values().forEach(pair -> Log.d("b/198965093",
|
||||
"perDisplayBounds - " + pair.first + ": " + Arrays.deepToString(pair.second)));
|
||||
Log.d("b/198965093", "normalizedDisplayInfo: " + normalizedDisplayInfo);
|
||||
mPerDisplayBounds.forEach((key, value) -> Log.d("b/198965093",
|
||||
"perDisplayBounds - " + key + ": " + Arrays.deepToString(value)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,14 +375,14 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
|
||||
public void dump(PrintWriter pw) {
|
||||
Info info = mInfo;
|
||||
pw.println("DisplayController.Info:");
|
||||
pw.println(" id=" + info.displayId);
|
||||
pw.println(" normalizedDisplayInfo=" + info.normalizedDisplayInfo);
|
||||
pw.println(" rotation=" + info.rotation);
|
||||
pw.println(" fontScale=" + info.fontScale);
|
||||
pw.println(" densityDpi=" + info.densityDpi);
|
||||
pw.println(" navigationMode=" + info.navigationMode.name());
|
||||
pw.println(" currentSize=" + info.currentSize);
|
||||
info.mPerDisplayBounds.values().forEach(pair -> pw.println(
|
||||
" perDisplayBounds - " + pair.first + ": " + Arrays.deepToString(pair.second)));
|
||||
info.mPerDisplayBounds.forEach((key, value) -> pw.println(
|
||||
" perDisplayBounds - " + key + ": " + Arrays.deepToString(value)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,7 +30,6 @@ import java.util.Objects;
|
||||
*/
|
||||
public class CachedDisplayInfo {
|
||||
|
||||
public final String id;
|
||||
public final Point size;
|
||||
public final int rotation;
|
||||
public final Rect cutout;
|
||||
@@ -40,11 +39,10 @@ public class CachedDisplayInfo {
|
||||
}
|
||||
|
||||
public CachedDisplayInfo(Point size, int rotation) {
|
||||
this("", size, rotation, new Rect());
|
||||
this(size, rotation, new Rect());
|
||||
}
|
||||
|
||||
public CachedDisplayInfo(String id, Point size, int rotation, Rect cutout) {
|
||||
this.id = id;
|
||||
public CachedDisplayInfo(Point size, int rotation, Rect cutout) {
|
||||
this.size = size;
|
||||
this.rotation = rotation;
|
||||
this.cutout = cutout;
|
||||
@@ -62,16 +60,15 @@ public class CachedDisplayInfo {
|
||||
|
||||
Rect newCutout = new Rect(cutout);
|
||||
rotateRect(newCutout, deltaRotation(rotation, Surface.ROTATION_0));
|
||||
return new CachedDisplayInfo(id, newSize, Surface.ROTATION_0, newCutout);
|
||||
return new CachedDisplayInfo(newSize, Surface.ROTATION_0, newCutout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CachedDisplayInfo{"
|
||||
+ "id='" + id + '\''
|
||||
+ ", size=" + size
|
||||
+ ", rotation=" + rotation
|
||||
+ "size=" + size
|
||||
+ ", cutout=" + cutout
|
||||
+ ", rotation=" + rotation
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@@ -80,13 +77,13 @@ public class CachedDisplayInfo {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof CachedDisplayInfo)) return false;
|
||||
CachedDisplayInfo that = (CachedDisplayInfo) o;
|
||||
return rotation == that.rotation && Objects.equals(id, that.id)
|
||||
&& Objects.equals(size, that.size) && Objects.equals(cutout,
|
||||
that.cutout);
|
||||
return rotation == that.rotation
|
||||
&& Objects.equals(size, that.size)
|
||||
&& Objects.equals(cutout, that.cutout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, size, rotation, cutout);
|
||||
return Objects.hash(size, rotation, cutout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.android.launcher3.util.window;
|
||||
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
|
||||
import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
|
||||
import static com.android.launcher3.ResourceUtils.NAVBAR_HEIGHT;
|
||||
@@ -41,7 +40,6 @@ import android.graphics.Rect;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.os.Build;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Pair;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.Surface;
|
||||
@@ -88,20 +86,12 @@ public class WindowManagerProxy implements ResourceBasedOverride {
|
||||
* Returns a map of normalized info of internal displays to estimated window bounds
|
||||
* for that display
|
||||
*/
|
||||
public ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> estimateInternalDisplayBounds(
|
||||
Context context) {
|
||||
Display[] displays = context.getSystemService(DisplayManager.class).getDisplays();
|
||||
ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> result = new ArrayMap<>();
|
||||
for (Display display : displays) {
|
||||
if (isInternalDisplay(display)) {
|
||||
Context displayContext = Utilities.ATLEAST_S
|
||||
? context.createWindowContext(display, TYPE_APPLICATION, null)
|
||||
: context.createDisplayContext(display);
|
||||
CachedDisplayInfo info = getDisplayInfo(displayContext, display).normalize();
|
||||
WindowBounds[] bounds = estimateWindowBounds(context, info);
|
||||
result.put(info.id, Pair.create(info, bounds));
|
||||
}
|
||||
}
|
||||
public ArrayMap<CachedDisplayInfo, WindowBounds[]> estimateInternalDisplayBounds(
|
||||
Context displayInfoContext) {
|
||||
CachedDisplayInfo info = getDisplayInfo(displayInfoContext).normalize();
|
||||
WindowBounds[] bounds = estimateWindowBounds(displayInfoContext, info);
|
||||
ArrayMap<CachedDisplayInfo, WindowBounds[]> result = new ArrayMap<>();
|
||||
result.put(info, bounds);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -109,12 +99,11 @@ public class WindowManagerProxy implements ResourceBasedOverride {
|
||||
* Returns the real bounds for the provided display after applying any insets normalization
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.R)
|
||||
public WindowBounds getRealBounds(Context windowContext,
|
||||
Display display, CachedDisplayInfo info) {
|
||||
public WindowBounds getRealBounds(Context displayInfoContext, CachedDisplayInfo info) {
|
||||
if (!Utilities.ATLEAST_R) {
|
||||
Point smallestSize = new Point();
|
||||
Point largestSize = new Point();
|
||||
display.getCurrentSizeRange(smallestSize, largestSize);
|
||||
getDisplay(displayInfoContext).getCurrentSizeRange(smallestSize, largestSize);
|
||||
|
||||
if (info.size.y > info.size.x) {
|
||||
// Portrait
|
||||
@@ -122,17 +111,16 @@ public class WindowManagerProxy implements ResourceBasedOverride {
|
||||
info.rotation);
|
||||
} else {
|
||||
// Landscape
|
||||
new WindowBounds(info.size.x, info.size.y, largestSize.x, smallestSize.y,
|
||||
return new WindowBounds(info.size.x, info.size.y, largestSize.x, smallestSize.y,
|
||||
info.rotation);
|
||||
}
|
||||
}
|
||||
|
||||
WindowMetrics wm = windowContext.getSystemService(WindowManager.class)
|
||||
WindowMetrics windowMetrics = displayInfoContext.getSystemService(WindowManager.class)
|
||||
.getMaximumWindowMetrics();
|
||||
|
||||
Rect insets = new Rect();
|
||||
normalizeWindowInsets(windowContext, wm.getWindowInsets(), insets);
|
||||
return new WindowBounds(wm.getBounds(), insets, info.rotation);
|
||||
normalizeWindowInsets(displayInfoContext, windowMetrics.getWindowInsets(), insets);
|
||||
return new WindowBounds(windowMetrics.getBounds(), insets, info.rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,12 +157,9 @@ public class WindowManagerProxy implements ResourceBasedOverride {
|
||||
insetsBuilder.setInsetsIgnoringVisibility(WindowInsets.Type.navigationBars(), newNavInsets);
|
||||
|
||||
Insets statusBarInsets = oldInsets.getInsets(WindowInsets.Type.statusBars());
|
||||
|
||||
|
||||
int statusBarHeight = getDimenByName(systemRes,
|
||||
(isPortrait) ? STATUS_BAR_HEIGHT_PORTRAIT : STATUS_BAR_HEIGHT_LANDSCAPE,
|
||||
STATUS_BAR_HEIGHT);
|
||||
|
||||
Insets newStatusBarInsets = Insets.of(
|
||||
statusBarInsets.left,
|
||||
Math.max(statusBarInsets.top, statusBarHeight),
|
||||
@@ -201,22 +186,15 @@ public class WindowManagerProxy implements ResourceBasedOverride {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the display is an internal displays
|
||||
*/
|
||||
protected boolean isInternalDisplay(Display display) {
|
||||
return display.getDisplayId() == Display.DEFAULT_DISPLAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of possible WindowBounds for the display keyed on the 4 surface rotations
|
||||
*/
|
||||
public WindowBounds[] estimateWindowBounds(Context context, CachedDisplayInfo display) {
|
||||
protected WindowBounds[] estimateWindowBounds(Context context, CachedDisplayInfo displayInfo) {
|
||||
int densityDpi = context.getResources().getConfiguration().densityDpi;
|
||||
int rotation = display.rotation;
|
||||
Rect safeCutout = display.cutout;
|
||||
int rotation = displayInfo.rotation;
|
||||
Rect safeCutout = displayInfo.cutout;
|
||||
|
||||
int minSize = Math.min(display.size.x, display.size.y);
|
||||
int minSize = Math.min(displayInfo.size.x, displayInfo.size.y);
|
||||
int swDp = (int) dpiFromPx(minSize, densityDpi);
|
||||
|
||||
Resources systemRes;
|
||||
@@ -255,7 +233,7 @@ public class WindowManagerProxy implements ResourceBasedOverride {
|
||||
Point tempSize = new Point();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int rotationChange = deltaRotation(rotation, i);
|
||||
tempSize.set(display.size.x, display.size.y);
|
||||
tempSize.set(displayInfo.size.x, displayInfo.size.y);
|
||||
rotateSize(tempSize, rotationChange);
|
||||
Rect bounds = new Rect(0, 0, tempSize.x, tempSize.y);
|
||||
|
||||
@@ -311,48 +289,58 @@ public class WindowManagerProxy implements ResourceBasedOverride {
|
||||
* Returns a CachedDisplayInfo initialized for the current display
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.S)
|
||||
public CachedDisplayInfo getDisplayInfo(Context displayContext, Display display) {
|
||||
int rotation = getRotation(displayContext);
|
||||
Rect cutoutRect = new Rect();
|
||||
Point size = new Point();
|
||||
public CachedDisplayInfo getDisplayInfo(Context displayInfoContext) {
|
||||
int rotation = getRotation(displayInfoContext);
|
||||
if (Utilities.ATLEAST_S) {
|
||||
WindowMetrics wm = displayContext.getSystemService(WindowManager.class)
|
||||
WindowMetrics windowMetrics = displayInfoContext.getSystemService(WindowManager.class)
|
||||
.getMaximumWindowMetrics();
|
||||
DisplayCutout cutout = wm.getWindowInsets().getDisplayCutout();
|
||||
if (cutout != null) {
|
||||
cutoutRect.set(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),
|
||||
cutout.getSafeInsetRight(), cutout.getSafeInsetBottom());
|
||||
}
|
||||
|
||||
size.set(wm.getBounds().right, wm.getBounds().bottom);
|
||||
return getDisplayInfo(windowMetrics, rotation);
|
||||
} else {
|
||||
Point size = new Point();
|
||||
Display display = getDisplay(displayInfoContext);
|
||||
display.getRealSize(size);
|
||||
Rect cutoutRect = new Rect();
|
||||
return new CachedDisplayInfo(size, rotation, cutoutRect);
|
||||
}
|
||||
return new CachedDisplayInfo(getDisplayId(display), size, rotation, cutoutRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique ID representing the display
|
||||
* Returns a CachedDisplayInfo initialized for the current display
|
||||
*/
|
||||
protected String getDisplayId(Display display) {
|
||||
return Integer.toString(display.getDisplayId());
|
||||
@TargetApi(Build.VERSION_CODES.S)
|
||||
protected CachedDisplayInfo getDisplayInfo(WindowMetrics windowMetrics, int rotation) {
|
||||
Point size = new Point(windowMetrics.getBounds().right, windowMetrics.getBounds().bottom);
|
||||
Rect cutoutRect = new Rect();
|
||||
DisplayCutout cutout = windowMetrics.getWindowInsets().getDisplayCutout();
|
||||
if (cutout != null) {
|
||||
cutoutRect.set(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),
|
||||
cutout.getSafeInsetRight(), cutout.getSafeInsetBottom());
|
||||
}
|
||||
return new CachedDisplayInfo(size, rotation, cutoutRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns rotation of the display associated with the context.
|
||||
* Returns rotation of the display associated with the context, or rotation of DEFAULT_DISPLAY
|
||||
* if the context isn't associated with a display.
|
||||
*/
|
||||
public int getRotation(Context context) {
|
||||
Display d = null;
|
||||
public int getRotation(Context displayInfoContext) {
|
||||
return getDisplay(displayInfoContext).getRotation();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the display associated with the context, or DEFAULT_DISPLAY if the context isn't
|
||||
* associated with a display.
|
||||
*/
|
||||
protected Display getDisplay(Context displayInfoContext) {
|
||||
if (Utilities.ATLEAST_R) {
|
||||
try {
|
||||
d = context.getDisplay();
|
||||
return displayInfoContext.getDisplay();
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
if (d == null) {
|
||||
d = context.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
|
||||
}
|
||||
return d.getRotation();
|
||||
return displayInfoContext.getSystemService(DisplayManager.class).getDisplay(
|
||||
DEFAULT_DISPLAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,7 @@ public class DisplayEmulator {
|
||||
* By changing the WindowManagerProxy we can override the window insets information
|
||||
**/
|
||||
private IWindowManager changeWindowManagerInstance(DeviceEmulationData deviceData) {
|
||||
WindowManagerProxy.INSTANCE.initializeForTesting(
|
||||
new TestWindowManagerProxy(mContext, deviceData));
|
||||
WindowManagerProxy.INSTANCE.initializeForTesting(new TestWindowManagerProxy(deviceData));
|
||||
return WindowManagerGlobal.getWindowManagerService();
|
||||
}
|
||||
|
||||
@@ -57,8 +56,7 @@ public class DisplayEmulator {
|
||||
WindowManagerProxy original = WindowManagerProxy.INSTANCE.get(mContext);
|
||||
// Set up emulation
|
||||
final int userId = UserHandle.myUserId();
|
||||
WindowManagerProxy.INSTANCE.initializeForTesting(
|
||||
new TestWindowManagerProxy(mContext, device));
|
||||
WindowManagerProxy.INSTANCE.initializeForTesting(new TestWindowManagerProxy(device));
|
||||
IWindowManager wm = changeWindowManagerInstance(device);
|
||||
// Change density twice to force display controller to reset its state
|
||||
wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, device.density / 2, userId);
|
||||
|
||||
@@ -19,7 +19,6 @@ import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.view.Display;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
import com.android.launcher3.deviceemulator.models.DeviceEmulationData;
|
||||
@@ -32,16 +31,11 @@ public class TestWindowManagerProxy extends WindowManagerProxy {
|
||||
|
||||
private final DeviceEmulationData mDevice;
|
||||
|
||||
public TestWindowManagerProxy(Context context, DeviceEmulationData device) {
|
||||
public TestWindowManagerProxy(DeviceEmulationData device) {
|
||||
super(true);
|
||||
mDevice = device;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInternalDisplay(Display display) {
|
||||
return display.getDisplayId() == Display.DEFAULT_DISPLAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDimenByName(Resources res, String resName) {
|
||||
Integer mock = mDevice.resourceOverrides.get(resName);
|
||||
@@ -54,27 +48,25 @@ public class TestWindowManagerProxy extends WindowManagerProxy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedDisplayInfo getDisplayInfo(Context context, Display display) {
|
||||
int rotation = display.getRotation();
|
||||
public CachedDisplayInfo getDisplayInfo(Context displayInfoContext) {
|
||||
int rotation = getRotation(displayInfoContext);
|
||||
Point size = new Point(mDevice.width, mDevice.height);
|
||||
RotationUtils.rotateSize(size, rotation);
|
||||
Rect cutout = new Rect(mDevice.cutout);
|
||||
RotationUtils.rotateRect(cutout, rotation);
|
||||
return new CachedDisplayInfo(getDisplayId(display), size, rotation, cutout);
|
||||
return new CachedDisplayInfo(size, rotation, cutout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowBounds getRealBounds(Context windowContext, Display display,
|
||||
CachedDisplayInfo info) {
|
||||
return estimateInternalDisplayBounds(windowContext)
|
||||
.get(getDisplayId(display)).second[display.getRotation()];
|
||||
public WindowBounds getRealBounds(Context displayInfoContext, CachedDisplayInfo info) {
|
||||
return estimateInternalDisplayBounds(displayInfoContext).get(
|
||||
getDisplayInfo(displayInfoContext))[getDisplay(displayInfoContext).getRotation()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindowInsets normalizeWindowInsets(Context context, WindowInsets oldInsets,
|
||||
Rect outInsets) {
|
||||
outInsets.set(getRealBounds(context, context.getDisplay(),
|
||||
getDisplayInfo(context, context.getDisplay())).insets);
|
||||
outInsets.set(getRealBounds(context, getDisplayInfo(context)).insets);
|
||||
return oldInsets;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user