Merge "Create prototype for TouchpadDebugView" into main
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e555761..a69c7ef 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -20,6 +20,8 @@
import static android.view.KeyEvent.KEYCODE_UNKNOWN;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static com.android.hardware.input.Flags.touchpadVisualizer;
+
import android.Manifest;
import android.annotation.EnforcePermission;
import android.annotation.NonNull;
@@ -121,6 +123,7 @@
import com.android.server.Watchdog;
import com.android.server.input.InputManagerInternal.LidSwitchCallback;
import com.android.server.input.debug.FocusEventDebugView;
+import com.android.server.input.debug.TouchpadDebugViewController;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
@@ -303,6 +306,9 @@
// Manages battery state for input devices.
private final BatteryController mBatteryController;
+ @Nullable
+ private final TouchpadDebugViewController mTouchpadDebugViewController;
+
// Manages Keyboard backlight
private final KeyboardBacklightControllerInterface mKeyboardBacklightController;
@@ -460,6 +466,9 @@
mSettingsObserver = new InputSettingsObserver(mContext, mHandler, this, mNative);
mKeyboardLayoutManager = new KeyboardLayoutManager(mContext, mNative, mDataStore,
injector.getLooper());
+ mTouchpadDebugViewController =
+ touchpadVisualizer() ? new TouchpadDebugViewController(mContext,
+ injector.getLooper()) : null;
mBatteryController = new BatteryController(mContext, mNative, injector.getLooper(),
injector.getUEventManager());
mKeyboardBacklightController = InputFeatureFlagProvider.isKeyboardBacklightControlEnabled()
@@ -589,6 +598,9 @@
mKeyRemapper.systemRunning();
mPointerIconCache.systemRunning();
mKeyboardGlyphManager.systemRunning();
+ if (mTouchpadDebugViewController != null) {
+ mTouchpadDebugViewController.systemRunning();
+ }
}
private void reloadDeviceAliases() {
diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugView.java b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
new file mode 100644
index 0000000..5fca771
--- /dev/null
+++ b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input.debug;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class TouchpadDebugView extends LinearLayout {
+
+ /**
+ * Input device ID for the touchpad that this debug view is displaying.
+ */
+ private final int mTouchpadId;
+
+ public TouchpadDebugView(Context context, int touchpadId) {
+ super(context);
+ mTouchpadId = touchpadId;
+ init(context);
+ }
+
+ private void init(Context context) {
+ setOrientation(VERTICAL);
+ setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT));
+ setBackgroundColor(Color.TRANSPARENT);
+
+ // TODO(b/286551975): Replace this content with the touchpad debug view.
+
+ TextView textView1 = new TextView(context);
+ textView1.setBackgroundColor(Color.parseColor("#FFFF0000"));
+ textView1.setTextSize(20);
+ textView1.setText("Touchpad Debug View 1");
+ textView1.setGravity(Gravity.CENTER);
+ textView1.setTextColor(Color.WHITE);
+
+ textView1.setLayoutParams(new LayoutParams(1000, 200));
+
+ TextView textView2 = new TextView(context);
+ textView2.setBackgroundColor(Color.BLUE);
+ textView2.setTextSize(20);
+ textView2.setText("Touchpad Debug View 2");
+ textView2.setGravity(Gravity.CENTER);
+ textView2.setTextColor(Color.WHITE);
+ textView2.setLayoutParams(new LayoutParams(1000, 200));
+
+ addView(textView1);
+ addView(textView2);
+ }
+
+ public int getTouchpadId() {
+ return mTouchpadId;
+ }
+}
diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
new file mode 100644
index 0000000..9c2aa36
--- /dev/null
+++ b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input.debug;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.hardware.display.DisplayManager;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Slog;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.InputDevice;
+import android.view.WindowManager;
+
+import java.util.Objects;
+
+public class TouchpadDebugViewController {
+
+ private static final String TAG = "TouchpadDebugViewController";
+
+ private final Context mContext;
+ private final Handler mHandler;
+ @Nullable
+ private TouchpadDebugView mTouchpadDebugView;
+
+ public TouchpadDebugViewController(Context context, Looper looper) {
+ final DisplayManager displayManager = Objects.requireNonNull(
+ context.getSystemService(DisplayManager.class));
+ final Display defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ mContext = context.createDisplayContext(defaultDisplay);
+ mHandler = new Handler(looper);
+ }
+
+ public void systemRunning() {
+ final InputManager inputManager = Objects.requireNonNull(
+ mContext.getSystemService(InputManager.class));
+ inputManager.registerInputDeviceListener(mInputDeviceListener, mHandler);
+ for (int deviceId : inputManager.getInputDeviceIds()) {
+ mInputDeviceListener.onInputDeviceAdded(deviceId);
+ }
+ }
+
+ private final InputManager.InputDeviceListener mInputDeviceListener =
+ new InputManager.InputDeviceListener() {
+ @Override
+ public void onInputDeviceAdded(int deviceId) {
+ final InputManager inputManager = Objects.requireNonNull(
+ mContext.getSystemService(InputManager.class));
+ InputDevice inputDevice = inputManager.getInputDevice(deviceId);
+
+ if (Objects.requireNonNull(inputDevice).supportsSource(
+ InputDevice.SOURCE_TOUCHPAD | InputDevice.SOURCE_MOUSE)) {
+ showDebugView(deviceId);
+ }
+ }
+
+ @Override
+ public void onInputDeviceRemoved(int deviceId) {
+ hideDebugView(deviceId);
+ }
+
+ @Override
+ public void onInputDeviceChanged(int deviceId) {
+ }
+ };
+
+ private void showDebugView(int touchpadId) {
+ if (mTouchpadDebugView != null) {
+ return;
+ }
+ final WindowManager wm = Objects.requireNonNull(
+ mContext.getSystemService(WindowManager.class));
+
+ mTouchpadDebugView = new TouchpadDebugView(mContext, touchpadId);
+
+ final WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
+ lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+ lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+ lp.setFitInsetsTypes(0);
+ lp.layoutInDisplayCutoutMode =
+ WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ lp.format = PixelFormat.TRANSLUCENT;
+ lp.setTitle("TouchpadDebugView - display " + mContext.getDisplayId());
+ lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+
+ lp.x = 40;
+ lp.y = 100;
+ lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
+ lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ lp.gravity = Gravity.TOP | Gravity.LEFT;
+
+ wm.addView(mTouchpadDebugView, lp);
+ Slog.d(TAG, "Touchpad debug view created.");
+ }
+
+ private void hideDebugView(int touchpadId) {
+ if (mTouchpadDebugView == null || mTouchpadDebugView.getTouchpadId() != touchpadId) {
+ return;
+ }
+ final WindowManager wm = Objects.requireNonNull(
+ mContext.getSystemService(WindowManager.class));
+ wm.removeView(mTouchpadDebugView);
+ mTouchpadDebugView = null;
+ Slog.d(TAG, "Touchpad debug view removed.");
+ }
+}
\ No newline at end of file