blob: 8f04cfb70469777b09c68b6efbba6207c0e76123 [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
20// Log debug messages about pointer updates
21#define DEBUG_POINTER_UPDATES 0
22
23#include "PointerController.h"
Liam Harringtonc782be62020-07-17 19:48:24 +000024#include "MouseCursorController.h"
25#include "PointerControllerContext.h"
26#include "TouchSpotController.h"
Jeff Brownb4ff35d2011-01-02 16:37:43 -080027
Mark Salyzyn52eb4e02016-09-28 16:15:30 -070028#include <log/log.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080029
Liam Harringtonc782be62020-07-17 19:48:24 +000030#include <SkBitmap.h>
31#include <SkBlendMode.h>
32#include <SkCanvas.h>
33#include <SkColor.h>
34#include <SkPaint.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080035
36namespace android {
37
38// --- PointerController ---
39
Michael Wrighta0bc6b12020-06-26 20:25:34 +010040std::shared_ptr<PointerController> PointerController::create(
41 const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
42 const sp<SpriteController>& spriteController) {
Liam Harringtonc782be62020-07-17 19:48:24 +000043 // using 'new' to access non-public constructor
Michael Wrighta0bc6b12020-06-26 20:25:34 +010044 std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>(
45 new PointerController(policy, looper, spriteController));
Jeff Brown2352b972011-04-12 22:39:53 -070046
Michael Wrighta0bc6b12020-06-26 20:25:34 +010047 /*
48 * Now we need to hook up the constructed PointerController object to its callbacks.
49 *
50 * This must be executed after the constructor but before any other methods on PointerController
51 * in order to ensure that the fully constructed object is visible on the Looper thread, since
52 * that may be a different thread than where the PointerController is initially constructed.
53 *
54 * Unfortunately, this cannot be done as part of the constructor since we need to hand out
55 * weak_ptr's which themselves cannot be constructed until there's at least one shared_ptr.
56 */
Jeff Brown5541de92011-04-11 11:54:25 -070057
Liam Harringtonc782be62020-07-17 19:48:24 +000058 controller->mContext.setHandlerController(controller);
59 controller->mContext.setCallbackController(controller);
Michael Wrighta0bc6b12020-06-26 20:25:34 +010060 return controller;
61}
Jun Mukaic0c0ac32015-10-27 10:09:21 -070062
Michael Wrighta0bc6b12020-06-26 20:25:34 +010063PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
64 const sp<Looper>& looper,
65 const sp<SpriteController>& spriteController)
Liam Harringtonc782be62020-07-17 19:48:24 +000066 : mContext(policy, looper, spriteController, *this), mCursorController(mContext) {
67 std::scoped_lock lock(mLock);
68 mLocked.presentation = Presentation::SPOT;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080069}
70
Liam Harringtonc782be62020-07-17 19:48:24 +000071bool PointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
72 float* outMaxY) const {
73 return mCursorController.getBounds(outMinX, outMinY, outMaxX, outMaxY);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080074}
75
76void PointerController::move(float deltaX, float deltaY) {
Liam Harringtonc782be62020-07-17 19:48:24 +000077 mCursorController.move(deltaX, deltaY);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080078}
79
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070080void PointerController::setButtonState(int32_t buttonState) {
Liam Harringtonc782be62020-07-17 19:48:24 +000081 mCursorController.setButtonState(buttonState);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080082}
83
Jeff Brownfe9f8ab2011-05-06 18:20:01 -070084int32_t PointerController::getButtonState() const {
Liam Harringtonc782be62020-07-17 19:48:24 +000085 return mCursorController.getButtonState();
Jeff Brownb4ff35d2011-01-02 16:37:43 -080086}
87
88void PointerController::setPosition(float x, float y) {
Liam Harringtonc782be62020-07-17 19:48:24 +000089 std::scoped_lock lock(mLock);
90 mCursorController.setPosition(x, y);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080091}
92
93void PointerController::getPosition(float* outX, float* outY) const {
Liam Harringtonc782be62020-07-17 19:48:24 +000094 mCursorController.getPosition(outX, outY);
Jeff Brownb4ff35d2011-01-02 16:37:43 -080095}
96
Arthur Hungb9b32002018-12-18 17:39:43 +080097int32_t PointerController::getDisplayId() const {
Liam Harringtonc782be62020-07-17 19:48:24 +000098 return mCursorController.getDisplayId();
Arthur Hungb9b32002018-12-18 17:39:43 +080099}
100
Jeff Brown538881e2011-05-25 18:23:38 -0700101void PointerController::fade(Transition transition) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000102 std::scoped_lock lock(mLock);
103 mCursorController.fade(transition);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800104}
105
Jeff Brown538881e2011-05-25 18:23:38 -0700106void PointerController::unfade(Transition transition) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000107 std::scoped_lock lock(mLock);
108 mCursorController.unfade(transition);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800109}
110
Jeff Brown2352b972011-04-12 22:39:53 -0700111void PointerController::setPresentation(Presentation presentation) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000112 std::scoped_lock lock(mLock);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800113
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800114 if (mLocked.presentation == presentation) {
115 return;
Jun Mukai1db53972015-09-11 18:08:31 -0700116 }
117
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800118 mLocked.presentation = presentation;
Jeff Brown2352b972011-04-12 22:39:53 -0700119
Liam Harringtonc782be62020-07-17 19:48:24 +0000120 if (!mCursorController.isViewportValid()) {
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800121 return;
122 }
123
Michael Wright6853fe62020-07-02 00:01:38 +0100124 if (presentation == Presentation::POINTER) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000125 mCursorController.getAdditionalMouseResources();
126 clearSpotsLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800127 }
128}
129
Liam Harringtonc782be62020-07-17 19:48:24 +0000130void PointerController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
131 BitSet32 spotIdBits, int32_t displayId) {
132 std::scoped_lock lock(mLock);
133 auto it = mLocked.spotControllers.find(displayId);
134 if (it == mLocked.spotControllers.end()) {
135 mLocked.spotControllers.try_emplace(displayId, displayId, mContext);
Jeff Brown2352b972011-04-12 22:39:53 -0700136 }
Liam Harringtonc782be62020-07-17 19:48:24 +0000137 mLocked.spotControllers.at(displayId).setSpots(spotCoords, spotIdToIndex, spotIdBits);
Jeff Brown2352b972011-04-12 22:39:53 -0700138}
139
140void PointerController::clearSpots() {
Liam Harringtonc782be62020-07-17 19:48:24 +0000141 std::scoped_lock lock(mLock);
142 clearSpotsLocked();
143}
Jeff Brown2352b972011-04-12 22:39:53 -0700144
Liam Harringtonc782be62020-07-17 19:48:24 +0000145void PointerController::clearSpotsLocked() REQUIRES(mLock) {
146 for (auto& [displayID, spotController] : mLocked.spotControllers) {
147 spotController.clearSpots();
Prabir Pradhanca7d7232020-01-31 17:42:34 -0800148 }
Jeff Brown2352b972011-04-12 22:39:53 -0700149}
150
151void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000152 mContext.setInactivityTimeout(inactivityTimeout);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800153}
154
Jun Mukai19a56012015-11-24 11:25:52 -0800155void PointerController::reloadPointerResources() {
Liam Harringtonc782be62020-07-17 19:48:24 +0000156 std::scoped_lock lock(mLock);
Jun Mukai19a56012015-11-24 11:25:52 -0800157
Liam Harringtonc782be62020-07-17 19:48:24 +0000158 for (auto& [displayID, spotController] : mLocked.spotControllers) {
159 spotController.reloadSpotResources();
160 }
Jun Mukai19a56012015-11-24 11:25:52 -0800161
Liam Harringtonc782be62020-07-17 19:48:24 +0000162 if (mCursorController.resourcesLoaded()) {
163 bool getAdditionalMouseResources = false;
164 if (mLocked.presentation == PointerController::Presentation::POINTER) {
165 getAdditionalMouseResources = true;
166 }
167 mCursorController.reloadPointerResources(getAdditionalMouseResources);
Arthur Hungb9b32002018-12-18 17:39:43 +0800168 }
169}
170
171void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000172 std::scoped_lock lock(mLock);
173
174 bool getAdditionalMouseResources = false;
175 if (mLocked.presentation == PointerController::Presentation::POINTER) {
176 getAdditionalMouseResources = true;
Jeff Brownd728bf52012-09-08 18:05:28 -0700177 }
Liam Harringtonc782be62020-07-17 19:48:24 +0000178 mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800179}
180
Michael Wrighte051f6f2016-05-13 17:44:16 +0100181void PointerController::updatePointerIcon(int32_t iconId) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000182 std::scoped_lock lock(mLock);
183 mCursorController.updatePointerIcon(iconId);
Jun Mukai1db53972015-09-11 18:08:31 -0700184}
185
Jun Mukaid4eaef72015-10-30 15:54:33 -0700186void PointerController::setCustomPointerIcon(const SpriteIcon& icon) {
Liam Harringtonc782be62020-07-17 19:48:24 +0000187 std::scoped_lock lock(mLock);
188 mCursorController.setCustomPointerIcon(icon);
Jun Mukaic0c0ac32015-10-27 10:09:21 -0700189}
190
Jeff Brown2352b972011-04-12 22:39:53 -0700191void PointerController::doInactivityTimeout() {
Michael Wright6853fe62020-07-02 00:01:38 +0100192 fade(Transition::GRADUAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800193}
194
Liam Harringtonc782be62020-07-17 19:48:24 +0000195void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports) {
196 std::unordered_set<int32_t> displayIdSet;
197 for (DisplayViewport viewport : viewports) {
198 displayIdSet.insert(viewport.displayId);
Arthur Hungb9b32002018-12-18 17:39:43 +0800199 }
200
Liam Harringtonc782be62020-07-17 19:48:24 +0000201 std::scoped_lock lock(mLock);
202 for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
203 int32_t displayID = it->first;
204 if (!displayIdSet.count(displayID)) {
Liam Harringtonce637132020-08-14 04:00:11 +0000205 /*
206 * Ensures that an in-progress animation won't dereference
207 * a null pointer to TouchSpotController.
208 */
209 mContext.removeAnimationCallback(displayID);
Liam Harringtonc782be62020-07-17 19:48:24 +0000210 it = mLocked.spotControllers.erase(it);
Jun Mukai1db53972015-09-11 18:08:31 -0700211 } else {
Liam Harringtonc782be62020-07-17 19:48:24 +0000212 ++it;
Jeff Brown2352b972011-04-12 22:39:53 -0700213 }
214 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800215}
216
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800217} // namespace android