Support PointerLocation on secondary display
- Move PointerLocation from PhoneWindowManager to DisplayPolicy.
- Observe PointerLocation system setting in WindowManagerService.
- Enable only for default display or non-private display.
Bug: 126463475
Test: Enable PointerLocation, enable desktop mode, use mouse
or touch on second display.
Change-Id: Ifbfce5a9ac4ec69530920884703445750704b5e2
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c0e5974..5810636 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -44,7 +44,6 @@
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SYSTEM_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -127,7 +126,6 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.ContentObserver;
-import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
@@ -211,7 +209,6 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ScreenshotHelper;
-import com.android.internal.widget.PointerLocationView;
import com.android.server.ExtconStateObserver;
import com.android.server.ExtconUEventObserver;
import com.android.server.GestureLauncherService;
@@ -494,9 +491,6 @@
private boolean mHandleVolumeKeysInWM;
- int mPointerLocationMode = 0; // guarded by mLock
- PointerLocationView mPointerLocationView;
-
private boolean mPendingKeyguardOccluded;
private boolean mKeyguardOccludedChanged;
private boolean mNotifyUserActivity;
@@ -619,8 +613,6 @@
private boolean mPerDisplayFocusEnabled = false;
private volatile int mTopFocusedDisplayId = INVALID_DISPLAY;
- private static final int MSG_ENABLE_POINTER_LOCATION = 1;
- private static final int MSG_DISABLE_POINTER_LOCATION = 2;
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
@@ -651,12 +643,6 @@
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case MSG_ENABLE_POINTER_LOCATION:
- enablePointerLocation();
- break;
- case MSG_DISABLE_POINTER_LOCATION:
- disablePointerLocation();
- break;
case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK:
dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj);
break;
@@ -779,9 +765,6 @@
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT), false, this,
UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.POINTER_LOCATION), false, this,
- UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
UserHandle.USER_ALL);
@@ -2007,15 +1990,6 @@
updateWakeGestureListenerLp();
}
- if (mSystemReady) {
- int pointerLocation = Settings.System.getIntForUser(resolver,
- Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT);
- if (mPointerLocationMode != pointerLocation) {
- mPointerLocationMode = pointerLocation;
- mHandler.sendEmptyMessage(pointerLocation != 0 ?
- MSG_ENABLE_POINTER_LOCATION : MSG_DISABLE_POINTER_LOCATION);
- }
- }
// use screen off timeout setting as the timeout for the lockscreen
mLockScreenTimeout = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT, 0, UserHandle.USER_CURRENT);
@@ -2047,46 +2021,6 @@
&& mWakeGestureListener.isSupported();
}
- private void enablePointerLocation() {
- if (mPointerLocationView == null) {
- mPointerLocationView = new PointerLocationView(mContext);
- mPointerLocationView.setPrintCoords(false);
- WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- WindowManager.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.MATCH_PARENT);
- lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
- lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
- | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
- lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- if (ActivityManager.isHighEndGfx()) {
- lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
- lp.privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
- }
- lp.format = PixelFormat.TRANSLUCENT;
- lp.setTitle("PointerLocation");
- WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
- lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
- wm.addView(mPointerLocationView, lp);
- //TODO (b/111365687) : make system context per display.
- mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView, DEFAULT_DISPLAY);
- }
- }
-
- private void disablePointerLocation() {
- if (mPointerLocationView != null) {
- //TODO (b/111365687) : make system context per display.
- mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView,
- DEFAULT_DISPLAY);
- WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
- wm.removeView(mPointerLocationView);
- mPointerLocationView = null;
- }
- }
-
-
/** {@inheritDoc} */
@Override
public int checkAddPermission(WindowManager.LayoutParams attrs, int[] outAppOp) {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index e48361f..4649635 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -44,8 +44,8 @@
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_STATUS_BAR_VISIBLE_TRANSPARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR;
@@ -113,6 +113,7 @@
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Insets;
+import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.hardware.power.V1_0.PowerHint;
@@ -149,6 +150,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.util.ScreenshotHelper;
+import com.android.internal.widget.PointerLocationView;
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.policy.WindowManagerPolicy;
@@ -343,6 +345,8 @@
private InputConsumer mInputConsumer = null;
+ private PointerLocationView mPointerLocationView;
+
/**
* The area covered by system windows which belong to another display. Forwarded insets is set
* in case this is a virtual display, this is displayed on another display that has insets, and
@@ -357,6 +361,8 @@
private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 1;
private static final int MSG_REQUEST_TRANSIENT_BARS = 2;
private static final int MSG_DISPOSE_INPUT_CONSUMER = 3;
+ private static final int MSG_ENABLE_POINTER_LOCATION = 4;
+ private static final int MSG_DISABLE_POINTER_LOCATION = 5;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -383,6 +389,12 @@
case MSG_DISPOSE_INPUT_CONSUMER:
disposeInputConsumer((InputConsumer) msg.obj);
break;
+ case MSG_ENABLE_POINTER_LOCATION:
+ enablePointerLocation();
+ break;
+ case MSG_DISABLE_POINTER_LOCATION:
+ disablePointerLocation();
+ break;
}
}
}
@@ -541,6 +553,9 @@
void systemReady() {
mSystemGestures.systemReady();
+ if (mService.mPointerLocationEnabled) {
+ setPointerLocationEnabled(true);
+ }
}
private int getDisplayId() {
@@ -747,7 +762,7 @@
case TYPE_WALLPAPER:
// Dreams and wallpapers don't have an app window token and can thus not be
// letterboxed. Hence always let them extend under the cutout.
- attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
break;
case TYPE_STATUS_BAR:
@@ -2095,7 +2110,7 @@
// Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
// the cutout safe zone.
- if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
+ if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES) {
final Rect displayCutoutSafeExceptMaybeBars = sTmpDisplayCutoutSafeExceptMaybeBarsRect;
displayCutoutSafeExceptMaybeBars.set(displayFrames.mDisplayCutoutSafe);
if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
@@ -3414,4 +3429,57 @@
pw.print(prefix); pw.println("Looper state:");
mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " ");
}
+
+ private boolean supportsPointerLocation() {
+ return mDisplayContent.isDefaultDisplay || !mDisplayContent.isPrivate();
+ }
+
+ void setPointerLocationEnabled(boolean pointerLocationEnabled) {
+ if (!supportsPointerLocation()) {
+ return;
+ }
+
+ mHandler.sendEmptyMessage(pointerLocationEnabled
+ ? MSG_ENABLE_POINTER_LOCATION : MSG_DISABLE_POINTER_LOCATION);
+ }
+
+ private void enablePointerLocation() {
+ if (mPointerLocationView != null) {
+ return;
+ }
+
+ mPointerLocationView = new PointerLocationView(mContext);
+ mPointerLocationView.setPrintCoords(false);
+ final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ WindowManager.LayoutParams.MATCH_PARENT,
+ WindowManager.LayoutParams.MATCH_PARENT);
+ lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
+ lp.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+ lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
+ if (ActivityManager.isHighEndGfx()) {
+ lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+ lp.privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
+ }
+ lp.format = PixelFormat.TRANSLUCENT;
+ lp.setTitle("PointerLocation - display " + getDisplayId());
+ lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ wm.addView(mPointerLocationView, lp);
+ mDisplayContent.registerPointerEventListener(mPointerLocationView);
+ }
+
+ private void disablePointerLocation() {
+ if (mPointerLocationView == null) {
+ return;
+ }
+
+ mDisplayContent.unregisterPointerEventListener(mPointerLocationView);
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ wm.removeView(mPointerLocationView);
+ mPointerLocationView = null;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e3a8be5..b973ed5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -689,6 +689,8 @@
Settings.Secure.getUriFor(Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS);
private final Uri mPolicyControlUri =
Settings.Global.getUriFor(Settings.Global.POLICY_CONTROL);
+ private final Uri mPointerLocationUri =
+ Settings.System.getUriFor(Settings.System.POINTER_LOCATION);
public SettingsObserver() {
super(new Handler());
@@ -703,8 +705,8 @@
UserHandle.USER_ALL);
resolver.registerContentObserver(mImmersiveModeConfirmationsUri, false, this,
UserHandle.USER_ALL);
- resolver.registerContentObserver(mPolicyControlUri, false, this,
- UserHandle.USER_ALL);
+ resolver.registerContentObserver(mPolicyControlUri, false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(mPointerLocationUri, false, this, UserHandle.USER_ALL);
}
@Override
@@ -723,6 +725,11 @@
return;
}
+ if (mPointerLocationUri.equals(uri)) {
+ updatePointerLocation();
+ return;
+ }
+
@UpdateAnimationScaleMode
final int mode;
if (mWindowAnimationScaleUri.equals(uri)) {
@@ -749,6 +756,22 @@
updateRotation(false /* alwaysSendConfiguration */, false /* forceRelayout */);
}
}
+
+ void updatePointerLocation() {
+ ContentResolver resolver = mContext.getContentResolver();
+ final boolean enablePointerLocation = Settings.System.getIntForUser(resolver,
+ Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT) != 0;
+
+ if (mPointerLocationEnabled == enablePointerLocation) {
+ return;
+ }
+ mPointerLocationEnabled = enablePointerLocation;
+ synchronized (mGlobalLock) {
+ mRoot.forAllDisplayPolicies(PooledLambda.obtainConsumer(
+ DisplayPolicy::setPointerLocationEnabled, PooledLambda.__(),
+ mPointerLocationEnabled));
+ }
+ }
}
PowerManager mPowerManager;
@@ -758,6 +781,7 @@
private float mTransitionAnimationScaleSetting = 1.0f;
private float mAnimatorDurationScaleSetting = 1.0f;
private boolean mAnimationsDisabled = false;
+ boolean mPointerLocationEnabled = false;
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
@@ -4363,6 +4387,7 @@
mHasWideColorGamutSupport = queryWideColorGamutSupport();
mHasHdrSupport = queryHdrSupport();
UiThread.getHandler().post(mSettingsObserver::updateSystemUiSettings);
+ UiThread.getHandler().post(mSettingsObserver::updatePointerLocation);
IVrManager vrManager = IVrManager.Stub.asInterface(
ServiceManager.getService(Context.VR_SERVICE));
if (vrManager != null) {