diff options
3 files changed, 208 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index e555761e34e1..a69c7efc5b21 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.provider.DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT; 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.LocalServices; 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 @@ public class InputManagerService extends IInputManager.Stub // 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 @@ public class InputManagerService extends IInputManager.Stub 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 @@ public class InputManagerService extends IInputManager.Stub 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 000000000000..5fca771c48b9 --- /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 000000000000..9c2aa3677655 --- /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 |