• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
18 //#define LOG_NDEBUG 0
19 
20 // Log debug messages about pointer updates
21 #define DEBUG_POINTER_UPDATES 0
22 
23 #include "PointerController.h"
24 #include "MouseCursorController.h"
25 #include "PointerControllerContext.h"
26 #include "TouchSpotController.h"
27 
28 #include <log/log.h>
29 
30 #include <SkBitmap.h>
31 #include <SkBlendMode.h>
32 #include <SkCanvas.h>
33 #include <SkColor.h>
34 #include <SkPaint.h>
35 
36 namespace android {
37 
38 // --- PointerController ---
39 
create(const sp<PointerControllerPolicyInterface> & policy,const sp<Looper> & looper,const sp<SpriteController> & spriteController)40 std::shared_ptr<PointerController> PointerController::create(
41         const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
42         const sp<SpriteController>& spriteController) {
43     // using 'new' to access non-public constructor
44     std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>(
45             new PointerController(policy, looper, spriteController));
46 
47     /*
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      */
57 
58     controller->mContext.setHandlerController(controller);
59     controller->mContext.setCallbackController(controller);
60     return controller;
61 }
62 
PointerController(const sp<PointerControllerPolicyInterface> & policy,const sp<Looper> & looper,const sp<SpriteController> & spriteController)63 PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy,
64                                      const sp<Looper>& looper,
65                                      const sp<SpriteController>& spriteController)
66       : mContext(policy, looper, spriteController, *this), mCursorController(mContext) {
67     std::scoped_lock lock(mLock);
68     mLocked.presentation = Presentation::SPOT;
69 }
70 
getBounds(float * outMinX,float * outMinY,float * outMaxX,float * outMaxY) const71 bool PointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX,
72                                   float* outMaxY) const {
73     return mCursorController.getBounds(outMinX, outMinY, outMaxX, outMaxY);
74 }
75 
move(float deltaX,float deltaY)76 void PointerController::move(float deltaX, float deltaY) {
77     mCursorController.move(deltaX, deltaY);
78 }
79 
setButtonState(int32_t buttonState)80 void PointerController::setButtonState(int32_t buttonState) {
81     mCursorController.setButtonState(buttonState);
82 }
83 
getButtonState() const84 int32_t PointerController::getButtonState() const {
85     return mCursorController.getButtonState();
86 }
87 
setPosition(float x,float y)88 void PointerController::setPosition(float x, float y) {
89     std::scoped_lock lock(mLock);
90     mCursorController.setPosition(x, y);
91 }
92 
getPosition(float * outX,float * outY) const93 void PointerController::getPosition(float* outX, float* outY) const {
94     mCursorController.getPosition(outX, outY);
95 }
96 
getDisplayId() const97 int32_t PointerController::getDisplayId() const {
98     return mCursorController.getDisplayId();
99 }
100 
fade(Transition transition)101 void PointerController::fade(Transition transition) {
102     std::scoped_lock lock(mLock);
103     mCursorController.fade(transition);
104 }
105 
unfade(Transition transition)106 void PointerController::unfade(Transition transition) {
107     std::scoped_lock lock(mLock);
108     mCursorController.unfade(transition);
109 }
110 
setPresentation(Presentation presentation)111 void PointerController::setPresentation(Presentation presentation) {
112     std::scoped_lock lock(mLock);
113 
114     if (mLocked.presentation == presentation) {
115         return;
116     }
117 
118     mLocked.presentation = presentation;
119 
120     if (!mCursorController.isViewportValid()) {
121         return;
122     }
123 
124     if (presentation == Presentation::POINTER) {
125         mCursorController.getAdditionalMouseResources();
126         clearSpotsLocked();
127     }
128 }
129 
setSpots(const PointerCoords * spotCoords,const uint32_t * spotIdToIndex,BitSet32 spotIdBits,int32_t displayId)130 void 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);
136     }
137     mLocked.spotControllers.at(displayId).setSpots(spotCoords, spotIdToIndex, spotIdBits);
138 }
139 
clearSpots()140 void PointerController::clearSpots() {
141     std::scoped_lock lock(mLock);
142     clearSpotsLocked();
143 }
144 
clearSpotsLocked()145 void PointerController::clearSpotsLocked() REQUIRES(mLock) {
146     for (auto& [displayID, spotController] : mLocked.spotControllers) {
147         spotController.clearSpots();
148     }
149 }
150 
setInactivityTimeout(InactivityTimeout inactivityTimeout)151 void PointerController::setInactivityTimeout(InactivityTimeout inactivityTimeout) {
152     mContext.setInactivityTimeout(inactivityTimeout);
153 }
154 
reloadPointerResources()155 void PointerController::reloadPointerResources() {
156     std::scoped_lock lock(mLock);
157 
158     for (auto& [displayID, spotController] : mLocked.spotControllers) {
159         spotController.reloadSpotResources();
160     }
161 
162     if (mCursorController.resourcesLoaded()) {
163         bool getAdditionalMouseResources = false;
164         if (mLocked.presentation == PointerController::Presentation::POINTER) {
165             getAdditionalMouseResources = true;
166         }
167         mCursorController.reloadPointerResources(getAdditionalMouseResources);
168     }
169 }
170 
setDisplayViewport(const DisplayViewport & viewport)171 void PointerController::setDisplayViewport(const DisplayViewport& viewport) {
172     std::scoped_lock lock(mLock);
173 
174     bool getAdditionalMouseResources = false;
175     if (mLocked.presentation == PointerController::Presentation::POINTER) {
176         getAdditionalMouseResources = true;
177     }
178     mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources);
179 }
180 
updatePointerIcon(int32_t iconId)181 void PointerController::updatePointerIcon(int32_t iconId) {
182     std::scoped_lock lock(mLock);
183     mCursorController.updatePointerIcon(iconId);
184 }
185 
setCustomPointerIcon(const SpriteIcon & icon)186 void PointerController::setCustomPointerIcon(const SpriteIcon& icon) {
187     std::scoped_lock lock(mLock);
188     mCursorController.setCustomPointerIcon(icon);
189 }
190 
doInactivityTimeout()191 void PointerController::doInactivityTimeout() {
192     fade(Transition::GRADUAL);
193 }
194 
onDisplayViewportsUpdated(std::vector<DisplayViewport> & viewports)195 void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports) {
196     std::unordered_set<int32_t> displayIdSet;
197     for (DisplayViewport viewport : viewports) {
198         displayIdSet.insert(viewport.displayId);
199     }
200 
201     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)) {
205             /*
206              * Ensures that an in-progress animation won't dereference
207              * a null pointer to TouchSpotController.
208              */
209             mContext.removeAnimationCallback(displayID);
210             it = mLocked.spotControllers.erase(it);
211         } else {
212             ++it;
213         }
214     }
215 }
216 
217 } // namespace android
218