Pointer icon refactor for mouse (base)
When PointerChoreographer is enabled, CursorInputMapper no longer
depends on the legacy PointerController. PointerChoreographer is
responsible for accumulating movements, fading/unfading pointers,
and deciding display/coordinates.
Test: atest libinputservice_test
Bug: 293587049
Change-Id: Ie35b385a99623bbcb2e47b394b7cf2c0f7c5bc0e
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index abd9284..576ebc1 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -24,6 +24,7 @@
#include <SkColor.h>
#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
+#include <com_android_input_flags.h>
#include <ftl/enum.h>
#include <mutex>
@@ -34,6 +35,8 @@
#define INDENT2 " "
#define INDENT3 " "
+namespace input_flags = com::android::input::flags;
+
namespace android {
namespace {
@@ -63,10 +66,20 @@
std::shared_ptr<PointerController> PointerController::create(
const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
- SpriteController& spriteController, bool enabled) {
+ SpriteController& spriteController, bool enabled, ControllerType type) {
// using 'new' to access non-public constructor
- std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>(
- new PointerController(policy, looper, spriteController, enabled));
+ std::shared_ptr<PointerController> controller;
+ switch (type) {
+ case ControllerType::MOUSE:
+ controller = std::shared_ptr<PointerController>(
+ new MousePointerController(policy, looper, spriteController, enabled));
+ break;
+ case ControllerType::LEGACY:
+ default:
+ controller = std::shared_ptr<PointerController>(
+ new PointerController(policy, looper, spriteController, enabled));
+ break;
+ }
/*
* Now we need to hook up the constructed PointerController object to its callbacks.
@@ -375,4 +388,13 @@
return dump;
}
+// --- MousePointerController ---
+
+MousePointerController::MousePointerController(const sp<PointerControllerPolicyInterface>& policy,
+ const sp<Looper>& looper,
+ SpriteController& spriteController, bool enabled)
+ : PointerController(policy, looper, spriteController, enabled) {
+ PointerController::setPresentation(Presentation::POINTER);
+}
+
} // namespace android
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index aa7ca3c..08e19a0 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -47,7 +47,8 @@
public:
static std::shared_ptr<PointerController> create(
const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
- SpriteController& spriteController, bool enabled);
+ SpriteController& spriteController, bool enabled,
+ ControllerType type = ControllerType::LEGACY);
~PointerController() override;
@@ -75,7 +76,7 @@
void onDisplayInfosChangedLocked(const std::vector<gui::DisplayInfo>& displayInfos)
REQUIRES(getLock());
- std::string dump();
+ std::string dump() override;
protected:
using WindowListenerConsumer =
@@ -87,10 +88,10 @@
WindowListenerConsumer registerListener,
WindowListenerConsumer unregisterListener);
-private:
PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
SpriteController& spriteController, bool enabled);
+private:
friend PointerControllerContext::LooperCallback;
friend PointerControllerContext::MessageHandler;
@@ -135,6 +136,24 @@
void clearSpotsLocked() REQUIRES(getLock());
};
+class MousePointerController : public PointerController {
+public:
+ /** A version of PointerController that controls one mouse pointer. */
+ MousePointerController(const sp<PointerControllerPolicyInterface>& policy,
+ const sp<Looper>& looper, SpriteController& spriteController,
+ bool enabled);
+
+ void setPresentation(Presentation) override {
+ LOG_ALWAYS_FATAL("Should not be called");
+ }
+ void setSpots(const PointerCoords*, const uint32_t*, BitSet32, int32_t) override {
+ LOG_ALWAYS_FATAL("Should not be called");
+ }
+ void clearSpots() override {
+ LOG_ALWAYS_FATAL("Should not be called");
+ }
+};
+
} // namespace android
#endif // _UI_POINTER_CONTROLLER_H
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 176bc283..5767c49 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -86,6 +86,8 @@
namespace android {
+static const bool ENABLE_POINTER_CHOREOGRAPHER = input_flags::enable_pointer_choreographer();
+
// The exponent used to calculate the pointer speed scaling factor.
// The scaling factor is calculated as 2 ^ (speed * exponent),
// where the speed ranges from -7 to + 7 and is supplied by the user.
@@ -327,6 +329,8 @@
TouchAffineTransformation getTouchAffineTransformation(JNIEnv* env, jfloatArray matrixArr);
void notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) override;
bool isInputMethodConnectionActive() override;
+ std::optional<DisplayViewport> getViewportForPointerDevice(
+ int32_t associatedDisplayId) override;
/* --- InputDispatcherPolicyInterface implementation --- */
@@ -374,8 +378,10 @@
virtual PointerIconStyle getCustomPointerIconId();
virtual void onPointerDisplayIdChanged(int32_t displayId, const FloatPoint& position);
- /* --- PointerControllerPolicyInterface implementation --- */
- std::shared_ptr<PointerControllerInterface> createPointerController() override;
+ /* --- PointerChoreographerPolicyInterface implementation --- */
+ std::shared_ptr<PointerControllerInterface> createPointerController(
+ PointerControllerInterface::ControllerType type) override;
+ void notifyPointerDisplayIdChanged(int32_t displayId, const FloatPoint& position) override;
private:
sp<InputManagerInterface> mInputManager;
@@ -492,7 +498,9 @@
dump += StringPrintf(INDENT "Pointer Capture: %s, seq=%" PRIu32 "\n",
mLocked.pointerCaptureRequest.enable ? "Enabled" : "Disabled",
mLocked.pointerCaptureRequest.seq);
- forEachPointerControllerLocked([&dump](PointerController& pc) { dump += pc.dump(); });
+ if (auto pc = mLocked.legacyPointerController.lock(); pc) {
+ dump += pc->dump();
+ }
} // release lock
dump += "\n";
@@ -537,6 +545,9 @@
[&viewports](PointerController& pc) { pc.onDisplayViewportsUpdated(viewports); });
} // release lock
+ if (ENABLE_POINTER_CHOREOGRAPHER) {
+ mInputManager->getChoreographer().setDisplayViewports(viewports);
+ }
mInputManager->getReader().requestRefreshConfiguration(
InputReaderConfiguration::Change::DISPLAY_INFO);
}
@@ -721,6 +732,7 @@
continue;
}
apply(*pc);
+ it++;
}
}
@@ -735,9 +747,6 @@
if (controller == nullptr) {
ensureSpriteControllerLocked();
- static const bool ENABLE_POINTER_CHOREOGRAPHER =
- input_flags::enable_pointer_choreographer();
-
// Disable the functionality of the legacy PointerController if PointerChoreographer is
// enabled.
controller = PointerController::create(this, mLooper, *mLocked.spriteController,
@@ -749,17 +758,43 @@
return controller;
}
-std::shared_ptr<PointerControllerInterface> NativeInputManager::createPointerController() {
+std::shared_ptr<PointerControllerInterface> NativeInputManager::createPointerController(
+ PointerControllerInterface::ControllerType type) {
std::scoped_lock _l(mLock);
ensureSpriteControllerLocked();
std::shared_ptr<PointerController> pc =
- PointerController::create(this, mLooper, *mLocked.spriteController, /*enabled=*/true);
+ PointerController::create(this, mLooper, *mLocked.spriteController, /*enabled=*/true,
+ type);
mLocked.pointerControllers.emplace_back(pc);
return pc;
}
void NativeInputManager::onPointerDisplayIdChanged(int32_t pointerDisplayId,
const FloatPoint& position) {
+ if (ENABLE_POINTER_CHOREOGRAPHER) {
+ return;
+ }
+ JNIEnv* env = jniEnv();
+ env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDisplayIdChanged, pointerDisplayId,
+ position.x, position.y);
+ checkAndClearExceptionFromCallback(env, "onPointerDisplayIdChanged");
+}
+
+void NativeInputManager::notifyPointerDisplayIdChanged(int32_t pointerDisplayId,
+ const FloatPoint& position) {
+ // Notify the Reader so that devices can be reconfigured.
+ { // acquire lock
+ std::scoped_lock _l(mLock);
+ if (mLocked.pointerDisplayId == pointerDisplayId) {
+ return;
+ }
+ mLocked.pointerDisplayId = pointerDisplayId;
+ ALOGI("%s: pointer displayId set to: %d", __func__, pointerDisplayId);
+ } // release lock
+ mInputManager->getReader().requestRefreshConfiguration(
+ InputReaderConfiguration::Change::DISPLAY_INFO);
+
+ // Notify the system.
JNIEnv* env = jniEnv();
env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDisplayIdChanged, pointerDisplayId,
position.x, position.y);
@@ -1118,19 +1153,23 @@
}
void NativeInputManager::setPointerDisplayId(int32_t displayId) {
- { // acquire lock
- std::scoped_lock _l(mLock);
+ if (ENABLE_POINTER_CHOREOGRAPHER) {
+ mInputManager->getChoreographer().setDefaultMouseDisplayId(displayId);
+ } else {
+ { // acquire lock
+ std::scoped_lock _l(mLock);
- if (mLocked.pointerDisplayId == displayId) {
- return;
- }
+ if (mLocked.pointerDisplayId == displayId) {
+ return;
+ }
- ALOGI("Setting pointer display id to %d.", displayId);
- mLocked.pointerDisplayId = displayId;
- } // release lock
+ ALOGI("Setting pointer display id to %d.", displayId);
+ mLocked.pointerDisplayId = displayId;
+ } // release lock
- mInputManager->getReader().requestRefreshConfiguration(
- InputReaderConfiguration::Change::DISPLAY_INFO);
+ mInputManager->getReader().requestRefreshConfiguration(
+ InputReaderConfiguration::Change::DISPLAY_INFO);
+ }
}
void NativeInputManager::setPointerSpeed(int32_t speed) {
@@ -1356,6 +1395,11 @@
return result;
}
+std::optional<DisplayViewport> NativeInputManager::getViewportForPointerDevice(
+ int32_t associatedDisplayId) {
+ return mInputManager->getChoreographer().getViewportForPointerDevice(associatedDisplayId);
+}
+
bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) {
ATRACE_CALL();
JNIEnv* env = jniEnv();
@@ -1689,6 +1733,9 @@
}
FloatPoint NativeInputManager::getMouseCursorPosition() {
+ if (ENABLE_POINTER_CHOREOGRAPHER) {
+ return mInputManager->getChoreographer().getMouseCursorPosition(ADISPLAY_ID_NONE);
+ }
std::scoped_lock _l(mLock);
const auto pc = mLocked.legacyPointerController.lock();
if (!pc) return {AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION};