blob: f43586f8d9d069bb1915c90689797ae307bd1bc2 [file] [log] [blame]
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "PointerController"
Jeff Brownb4ff35d2011-01-02 16:37:43 -080018//#define LOG_NDEBUG 0
19
Prabir Pradhan02b05452021-11-17 21:48:11 +000020#include "PointerController.h"
Prabir Pradhan02b05452021-11-17 21:48:11 +000021#include "PointerControllerContext.h"
Prabir Pradhan02b05452021-11-17 21:48:11 +000022
Liam Harringtonc782be62020-07-17 19:48:24 +000023#include <SkBlendMode.h>
24#include <SkCanvas.h>
25#include <SkColor.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080026
27namespace android {
28
Prabir Pradhanf97fac32021-11-18 16:40:34 +000029namespace {
30
31const ui::Transform kIdentityTransform;
32
33} // namespace
34
35// --- PointerController::DisplayInfoListener ---
36
37void PointerController::DisplayInfoListener::onWindowInfosChanged(
38 const std::vector<android::gui::WindowInfo>&,
39 const std::vector<android::gui::DisplayInfo>& displayInfo) {
40 mPointerController.onDisplayInfosChanged(displayInfo);
41}
42
Jeff Brownb4ff35d2011-01-02 16:37:43 -080043// --- PointerController ---
44
Michael Wrighta0bc6b12020-06-26 20:25:34 +010045std::shared_ptr<PointerController> PointerController::create(
46 const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
47 const sp<SpriteController>& spriteController) {
Liam Harringtonc782be62020-07-17 19:48:24 +000048 // using 'new' to access non-public constructor
Michael Wrighta0bc6b12020-06-26 20:25:34 +010049 std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>(
50 new PointerController(policy, looper, spriteController));
Jeff Brown2352b972011-04-12 22:39:53 -070051
Michael Wrighta0bc6b12020-06-26 20:25:34 +010052 /*
53 * Now we need to hook up the constructed PointerController object to its callbacks.
54 *
55 * This must be executed after the constructor but before any other methods on PointerController
56 * in order to ensure that the fully constructed object is visible on the Looper thread, since
57 * that may be a different thread than where the PointerController is initially constructed.
58 *
59 * Unfortunately, this cannot be done as part of the constructor since we need to hand out
60 * weak_ptr's which themselves cannot be constructed until there's at least one shared_ptr.
61 */
Jeff Brown5541de92011-04-11 11:54:25 -070062
Liam Harringtonc782be62020-07-17 19:48:24 +000063 controller->mContext.setHandlerController(controller);
64 controller->mContext.setCallbackController(controller);
Michael Wrighta0bc6b12020-06-26 20:25:34 +010065 return controller;
66}
Jun Mukaic0c0ac32015-10-27 10:09:21 -070067
Michael Wrighta0bc6b12020-06-26 20:25:34 +010068PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
69 const sp<Looper>& looper,
70 const sp<SpriteController>& spriteController)
Prabir Pradhanf97fac32021-11-18 16:40:34 +000071 : mContext(policy, looper, spriteController, *this),
72 mCursorController(mContext),
73 mDisplayInfoListener(new DisplayInfoListener(*this)) {
Liam Harringtonc782be62020-07-17 19:48:24 +000074 std::scoped_lock lock(mLock);
75 mLocked.presentation = Presentation::SPOT;
Prabir Pradhanf97fac32021-11-18 16:40:34 +000076 SurfaceComposerClient::getDefault()->addWindowInfosListener(mDisplayInfoListener);
77}
78
79PointerController::~PointerController() {
80 SurfaceComposerClient::getDefault()->removeWindowInfosListener(mDisplayInfoListener);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080081}
82
Liam Harringtonc782be62020-07-17 19:48:24 +000083bool PointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
84 float* outMaxY) const {
85 return mCursorController.getBounds(outMinX, outMinY, outMaxX, outMaxY);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080086}
87
88void PointerController::move(float deltaX, float deltaY) {
Prabir Pradhanf97fac32021-11-18 16:40:34 +000089 const int32_t displayId = mCursorController.getDisplayId();
90 vec2 transformed;
91 {
92 std::scoped_lock lock(mLock);
93 const auto& transform = getTransformForDisplayLocked(displayId);
94 transformed = transformWithoutTranslation(transform, {deltaX, deltaY});
95 }
96 mCursorController.move(transformed.x, transformed.y);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080097}
98
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070099void PointerController::setButtonState(int32_t buttonState) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000100 mCursorController.setButtonState(buttonState);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800101}
102
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700103int32_t PointerController::getButtonState() const {
Liam Harringtonc782be62020-07-17 19:48:24 +0000104 return mCursorController.getButtonState();
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800105}
106
107void PointerController::setPosition(float x, float y) {
Prabir Pradhanf97fac32021-11-18 16:40:34 +0000108 const int32_t displayId = mCursorController.getDisplayId();
109 vec2 transformed;
110 {
111 std::scoped_lock lock(mLock);
112 const auto& transform = getTransformForDisplayLocked(displayId);
113 transformed = transform.transform(x, y);
114 }
115 mCursorController.setPosition(transformed.x, transformed.y);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800116}
117
118void PointerController::getPosition(float* outX, float* outY) const {
Prabir Pradhanf97fac32021-11-18 16:40:34 +0000119 const int32_t displayId = mCursorController.getDisplayId();
Liam Harringtonc782be62020-07-17 19:48:24 +0000120 mCursorController.getPosition(outX, outY);
Prabir Pradhanf97fac32021-11-18 16:40:34 +0000121 {
122 std::scoped_lock lock(mLock);
123 const auto& transform = getTransformForDisplayLocked(displayId);
124 const auto xy = transform.inverse().transform(*outX, *outY);
125 *outX = xy.x;
126 *outY = xy.y;
127 }
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800128}
129
Arthur Hungb9b32002018-12-18 17:39:43 +0800130int32_t PointerController::getDisplayId() const {
Liam Harringtonc782be62020-07-17 19:48:24 +0000131 return mCursorController.getDisplayId();
Arthur Hungb9b32002018-12-18 17:39:43 +0800132}
133
Jeff Brown538881e2011-05-25 18:23:38 -0700134void PointerController::fade(Transition transition) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000135 std::scoped_lock lock(mLock);
136 mCursorController.fade(transition);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800137}
138
Jeff Brown538881e2011-05-25 18:23:38 -0700139void PointerController::unfade(Transition transition) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000140 std::scoped_lock lock(mLock);
141 mCursorController.unfade(transition);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800142}
143
Jeff Brown2352b972011-04-12 22:39:53 -0700144void PointerController::setPresentation(Presentation presentation) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000145 std::scoped_lock lock(mLock);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800146
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800147 if (mLocked.presentation == presentation) {
148 return;
Jun Mukai1db53972015-09-11 18:08:31 -0700149 }
150
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800151 mLocked.presentation = presentation;
Jeff Brown2352b972011-04-12 22:39:53 -0700152
Liam Harringtonc782be62020-07-17 19:48:24 +0000153 if (!mCursorController.isViewportValid()) {
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800154 return;
155 }
156
Michael Wright6853fe62020-07-02 00:01:38 +0100157 if (presentation == Presentation::POINTER) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000158 mCursorController.getAdditionalMouseResources();
159 clearSpotsLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800160 }
161}
162
Liam Harringtonc782be62020-07-17 19:48:24 +0000163void PointerController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
164 BitSet32 spotIdBits, int32_t displayId) {
165 std::scoped_lock lock(mLock);
Prabir Pradhanf97fac32021-11-18 16:40:34 +0000166 std::array<PointerCoords, MAX_POINTERS> outSpotCoords{};
167 const ui::Transform& transform = getTransformForDisplayLocked(displayId);
168
169 for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
170 const uint32_t index = spotIdToIndex[idBits.clearFirstMarkedBit()];
171
172 const vec2 xy = transform.transform(spotCoords[index].getXYValue());
173 outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
174 outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
175
176 float pressure = spotCoords[index].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
177 outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
178 }
179
Liam Harringtonc782be62020-07-17 19:48:24 +0000180 auto it = mLocked.spotControllers.find(displayId);
181 if (it == mLocked.spotControllers.end()) {
182 mLocked.spotControllers.try_emplace(displayId, displayId, mContext);
Jeff Brown2352b972011-04-12 22:39:53 -0700183 }
Prabir Pradhanf97fac32021-11-18 16:40:34 +0000184 mLocked.spotControllers.at(displayId).setSpots(outSpotCoords.data(), spotIdToIndex, spotIdBits);
Jeff Brown2352b972011-04-12 22:39:53 -0700185}
186
187void PointerController::clearSpots() {
Liam Harringtonc782be62020-07-17 19:48:24 +0000188 std::scoped_lock lock(mLock);
189 clearSpotsLocked();
190}
Jeff Brown2352b972011-04-12 22:39:53 -0700191
Liam Harringtonc782be62020-07-17 19:48:24 +0000192void PointerController::clearSpotsLocked() REQUIRES(mLock) {
193 for (auto& [displayID, spotController] : mLocked.spotControllers) {
194 spotController.clearSpots();
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800195 }
Jeff Brown2352b972011-04-12 22:39:53 -0700196}
197
198void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000199 mContext.setInactivityTimeout(inactivityTimeout);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800200}
201
Jun Mukai19a56012015-11-24 11:25:52 -0800202void PointerController::reloadPointerResources() {
Liam Harringtonc782be62020-07-17 19:48:24 +0000203 std::scoped_lock lock(mLock);
Jun Mukai19a56012015-11-24 11:25:52 -0800204
Liam Harringtonc782be62020-07-17 19:48:24 +0000205 for (auto& [displayID, spotController] : mLocked.spotControllers) {
206 spotController.reloadSpotResources();
207 }
Jun Mukai19a56012015-11-24 11:25:52 -0800208
Liam Harringtonc782be62020-07-17 19:48:24 +0000209 if (mCursorController.resourcesLoaded()) {
210 bool getAdditionalMouseResources = false;
211 if (mLocked.presentation == PointerController::Presentation::POINTER) {
212 getAdditionalMouseResources = true;
213 }
214 mCursorController.reloadPointerResources(getAdditionalMouseResources);
Arthur Hungb9b32002018-12-18 17:39:43 +0800215 }
216}
217
218void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000219 std::scoped_lock lock(mLock);
220
221 bool getAdditionalMouseResources = false;
222 if (mLocked.presentation == PointerController::Presentation::POINTER) {
223 getAdditionalMouseResources = true;
Jeff Brownd728bf52012-09-08 18:05:28 -0700224 }
Liam Harringtonc782be62020-07-17 19:48:24 +0000225 mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800226}
227
Michael Wrighte051f6f2016-05-13 17:44:16 +0100228void PointerController::updatePointerIcon(int32_t iconId) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000229 std::scoped_lock lock(mLock);
230 mCursorController.updatePointerIcon(iconId);
Jun Mukai1db53972015-09-11 18:08:31 -0700231}
232
Jun Mukaid4eaef72015-10-30 15:54:33 -0700233void PointerController::setCustomPointerIcon(const SpriteIcon& icon) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000234 std::scoped_lock lock(mLock);
235 mCursorController.setCustomPointerIcon(icon);
Jun Mukaic0c0ac32015-10-27 10:09:21 -0700236}
237
Jeff Brown2352b972011-04-12 22:39:53 -0700238void PointerController::doInactivityTimeout() {
Michael Wright6853fe62020-07-02 00:01:38 +0100239 fade(Transition::GRADUAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800240}
241
Liam Harringtonc782be62020-07-17 19:48:24 +0000242void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports) {
243 std::unordered_set<int32_t> displayIdSet;
Prabir Pradhanf97fac32021-11-18 16:40:34 +0000244 for (const DisplayViewport& viewport : viewports) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000245 displayIdSet.insert(viewport.displayId);
Arthur Hungb9b32002018-12-18 17:39:43 +0800246 }
247
Liam Harringtonc782be62020-07-17 19:48:24 +0000248 std::scoped_lock lock(mLock);
249 for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
250 int32_t displayID = it->first;
251 if (!displayIdSet.count(displayID)) {
Liam Harringtonce637132020-08-14 04:00:11 +0000252 /*
253 * Ensures that an in-progress animation won't dereference
254 * a null pointer to TouchSpotController.
255 */
256 mContext.removeAnimationCallback(displayID);
Liam Harringtonc782be62020-07-17 19:48:24 +0000257 it = mLocked.spotControllers.erase(it);
Jun Mukai1db53972015-09-11 18:08:31 -0700258 } else {
Liam Harringtonc782be62020-07-17 19:48:24 +0000259 ++it;
Jeff Brown2352b972011-04-12 22:39:53 -0700260 }
261 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800262}
263
Prabir Pradhanf97fac32021-11-18 16:40:34 +0000264void PointerController::onDisplayInfosChanged(const std::vector<gui::DisplayInfo>& displayInfo) {
265 std::scoped_lock lock(mLock);
266 mLocked.mDisplayInfos = displayInfo;
267}
268
269const ui::Transform& PointerController::getTransformForDisplayLocked(int displayId) const {
270 const auto& di = mLocked.mDisplayInfos;
271 auto it = std::find_if(di.begin(), di.end(), [displayId](const gui::DisplayInfo& info) {
272 return info.displayId == displayId;
273 });
274 return it != di.end() ? it->transform : kIdentityTransform;
275}
276
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800277} // namespace android