GestureNav: Log exclusion rect heights
Logs the rejected and requested exclusion rect heights. Test: adb shell device_config put android:window_manager key_system_gesture_exclusion_log_debounce_millis 1000 Bug: 135152789 Change-Id: Ie12640f4bf0a8b40b666e604188a0bedd85e8981 Exempt-From-Owner-Approval: DeviceConfig.java: Adding constant to WindowManager namespace.
This commit is contained in:
@@ -337,6 +337,20 @@ public final class DeviceConfig {
|
||||
String KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE =
|
||||
"system_gestures_excluded_by_pre_q_sticky_immersive";
|
||||
|
||||
/**
|
||||
* The minimum duration between gesture exclusion logging for a given window in
|
||||
* milliseconds.
|
||||
*
|
||||
* Events that happen in-between will be silently dropped.
|
||||
*
|
||||
* A non-positive value disables logging.
|
||||
*
|
||||
* @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
|
||||
* @hide
|
||||
*/
|
||||
String KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS =
|
||||
"system_gesture_exclusion_log_debounce_millis";
|
||||
|
||||
/**
|
||||
* Key for controlling which packages are explicitly blocked from running at refresh rates
|
||||
* higher than 60hz.
|
||||
|
||||
@@ -28,7 +28,14 @@ oneway interface ISystemGestureExclusionListener {
|
||||
* Called when the system gesture exclusion for the given display changed.
|
||||
* @param displayId the display whose system gesture exclusion changed
|
||||
* @param systemGestureExclusion a {@code Region} where the app would like priority over the
|
||||
* system gestures, in display coordinates.
|
||||
* system gestures, in display coordinates. Certain restrictions
|
||||
* might be applied such that apps don't get all the exclusions
|
||||
* they request.
|
||||
* @param systemGestureExclusionUnrestricted a {@code Region} where the app would like priority
|
||||
* over the system gestures, in display coordinates, without
|
||||
* any restrictions applied. Null if no restrictions have been
|
||||
* applied.
|
||||
*/
|
||||
void onSystemGestureExclusionChanged(int displayId, in Region systemGestureExclusion);
|
||||
void onSystemGestureExclusionChanged(int displayId, in Region systemGestureExclusion,
|
||||
in Region systemGestureExclusionUnrestricted);
|
||||
}
|
||||
@@ -53,6 +53,12 @@ public class PointerLocationView extends View implements InputDeviceListener,
|
||||
// to plot alongside the default one. Useful for testing and comparison purposes.
|
||||
private static final String ALT_STRATEGY_PROPERY_KEY = "debug.velocitytracker.alt";
|
||||
|
||||
/**
|
||||
* If set to a positive value between 1-255, shows an overlay with the approved (red) and
|
||||
* rejected (blue) exclusions.
|
||||
*/
|
||||
private static final String GESTURE_EXCLUSION_PROP = "debug.pointerlocation.showexclusion";
|
||||
|
||||
public static class PointerState {
|
||||
// Trace of previous points.
|
||||
private float[] mTraceX = new float[32];
|
||||
@@ -138,8 +144,10 @@ public class PointerLocationView extends View implements InputDeviceListener,
|
||||
private final PointerCoords mTempCoords = new PointerCoords();
|
||||
|
||||
private final Region mSystemGestureExclusion = new Region();
|
||||
private final Region mSystemGestureExclusionRejected = new Region();
|
||||
private final Path mSystemGestureExclusionPath = new Path();
|
||||
private final Paint mSystemGestureExclusionPaint;
|
||||
private final Paint mSystemGestureExclusionRejectedPaint;
|
||||
|
||||
private final VelocityTracker mVelocity;
|
||||
private final VelocityTracker mAltVelocity;
|
||||
@@ -190,6 +198,10 @@ public class PointerLocationView extends View implements InputDeviceListener,
|
||||
mSystemGestureExclusionPaint.setARGB(25, 255, 0, 0);
|
||||
mSystemGestureExclusionPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
|
||||
mSystemGestureExclusionRejectedPaint = new Paint();
|
||||
mSystemGestureExclusionRejectedPaint.setARGB(25, 0, 0, 255);
|
||||
mSystemGestureExclusionRejectedPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
|
||||
PointerState ps = new PointerState();
|
||||
mPointers.add(ps);
|
||||
mActivePointerId = 0;
|
||||
@@ -263,6 +275,12 @@ public class PointerLocationView extends View implements InputDeviceListener,
|
||||
canvas.drawPath(mSystemGestureExclusionPath, mSystemGestureExclusionPaint);
|
||||
}
|
||||
|
||||
if (!mSystemGestureExclusionRejected.isEmpty()) {
|
||||
mSystemGestureExclusionPath.reset();
|
||||
mSystemGestureExclusionRejected.getBoundaryPath(mSystemGestureExclusionPath);
|
||||
canvas.drawPath(mSystemGestureExclusionPath, mSystemGestureExclusionRejectedPaint);
|
||||
}
|
||||
|
||||
// Labels
|
||||
if (mActivePointerId >= 0) {
|
||||
final PointerState ps = mPointers.get(mActivePointerId);
|
||||
@@ -754,6 +772,9 @@ public class PointerLocationView extends View implements InputDeviceListener,
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
final int alpha = systemGestureExclusionOpacity();
|
||||
mSystemGestureExclusionPaint.setAlpha(alpha);
|
||||
mSystemGestureExclusionRejectedPaint.setAlpha(alpha);
|
||||
} else {
|
||||
mSystemGestureExclusion.setEmpty();
|
||||
}
|
||||
@@ -805,7 +826,12 @@ public class PointerLocationView extends View implements InputDeviceListener,
|
||||
}
|
||||
|
||||
private static boolean shouldShowSystemGestureExclusion() {
|
||||
return SystemProperties.getBoolean("debug.pointerlocation.showexclusion", false);
|
||||
return systemGestureExclusionOpacity() > 0;
|
||||
}
|
||||
|
||||
private static int systemGestureExclusionOpacity() {
|
||||
int x = SystemProperties.getInt(GESTURE_EXCLUSION_PROP, 0);
|
||||
return x >= 0 && x <= 255 ? x : 0;
|
||||
}
|
||||
|
||||
// HACK
|
||||
@@ -928,12 +954,19 @@ public class PointerLocationView extends View implements InputDeviceListener,
|
||||
private ISystemGestureExclusionListener mSystemGestureExclusionListener =
|
||||
new ISystemGestureExclusionListener.Stub() {
|
||||
@Override
|
||||
public void onSystemGestureExclusionChanged(int displayId, Region systemGestureExclusion) {
|
||||
public void onSystemGestureExclusionChanged(int displayId, Region systemGestureExclusion,
|
||||
Region systemGestureExclusionUnrestricted) {
|
||||
Region exclusion = Region.obtain(systemGestureExclusion);
|
||||
Region rejected = Region.obtain();
|
||||
if (systemGestureExclusionUnrestricted != null) {
|
||||
rejected.set(systemGestureExclusionUnrestricted);
|
||||
rejected.op(exclusion, Region.Op.DIFFERENCE);
|
||||
}
|
||||
Handler handler = getHandler();
|
||||
if (handler != null) {
|
||||
handler.post(() -> {
|
||||
mSystemGestureExclusion.set(exclusion);
|
||||
mSystemGestureExclusionRejected.set(rejected);
|
||||
exclusion.recycle();
|
||||
invalidate();
|
||||
});
|
||||
|
||||
@@ -34,9 +34,11 @@ public abstract class SystemGestureExclusionListenerCompat {
|
||||
new ISystemGestureExclusionListener.Stub() {
|
||||
@Override
|
||||
public void onSystemGestureExclusionChanged(int displayId,
|
||||
Region systemGestureExclusion) {
|
||||
Region systemGestureExclusion, Region unrestrictedOrNull) {
|
||||
if (displayId == mDisplayId) {
|
||||
onExclusionChanged(systemGestureExclusion);
|
||||
Region unrestricted = (unrestrictedOrNull == null)
|
||||
? systemGestureExclusion : unrestrictedOrNull;
|
||||
onExclusionChanged(systemGestureExclusion, unrestricted);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -47,10 +49,28 @@ public abstract class SystemGestureExclusionListenerCompat {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the exclusion region has changed
|
||||
* Called when the exclusion region has changed.
|
||||
*
|
||||
* TODO: remove, once all subclasses have migrated to
|
||||
* {@link #onExclusionChanged(Region, Region)}.
|
||||
*/
|
||||
public abstract void onExclusionChanged(Region systemGestureExclusion);
|
||||
|
||||
/**
|
||||
* Called when the exclusion region has changed.
|
||||
*
|
||||
* @param systemGestureExclusion the system gesture exclusion to be applied
|
||||
* @param systemGestureExclusionUnrestricted what would be the system gesture exclusion, if
|
||||
* there were no restrictions being applied. For logging purposes only.
|
||||
*
|
||||
*/
|
||||
public void onExclusionChanged(Region systemGestureExclusion,
|
||||
Region systemGestureExclusionUnrestricted) {
|
||||
// TODO: make abstract, once all subclasses have migrated away from
|
||||
// onExclusionChanged(Region)
|
||||
onExclusionChanged(systemGestureExclusion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the listener for getting exclusion rect changes.
|
||||
*/
|
||||
|
||||
@@ -103,7 +103,7 @@ public class EdgeBackGestureHandler implements DisplayListener {
|
||||
new ISystemGestureExclusionListener.Stub() {
|
||||
@Override
|
||||
public void onSystemGestureExclusionChanged(int displayId,
|
||||
Region systemGestureExclusion) {
|
||||
Region systemGestureExclusion, Region unrestrictedOrNull) {
|
||||
if (displayId == mDisplayId) {
|
||||
mMainExecutor.execute(() -> mExcludeRegion.set(systemGestureExclusion));
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
|
||||
@@ -137,6 +138,8 @@ import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREEN
|
||||
import static com.android.server.wm.WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION;
|
||||
import static com.android.server.wm.WindowManagerService.dipToPixel;
|
||||
import static com.android.server.wm.WindowManagerService.logSurface;
|
||||
import static com.android.server.wm.WindowState.EXCLUSION_LEFT;
|
||||
import static com.android.server.wm.WindowState.EXCLUSION_RIGHT;
|
||||
import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
|
||||
import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
|
||||
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
|
||||
@@ -330,6 +333,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
private final RemoteCallbackList<ISystemGestureExclusionListener>
|
||||
mSystemGestureExclusionListeners = new RemoteCallbackList<>();
|
||||
private final Region mSystemGestureExclusion = new Region();
|
||||
private boolean mSystemGestureExclusionWasRestricted = false;
|
||||
private final Region mSystemGestureExclusionUnrestricted = new Region();
|
||||
private int mSystemGestureExclusionLimit;
|
||||
|
||||
/**
|
||||
@@ -5139,16 +5144,21 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
return false;
|
||||
}
|
||||
|
||||
final Region systemGestureExclusion = calculateSystemGestureExclusion();
|
||||
final Region systemGestureExclusion = Region.obtain();
|
||||
mSystemGestureExclusionWasRestricted = calculateSystemGestureExclusion(
|
||||
systemGestureExclusion, mSystemGestureExclusionUnrestricted);
|
||||
try {
|
||||
if (mSystemGestureExclusion.equals(systemGestureExclusion)) {
|
||||
return false;
|
||||
}
|
||||
mSystemGestureExclusion.set(systemGestureExclusion);
|
||||
final Region unrestrictedOrNull = mSystemGestureExclusionWasRestricted
|
||||
? mSystemGestureExclusionUnrestricted : null;
|
||||
for (int i = mSystemGestureExclusionListeners.beginBroadcast() - 1; i >= 0; --i) {
|
||||
try {
|
||||
mSystemGestureExclusionListeners.getBroadcastItem(i)
|
||||
.onSystemGestureExclusionChanged(mDisplayId, systemGestureExclusion);
|
||||
.onSystemGestureExclusionChanged(mDisplayId, systemGestureExclusion,
|
||||
unrestrictedOrNull);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to notify SystemGestureExclusionListener", e);
|
||||
}
|
||||
@@ -5160,8 +5170,22 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the system gesture exclusion.
|
||||
*
|
||||
* @param outExclusion will be set to the gesture exclusion region
|
||||
* @param outExclusionUnrestricted will be set to the gesture exclusion region without
|
||||
* any restrictions applied.
|
||||
* @return whether any restrictions were applied, i.e. outExclusion and outExclusionUnrestricted
|
||||
* differ.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
Region calculateSystemGestureExclusion() {
|
||||
boolean calculateSystemGestureExclusion(Region outExclusion, @Nullable
|
||||
Region outExclusionUnrestricted) {
|
||||
outExclusion.setEmpty();
|
||||
if (outExclusionUnrestricted != null) {
|
||||
outExclusionUnrestricted.setEmpty();
|
||||
}
|
||||
final Region unhandled = Region.obtain();
|
||||
unhandled.set(0, 0, mDisplayFrames.mDisplayWidth, mDisplayFrames.mDisplayHeight);
|
||||
|
||||
@@ -5170,7 +5194,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
final Rect rightEdge = mInsetsStateController.getSourceProvider(TYPE_RIGHT_GESTURES)
|
||||
.getSource().getFrame();
|
||||
|
||||
final Region global = Region.obtain();
|
||||
final Region touchableRegion = Region.obtain();
|
||||
final Region local = Region.obtain();
|
||||
final int[] remainingLeftRight =
|
||||
@@ -5208,28 +5231,39 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
if (needsGestureExclusionRestrictions(w, mLastDispatchedSystemUiVisibility)) {
|
||||
|
||||
// Processes the region along the left edge.
|
||||
remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, global, leftEdge,
|
||||
remainingLeftRight[0]);
|
||||
remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
|
||||
remainingLeftRight[0], w, EXCLUSION_LEFT);
|
||||
|
||||
// Processes the region along the right edge.
|
||||
remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, global, rightEdge,
|
||||
remainingLeftRight[1]);
|
||||
remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
|
||||
remainingLeftRight[1], w, EXCLUSION_RIGHT);
|
||||
|
||||
// Adds the middle (unrestricted area)
|
||||
final Region middle = Region.obtain(local);
|
||||
middle.op(leftEdge, Op.DIFFERENCE);
|
||||
middle.op(rightEdge, Op.DIFFERENCE);
|
||||
global.op(middle, Op.UNION);
|
||||
outExclusion.op(middle, Op.UNION);
|
||||
middle.recycle();
|
||||
} else {
|
||||
global.op(local, Op.UNION);
|
||||
boolean loggable = needsGestureExclusionRestrictions(w, 0 /* lastSysUiVis */);
|
||||
if (loggable) {
|
||||
addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
|
||||
Integer.MAX_VALUE, w, EXCLUSION_LEFT);
|
||||
addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
|
||||
Integer.MAX_VALUE, w, EXCLUSION_RIGHT);
|
||||
}
|
||||
outExclusion.op(local, Op.UNION);
|
||||
}
|
||||
if (outExclusionUnrestricted != null) {
|
||||
outExclusionUnrestricted.op(local, Op.UNION);
|
||||
}
|
||||
unhandled.op(touchableRegion, Op.DIFFERENCE);
|
||||
}, true /* topToBottom */);
|
||||
local.recycle();
|
||||
touchableRegion.recycle();
|
||||
unhandled.recycle();
|
||||
return global;
|
||||
return remainingLeftRight[0] < mSystemGestureExclusionLimit
|
||||
|| remainingLeftRight[1] < mSystemGestureExclusionLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5246,6 +5280,23 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
&& win.getActivityType() != ACTIVITY_TYPE_HOME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether gesture exclusion area should be logged for the given window
|
||||
*/
|
||||
static boolean logsGestureExclusionRestrictions(WindowState win) {
|
||||
if (win.mWmService.mSystemGestureExclusionLogDebounceTimeoutMillis <= 0) {
|
||||
return false;
|
||||
}
|
||||
final WindowManager.LayoutParams attrs = win.getAttrs();
|
||||
final int type = attrs.type;
|
||||
return type != TYPE_WALLPAPER
|
||||
&& type != TYPE_APPLICATION_STARTING
|
||||
&& type != TYPE_NAVIGATION_BAR
|
||||
&& (attrs.flags & FLAG_NOT_TOUCHABLE) == 0
|
||||
&& needsGestureExclusionRestrictions(win, 0 /* sysUiVisibility */)
|
||||
&& win.getDisplayContent().mDisplayPolicy.hasSideGestures();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a local gesture exclusion area to the global area while applying a limit per edge.
|
||||
*
|
||||
@@ -5253,25 +5304,34 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
* @param global The destination.
|
||||
* @param edge Only processes the part in that region.
|
||||
* @param limit How much limit in pixels we have.
|
||||
* @return How much of the limit are remaining.
|
||||
* @param win The WindowState that is being processed
|
||||
* @param side The side that is being processed, either {@link WindowState#EXCLUSION_LEFT} or
|
||||
* {@link WindowState#EXCLUSION_RIGHT}
|
||||
* @return How much of the limit is remaining.
|
||||
*/
|
||||
private static int addToGlobalAndConsumeLimit(Region local, Region global, Rect edge,
|
||||
int limit) {
|
||||
int limit, WindowState win, int side) {
|
||||
final Region r = Region.obtain(local);
|
||||
r.op(edge, Op.INTERSECT);
|
||||
|
||||
final int[] remaining = {limit};
|
||||
final int[] requestedExclusion = {0};
|
||||
forEachRectReverse(r, rect -> {
|
||||
if (remaining[0] <= 0) {
|
||||
return;
|
||||
}
|
||||
final int height = rect.height();
|
||||
requestedExclusion[0] += height;
|
||||
if (height > remaining[0]) {
|
||||
rect.top = rect.bottom - remaining[0];
|
||||
}
|
||||
remaining[0] -= height;
|
||||
global.op(rect, Op.UNION);
|
||||
});
|
||||
|
||||
final int grantedExclusion = limit - remaining[0];
|
||||
win.setLastExclusionHeights(side, requestedExclusion[0], grantedExclusion);
|
||||
|
||||
r.recycle();
|
||||
return remaining[0];
|
||||
}
|
||||
@@ -5286,10 +5346,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
final Region unrestrictedOrNull = mSystemGestureExclusionWasRestricted
|
||||
? mSystemGestureExclusionUnrestricted : null;
|
||||
// If updateSystemGestureExclusion changed the exclusion, it will already have
|
||||
// notified the listener. Otherwise, we'll do it here.
|
||||
try {
|
||||
listener.onSystemGestureExclusionChanged(mDisplayId, mSystemGestureExclusion);
|
||||
listener.onSystemGestureExclusionChanged(mDisplayId, mSystemGestureExclusion,
|
||||
unrestrictedOrNull);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to notify SystemGestureExclusionListener during register", e);
|
||||
}
|
||||
|
||||
@@ -478,9 +478,10 @@ public class DisplayPolicy {
|
||||
|
||||
@Override
|
||||
public void onSwipeFromRight() {
|
||||
final Region excludedRegion;
|
||||
final Region excludedRegion = Region.obtain();
|
||||
synchronized (mLock) {
|
||||
excludedRegion = mDisplayContent.calculateSystemGestureExclusion();
|
||||
mDisplayContent.calculateSystemGestureExclusion(
|
||||
excludedRegion, null /* outUnrestricted */);
|
||||
}
|
||||
final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
|
||||
|| mNavigationBarPosition == NAV_BAR_RIGHT;
|
||||
@@ -488,13 +489,15 @@ public class DisplayPolicy {
|
||||
&& !mSystemGestures.currentGestureStartedInRegion(excludedRegion)) {
|
||||
requestTransientBars(mNavigationBar);
|
||||
}
|
||||
excludedRegion.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwipeFromLeft() {
|
||||
final Region excludedRegion;
|
||||
final Region excludedRegion = Region.obtain();
|
||||
synchronized (mLock) {
|
||||
excludedRegion = mDisplayContent.calculateSystemGestureExclusion();
|
||||
mDisplayContent.calculateSystemGestureExclusion(
|
||||
excludedRegion, null /* outUnrestricted */);
|
||||
}
|
||||
final boolean sideAllowed = mNavigationBarAlwaysShowOnSideGesture
|
||||
|| mNavigationBarPosition == NAV_BAR_LEFT;
|
||||
@@ -502,6 +505,7 @@ public class DisplayPolicy {
|
||||
&& !mSystemGestures.currentGestureStartedInRegion(excludedRegion)) {
|
||||
requestTransientBars(mNavigationBar);
|
||||
}
|
||||
excludedRegion.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -674,6 +678,10 @@ public class DisplayPolicy {
|
||||
return mHasStatusBar;
|
||||
}
|
||||
|
||||
boolean hasSideGestures() {
|
||||
return mHasNavigationBar && mSideGestureInset > 0;
|
||||
}
|
||||
|
||||
public boolean navigationBarCanMove() {
|
||||
return mNavigationBarCanMove;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import static android.os.Process.myPid;
|
||||
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
||||
import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE;
|
||||
import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP;
|
||||
import static android.provider.DeviceConfig.WindowManager.KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS;
|
||||
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
@@ -847,6 +848,16 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
int mSystemGestureExclusionLimitDp;
|
||||
boolean mSystemGestureExcludedByPreQStickyImmersive;
|
||||
|
||||
/**
|
||||
* The minimum duration between gesture exclusion logging for a given window in
|
||||
* milliseconds.
|
||||
*
|
||||
* Events that happen in-between will be silently dropped.
|
||||
*
|
||||
* A non-positive value disables logging.
|
||||
*/
|
||||
public long mSystemGestureExclusionLogDebounceTimeoutMillis;
|
||||
|
||||
public interface WindowChangeListener {
|
||||
public void windowsChanged();
|
||||
public void focusChanged();
|
||||
@@ -1146,6 +1157,9 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
|
||||
DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
|
||||
mSystemGestureExclusionLogDebounceTimeoutMillis =
|
||||
DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS, 0);
|
||||
mSystemGestureExcludedByPreQStickyImmersive =
|
||||
DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
|
||||
@@ -1163,6 +1177,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mSystemGestureExcludedByPreQStickyImmersive = excludedByPreQSticky;
|
||||
mRoot.forAllDisplays(DisplayContent::updateSystemGestureExclusionLimit);
|
||||
}
|
||||
|
||||
mSystemGestureExclusionLogDebounceTimeoutMillis =
|
||||
DeviceConfig.getInt(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS, 0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import static android.app.ActivityTaskManager.INVALID_STACK_ID;
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_DEFAULT;
|
||||
import static android.app.AppOpsManager.OP_NONE;
|
||||
import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.os.PowerManager.DRAW_WAKE_LOCK;
|
||||
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
@@ -80,6 +82,7 @@ import static com.android.server.policy.WindowManagerPolicy.TRANSIT_ENTER;
|
||||
import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT;
|
||||
import static com.android.server.policy.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
|
||||
import static com.android.server.wm.AnimationSpecProto.MOVE;
|
||||
import static com.android.server.wm.DisplayContent.logsGestureExclusionRestrictions;
|
||||
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
|
||||
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
|
||||
import static com.android.server.wm.IdentifierProto.HASH_CODE;
|
||||
@@ -174,6 +177,7 @@ import android.util.ArraySet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.MergedConfiguration;
|
||||
import android.util.Slog;
|
||||
import android.util.StatsLog;
|
||||
import android.util.TimeUtils;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.Display;
|
||||
@@ -227,6 +231,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
// to capture touch events in that area.
|
||||
static final int RESIZE_HANDLE_WIDTH_IN_DP = 30;
|
||||
|
||||
static final int EXCLUSION_LEFT = 0;
|
||||
static final int EXCLUSION_RIGHT = 1;
|
||||
|
||||
final WindowManagerPolicy mPolicy;
|
||||
final Context mContext;
|
||||
final Session mSession;
|
||||
@@ -397,6 +404,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
*/
|
||||
private final List<Rect> mExclusionRects = new ArrayList<>();
|
||||
|
||||
// 0 = left, 1 = right
|
||||
private final int[] mLastRequestedExclusionHeight = {0, 0};
|
||||
private final int[] mLastGrantedExclusionHeight = {0, 0};
|
||||
private final long[] mLastExclusionLogUptimeMillis = {0, 0};
|
||||
|
||||
private boolean mLastShownChangedReported;
|
||||
|
||||
// If a window showing a wallpaper: the requested offset for the
|
||||
// wallpaper; if a wallpaper window: the currently applied offset.
|
||||
float mWallpaperX = -1;
|
||||
@@ -679,6 +693,20 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
&& mAppToken != null && mAppToken.mTargetSdk < Build.VERSION_CODES.Q;
|
||||
}
|
||||
|
||||
void setLastExclusionHeights(int side, int requested, int granted) {
|
||||
boolean changed = mLastGrantedExclusionHeight[side] != granted
|
||||
|| mLastRequestedExclusionHeight[side] != requested;
|
||||
|
||||
if (changed) {
|
||||
if (mLastShownChangedReported) {
|
||||
logExclusionRestrictions(side);
|
||||
}
|
||||
|
||||
mLastGrantedExclusionHeight[side] = granted;
|
||||
mLastRequestedExclusionHeight[side] = requested;
|
||||
}
|
||||
}
|
||||
|
||||
interface PowerManagerWrapper {
|
||||
void wakeUp(long time, @WakeReason int reason, String details);
|
||||
|
||||
@@ -2957,6 +2985,49 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
||||
mAnimatingExit = false;
|
||||
}
|
||||
|
||||
void onSurfaceShownChanged(boolean shown) {
|
||||
if (mLastShownChangedReported == shown) {
|
||||
return;
|
||||
}
|
||||
mLastShownChangedReported = shown;
|
||||
|
||||
if (shown) {
|
||||
initExclusionRestrictions();
|
||||
} else {
|
||||
logExclusionRestrictions(EXCLUSION_LEFT);
|
||||
logExclusionRestrictions(EXCLUSION_RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
private void logExclusionRestrictions(int side) {
|
||||
if (!logsGestureExclusionRestrictions(this)
|
||||
|| SystemClock.uptimeMillis() < mLastExclusionLogUptimeMillis[side]
|
||||
+ mWmService.mSystemGestureExclusionLogDebounceTimeoutMillis) {
|
||||
// Drop the log if we have just logged; this is okay, because what we would have logged
|
||||
// was true only for a short duration.
|
||||
return;
|
||||
}
|
||||
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
final long duration = now - mLastExclusionLogUptimeMillis[side];
|
||||
mLastExclusionLogUptimeMillis[side] = now;
|
||||
|
||||
final int requested = mLastRequestedExclusionHeight[side];
|
||||
final int granted = mLastGrantedExclusionHeight[side];
|
||||
|
||||
StatsLog.write(StatsLog.EXCLUSION_RECT_STATE_CHANGED,
|
||||
mAttrs.packageName, requested, requested - granted /* rejected */,
|
||||
side + 1 /* Sides are 1-indexed in atoms.proto */,
|
||||
(getConfiguration().orientation == ORIENTATION_LANDSCAPE),
|
||||
isSplitScreenWindowingMode(getWindowingMode()), (int) duration);
|
||||
}
|
||||
|
||||
private void initExclusionRestrictions() {
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
mLastExclusionLogUptimeMillis[EXCLUSION_LEFT] = now;
|
||||
mLastExclusionLogUptimeMillis[EXCLUSION_RIGHT] = now;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefaultDisplay() {
|
||||
final DisplayContent displayContent = getDisplayContent();
|
||||
|
||||
@@ -507,6 +507,8 @@ class WindowSurfaceController {
|
||||
|
||||
mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mAnimator.mWin, surfaceShown);
|
||||
|
||||
mAnimator.mWin.onSurfaceShownChanged(surfaceShown);
|
||||
|
||||
if (mWindowSession != null) {
|
||||
mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType);
|
||||
}
|
||||
|
||||
@@ -756,7 +756,8 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
final ISystemGestureExclusionListener.Stub verifier =
|
||||
new ISystemGestureExclusionListener.Stub() {
|
||||
@Override
|
||||
public void onSystemGestureExclusionChanged(int displayId, Region actual) {
|
||||
public void onSystemGestureExclusionChanged(int displayId, Region actual,
|
||||
Region unrestricted) {
|
||||
Region expected = Region.obtain();
|
||||
expected.set(10, 20, 30, 40);
|
||||
assertEquals(expected, actual);
|
||||
@@ -790,7 +791,14 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
|
||||
final Region expected = Region.obtain();
|
||||
expected.set(20, 30, 40, 50);
|
||||
assertEquals(expected, dc.calculateSystemGestureExclusion());
|
||||
assertEquals(expected, calculateSystemGestureExclusion(dc));
|
||||
}
|
||||
|
||||
private Region calculateSystemGestureExclusion(DisplayContent dc) {
|
||||
Region out = Region.obtain();
|
||||
Region unrestricted = Region.obtain();
|
||||
dc.calculateSystemGestureExclusion(out, unrestricted);
|
||||
return out;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -814,7 +822,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
win2.setHasSurface(true);
|
||||
|
||||
final Region expected = Region.obtain();
|
||||
assertEquals(expected, dc.calculateSystemGestureExclusion());
|
||||
assertEquals(expected, calculateSystemGestureExclusion(dc));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -839,7 +847,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
|
||||
final Region expected = Region.obtain();
|
||||
expected.set(dc.getBounds());
|
||||
assertEquals(expected, dc.calculateSystemGestureExclusion());
|
||||
assertEquals(expected, calculateSystemGestureExclusion(dc));
|
||||
|
||||
win.setHasSurface(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user