blob: 6ea303c0163e1a2289aa1eab5841e531fdac95b3 [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
Jeff Brownb4ff35d2011-01-02 16:37:43 -080020#include "PointerController.h"
Liam Harringtonc782be62020-07-17 19:48:24 +000021#include "PointerControllerContext.h"
Jeff Brownb4ff35d2011-01-02 16:37:43 -080022
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 Pradhan3f6626e2021-11-04 16:40:47 -070029namespace {
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 Pradhan3f6626e2021-11-04 16:40:47 -070071 : 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 Pradhan3f6626e2021-11-04 16:40:47 -070076 SurfaceComposerClient::getDefault()->addWindowInfosListener(mDisplayInfoListener);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080077}
78
Liam Harringtonc782be62020-07-17 19:48:24 +000079bool PointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
80 float* outMaxY) const {
81 return mCursorController.getBounds(outMinX, outMinY, outMaxX, outMaxY);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080082}
83
84void PointerController::move(float deltaX, float deltaY) {
Prabir Pradhan3f6626e2021-11-04 16:40:47 -070085 const int32_t displayId = mCursorController.getDisplayId();
86 vec2 transformed;
87 {
88 std::scoped_lock lock(mLock);
89 const auto& transform = getTransformForDisplayLocked(displayId);
90 transformed = transformWithoutTranslation(transform, {deltaX, deltaY});
91 }
92 mCursorController.move(transformed.x, transformed.y);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080093}
94
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070095void PointerController::setButtonState(int32_t buttonState) {
Liam Harringtonc782be62020-07-17 19:48:24 +000096 mCursorController.setButtonState(buttonState);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080097}
98
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070099int32_t PointerController::getButtonState() const {
Liam Harringtonc782be62020-07-17 19:48:24 +0000100 return mCursorController.getButtonState();
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800101}
102
103void PointerController::setPosition(float x, float y) {
Prabir Pradhan3f6626e2021-11-04 16:40:47 -0700104 const int32_t displayId = mCursorController.getDisplayId();
105 vec2 transformed;
106 {
107 std::scoped_lock lock(mLock);
108 const auto& transform = getTransformForDisplayLocked(displayId);
109 transformed = transform.transform(x, y);
110 }
111 mCursorController.setPosition(transformed.x, transformed.y);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800112}
113
114void PointerController::getPosition(float* outX, float* outY) const {
Prabir Pradhan3f6626e2021-11-04 16:40:47 -0700115 const int32_t displayId = mCursorController.getDisplayId();
Liam Harringtonc782be62020-07-17 19:48:24 +0000116 mCursorController.getPosition(outX, outY);
Prabir Pradhan3f6626e2021-11-04 16:40:47 -0700117 {
118 std::scoped_lock lock(mLock);
119 const auto& transform = getTransformForDisplayLocked(displayId);
120 const auto xy = transform.inverse().transform(*outX, *outY);
121 *outX = xy.x;
122 *outY = xy.y;
123 }
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800124}
125
Arthur Hungb9b32002018-12-18 17:39:43 +0800126int32_t PointerController::getDisplayId() const {
Liam Harringtonc782be62020-07-17 19:48:24 +0000127 return mCursorController.getDisplayId();
Arthur Hungb9b32002018-12-18 17:39:43 +0800128}
129
Jeff Brown538881e2011-05-25 18:23:38 -0700130void PointerController::fade(Transition transition) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000131 std::scoped_lock lock(mLock);
132 mCursorController.fade(transition);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800133}
134
Jeff Brown538881e2011-05-25 18:23:38 -0700135void PointerController::unfade(Transition transition) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000136 std::scoped_lock lock(mLock);
137 mCursorController.unfade(transition);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800138}
139
Jeff Brown2352b972011-04-12 22:39:53 -0700140void PointerController::setPresentation(Presentation presentation) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000141 std::scoped_lock lock(mLock);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800142
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800143 if (mLocked.presentation == presentation) {
144 return;
Jun Mukai1db53972015-09-11 18:08:31 -0700145 }
146
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800147 mLocked.presentation = presentation;
Jeff Brown2352b972011-04-12 22:39:53 -0700148
Liam Harringtonc782be62020-07-17 19:48:24 +0000149 if (!mCursorController.isViewportValid()) {
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800150 return;
151 }
152
Michael Wright6853fe62020-07-02 00:01:38 +0100153 if (presentation == Presentation::POINTER) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000154 mCursorController.getAdditionalMouseResources();
155 clearSpotsLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800156 }
157}
158
Liam Harringtonc782be62020-07-17 19:48:24 +0000159void PointerController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
160 BitSet32 spotIdBits, int32_t displayId) {
161 std::scoped_lock lock(mLock);
Prabir Pradhan3f6626e2021-11-04 16:40:47 -0700162 std::array<PointerCoords, MAX_POINTERS> outSpotCoords{};
163 const ui::Transform& transform = getTransformForDisplayLocked(displayId);
164
165 for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) {
166 const uint32_t index = spotIdToIndex[idBits.clearFirstMarkedBit()];
167
168 const vec2 xy = transform.transform(spotCoords[index].getXYValue());
169 outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
170 outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
171
172 float pressure = spotCoords[index].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
173 outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
174 }
175
Liam Harringtonc782be62020-07-17 19:48:24 +0000176 auto it = mLocked.spotControllers.find(displayId);
177 if (it == mLocked.spotControllers.end()) {
178 mLocked.spotControllers.try_emplace(displayId, displayId, mContext);
Jeff Brown2352b972011-04-12 22:39:53 -0700179 }
Prabir Pradhan3f6626e2021-11-04 16:40:47 -0700180 mLocked.spotControllers.at(displayId).setSpots(outSpotCoords.data(), spotIdToIndex, spotIdBits);
Jeff Brown2352b972011-04-12 22:39:53 -0700181}
182
183void PointerController::clearSpots() {
Liam Harringtonc782be62020-07-17 19:48:24 +0000184 std::scoped_lock lock(mLock);
185 clearSpotsLocked();
186}
Jeff Brown2352b972011-04-12 22:39:53 -0700187
Liam Harringtonc782be62020-07-17 19:48:24 +0000188void PointerController::clearSpotsLocked() REQUIRES(mLock) {
189 for (auto& [displayID, spotController] : mLocked.spotControllers) {
190 spotController.clearSpots();
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800191 }
Jeff Brown2352b972011-04-12 22:39:53 -0700192}
193
194void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000195 mContext.setInactivityTimeout(inactivityTimeout);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800196}
197
Jun Mukai19a56012015-11-24 11:25:52 -0800198void PointerController::reloadPointerResources() {
Liam Harringtonc782be62020-07-17 19:48:24 +0000199 std::scoped_lock lock(mLock);
Jun Mukai19a56012015-11-24 11:25:52 -0800200
Liam Harringtonc782be62020-07-17 19:48:24 +0000201 for (auto& [displayID, spotController] : mLocked.spotControllers) {
202 spotController.reloadSpotResources();
203 }
Jun Mukai19a56012015-11-24 11:25:52 -0800204
Liam Harringtonc782be62020-07-17 19:48:24 +0000205 if (mCursorController.resourcesLoaded()) {
206 bool getAdditionalMouseResources = false;
207 if (mLocked.presentation == PointerController::Presentation::POINTER) {
208 getAdditionalMouseResources = true;
209 }
210 mCursorController.reloadPointerResources(getAdditionalMouseResources);
Arthur Hungb9b32002018-12-18 17:39:43 +0800211 }
212}
213
214void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000215 std::scoped_lock lock(mLock);
216
217 bool getAdditionalMouseResources = false;
218 if (mLocked.presentation == PointerController::Presentation::POINTER) {
219 getAdditionalMouseResources = true;
Jeff Brownd728bf52012-09-08 18:05:28 -0700220 }
Liam Harringtonc782be62020-07-17 19:48:24 +0000221 mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800222}
223
Michael Wrighte051f6f2016-05-13 17:44:16 +0100224void PointerController::updatePointerIcon(int32_t iconId) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000225 std::scoped_lock lock(mLock);
226 mCursorController.updatePointerIcon(iconId);
Jun Mukai1db53972015-09-11 18:08:31 -0700227}
228
Jun Mukaid4eaef72015-10-30 15:54:33 -0700229void PointerController::setCustomPointerIcon(const SpriteIcon& icon) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000230 std::scoped_lock lock(mLock);
231 mCursorController.setCustomPointerIcon(icon);
Jun Mukaic0c0ac32015-10-27 10:09:21 -0700232}
233
Jeff Brown2352b972011-04-12 22:39:53 -0700234void PointerController::doInactivityTimeout() {
Michael Wright6853fe62020-07-02 00:01:38 +0100235 fade(Transition::GRADUAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800236}
237
Liam Harringtonc782be62020-07-17 19:48:24 +0000238void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports) {
239 std::unordered_set<int32_t> displayIdSet;
Prabir Pradhan3f6626e2021-11-04 16:40:47 -0700240 for (const DisplayViewport& viewport : viewports) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000241 displayIdSet.insert(viewport.displayId);
Arthur Hungb9b32002018-12-18 17:39:43 +0800242 }
243
Liam Harringtonc782be62020-07-17 19:48:24 +0000244 std::scoped_lock lock(mLock);
245 for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
246 int32_t displayID = it->first;
247 if (!displayIdSet.count(displayID)) {
Liam Harringtonce637132020-08-14 04:00:11 +0000248 /*
249 * Ensures that an in-progress animation won't dereference
250 * a null pointer to TouchSpotController.
251 */
252 mContext.removeAnimationCallback(displayID);
Liam Harringtonc782be62020-07-17 19:48:24 +0000253 it = mLocked.spotControllers.erase(it);
Jun Mukai1db53972015-09-11 18:08:31 -0700254 } else {
Liam Harringtonc782be62020-07-17 19:48:24 +0000255 ++it;
Jeff Brown2352b972011-04-12 22:39:53 -0700256 }
257 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800258}
259
Prabir Pradhan3f6626e2021-11-04 16:40:47 -0700260void PointerController::onDisplayInfosChanged(const std::vector<gui::DisplayInfo>& displayInfo) {
261 std::scoped_lock lock(mLock);
262 mLocked.mDisplayInfos = displayInfo;
263}
264
265const ui::Transform& PointerController::getTransformForDisplayLocked(int displayId) const {
266 const auto& di = mLocked.mDisplayInfos;
267 auto it = std::find_if(di.begin(), di.end(), [displayId](const gui::DisplayInfo& info) {
268 return info.displayId == displayId;
269 });
270 return it != di.end() ? it->transform : kIdentityTransform;
271}
272
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800273} // namespace android