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 #ifndef _UI_POINTER_CONTROLLER_H
18 #define _UI_POINTER_CONTROLLER_H
19 
20 #include <PointerControllerInterface.h>
21 #include <gui/DisplayEventReceiver.h>
22 #include <input/DisplayViewport.h>
23 #include <input/Input.h>
24 #include <ui/DisplayInfo.h>
25 #include <utils/BitSet.h>
26 #include <utils/Looper.h>
27 #include <utils/RefBase.h>
28 
29 #include <map>
30 #include <memory>
31 #include <vector>
32 
33 #include "SpriteController.h"
34 
35 namespace android {
36 
37 /*
38  * Pointer resources.
39  */
40 struct PointerResources {
41     SpriteIcon spotHover;
42     SpriteIcon spotTouch;
43     SpriteIcon spotAnchor;
44 };
45 
46 struct PointerAnimation {
47     std::vector<SpriteIcon> animationFrames;
48     nsecs_t durationPerFrame;
49 };
50 
51 /*
52  * Pointer controller policy interface.
53  *
54  * The pointer controller policy is used by the pointer controller to interact with
55  * the Window Manager and other system components.
56  *
57  * The actual implementation is partially supported by callbacks into the DVM
58  * via JNI.  This interface is also mocked in the unit tests.
59  */
60 class PointerControllerPolicyInterface : public virtual RefBase {
61 protected:
PointerControllerPolicyInterface()62     PointerControllerPolicyInterface() { }
~PointerControllerPolicyInterface()63     virtual ~PointerControllerPolicyInterface() { }
64 
65 public:
66     virtual void loadPointerIcon(SpriteIcon* icon, int32_t displayId) = 0;
67     virtual void loadPointerResources(PointerResources* outResources, int32_t displayId) = 0;
68     virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
69             std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) = 0;
70     virtual int32_t getDefaultPointerIconId() = 0;
71     virtual int32_t getCustomPointerIconId() = 0;
72 };
73 
74 /*
75  * Tracks pointer movements and draws the pointer sprite to a surface.
76  *
77  * Handles pointer acceleration and animation.
78  */
79 class PointerController : public PointerControllerInterface {
80 public:
81     static std::shared_ptr<PointerController> create(
82             const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
83             const sp<SpriteController>& spriteController);
84     enum class InactivityTimeout {
85         NORMAL = 0,
86         SHORT = 1,
87     };
88 
89     virtual ~PointerController();
90 
91     virtual bool getBounds(float* outMinX, float* outMinY,
92             float* outMaxX, float* outMaxY) const;
93     virtual void move(float deltaX, float deltaY);
94     virtual void setButtonState(int32_t buttonState);
95     virtual int32_t getButtonState() const;
96     virtual void setPosition(float x, float y);
97     virtual void getPosition(float* outX, float* outY) const;
98     virtual int32_t getDisplayId() const;
99     virtual void fade(Transition transition);
100     virtual void unfade(Transition transition);
101     virtual void setDisplayViewport(const DisplayViewport& viewport);
102 
103     virtual void setPresentation(Presentation presentation);
104     virtual void setSpots(const PointerCoords* spotCoords,
105             const uint32_t* spotIdToIndex, BitSet32 spotIdBits, int32_t displayId);
106     virtual void clearSpots();
107 
108     void updatePointerIcon(int32_t iconId);
109     void setCustomPointerIcon(const SpriteIcon& icon);
110     void setInactivityTimeout(InactivityTimeout inactivityTimeout);
111     void reloadPointerResources();
112 
113 private:
114     static constexpr size_t MAX_RECYCLED_SPRITES = 12;
115     static constexpr size_t MAX_SPOTS = 12;
116 
117     enum {
118         MSG_INACTIVITY_TIMEOUT,
119     };
120 
121     struct Spot {
122         static const uint32_t INVALID_ID = 0xffffffff;
123 
124         uint32_t id;
125         sp<Sprite> sprite;
126         float alpha;
127         float scale;
128         float x, y;
129 
SpotSpot130         inline Spot(uint32_t id, const sp<Sprite>& sprite)
131               : id(id),
132                 sprite(sprite),
133                 alpha(1.0f),
134                 scale(1.0f),
135                 x(0.0f),
136                 y(0.0f),
137                 lastIcon(nullptr) {}
138 
139         void updateSprite(const SpriteIcon* icon, float x, float y, int32_t displayId);
140 
141     private:
142         const SpriteIcon* lastIcon;
143     };
144 
145     class MessageHandler : public virtual android::MessageHandler {
146     public:
147         void handleMessage(const Message& message) override;
148         std::weak_ptr<PointerController> pointerController;
149     };
150 
151     class LooperCallback : public virtual android::LooperCallback {
152     public:
153         int handleEvent(int fd, int events, void* data) override;
154         std::weak_ptr<PointerController> pointerController;
155     };
156 
157     mutable Mutex mLock;
158 
159     sp<PointerControllerPolicyInterface> mPolicy;
160     sp<Looper> mLooper;
161     sp<SpriteController> mSpriteController;
162     sp<MessageHandler> mHandler;
163     sp<LooperCallback> mCallback;
164 
165     DisplayEventReceiver mDisplayEventReceiver;
166 
167     PointerResources mResources;
168 
169     struct Locked {
170         bool animationPending;
171         nsecs_t animationTime;
172 
173         size_t animationFrameIndex;
174         nsecs_t lastFrameUpdatedTime;
175 
176         DisplayViewport viewport;
177 
178         InactivityTimeout inactivityTimeout;
179 
180         Presentation presentation;
181         bool presentationChanged;
182 
183         int32_t pointerFadeDirection;
184         float pointerX;
185         float pointerY;
186         float pointerAlpha;
187         sp<Sprite> pointerSprite;
188         SpriteIcon pointerIcon;
189         bool pointerIconChanged;
190 
191         std::map<int32_t, SpriteIcon> additionalMouseResources;
192         std::map<int32_t, PointerAnimation> animationResources;
193 
194         int32_t requestedPointerType;
195 
196         int32_t buttonState;
197 
198         std::map<int32_t /* displayId */, std::vector<Spot*>> spotsByDisplay;
199         std::vector<sp<Sprite>> recycledSprites;
200     } mLocked GUARDED_BY(mLock);
201 
202     PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
203                       const sp<SpriteController>& spriteController);
204 
205     bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
206     void setPositionLocked(float x, float y);
207 
208     void doAnimate(nsecs_t timestamp);
209     bool doFadingAnimationLocked(nsecs_t timestamp);
210     bool doBitmapAnimationLocked(nsecs_t timestamp);
211     void doInactivityTimeout();
212 
213     void startAnimationLocked();
214 
215     void resetInactivityTimeoutLocked();
216     void removeInactivityTimeoutLocked();
217     void updatePointerLocked();
218 
219     Spot* getSpot(uint32_t id, const std::vector<Spot*>& spots);
220     Spot* createAndAddSpotLocked(uint32_t id, std::vector<Spot*>& spots);
221     Spot* removeFirstFadingSpotLocked(std::vector<Spot*>& spots);
222     void releaseSpotLocked(Spot* spot);
223     void fadeOutAndReleaseSpotLocked(Spot* spot);
224     void fadeOutAndReleaseAllSpotsLocked();
225 
226     void loadResourcesLocked();
227 };
228 
229 } // namespace android
230 
231 #endif // _UI_POINTER_CONTROLLER_H
232