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 "SpriteController.h"
21
22#include <ui/DisplayInfo.h>
23#include <androidfw/Input.h>
24#include <utils/BitSet.h>
25#include <utils/RefBase.h>
26#include <utils/Looper.h>
27#include <utils/String8.h>
28
29#include <SkBitmap.h>
30
31namespace android {
32
33/**
34 * Interface for tracking a mouse / touch pad pointer and touch pad spots.
35 *
36 * The spots are sprites on screen that visually represent the positions of
37 * fingers
38 *
39 * The pointer controller is responsible for providing synchronization and for tracking
40 * display orientation changes if needed.
41 */
42class PointerControllerInterface : public virtual RefBase {
43protected:
44    PointerControllerInterface() { }
45    virtual ~PointerControllerInterface() { }
46
47public:
48    /* Gets the bounds of the region that the pointer can traverse.
49     * Returns true if the bounds are available. */
50    virtual bool getBounds(float* outMinX, float* outMinY,
51            float* outMaxX, float* outMaxY) const = 0;
52
53    /* Move the pointer. */
54    virtual void move(float deltaX, float deltaY) = 0;
55
56    /* Sets a mask that indicates which buttons are pressed. */
57    virtual void setButtonState(int32_t buttonState) = 0;
58
59    /* Gets a mask that indicates which buttons are pressed. */
60    virtual int32_t getButtonState() const = 0;
61
62    /* Sets the absolute location of the pointer. */
63    virtual void setPosition(float x, float y) = 0;
64
65    /* Gets the absolute location of the pointer. */
66    virtual void getPosition(float* outX, float* outY) const = 0;
67
68    enum Transition {
69        // Fade/unfade immediately.
70        TRANSITION_IMMEDIATE,
71        // Fade/unfade gradually.
72        TRANSITION_GRADUAL,
73    };
74
75    /* Fades the pointer out now. */
76    virtual void fade(Transition transition) = 0;
77
78    /* Makes the pointer visible if it has faded out.
79     * The pointer never unfades itself automatically.  This method must be called
80     * by the client whenever the pointer is moved or a button is pressed and it
81     * wants to ensure that the pointer becomes visible again. */
82    virtual void unfade(Transition transition) = 0;
83
84    enum Presentation {
85        // Show the mouse pointer.
86        PRESENTATION_POINTER,
87        // Show spots and a spot anchor in place of the mouse pointer.
88        PRESENTATION_SPOT,
89    };
90
91    /* Sets the mode of the pointer controller. */
92    virtual void setPresentation(Presentation presentation) = 0;
93
94    /* Sets the spots for the current gesture.
95     * The spots are not subject to the inactivity timeout like the pointer
96     * itself it since they are expected to remain visible for so long as
97     * the fingers are on the touch pad.
98     *
99     * The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant.
100     * For spotCoords, pressure != 0 indicates that the spot's location is being
101     * pressed (not hovering).
102     */
103    virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
104            BitSet32 spotIdBits) = 0;
105
106    /* Removes all spots. */
107    virtual void clearSpots() = 0;
108};
109
110
111/*
112 * Pointer resources.
113 */
114struct PointerResources {
115    SpriteIcon spotHover;
116    SpriteIcon spotTouch;
117    SpriteIcon spotAnchor;
118};
119
120
121/*
122 * Pointer controller policy interface.
123 *
124 * The pointer controller policy is used by the pointer controller to interact with
125 * the Window Manager and other system components.
126 *
127 * The actual implementation is partially supported by callbacks into the DVM
128 * via JNI.  This interface is also mocked in the unit tests.
129 */
130class PointerControllerPolicyInterface : public virtual RefBase {
131protected:
132    PointerControllerPolicyInterface() { }
133    virtual ~PointerControllerPolicyInterface() { }
134
135public:
136    virtual void loadPointerResources(PointerResources* outResources) = 0;
137};
138
139
140/*
141 * Tracks pointer movements and draws the pointer sprite to a surface.
142 *
143 * Handles pointer acceleration and animation.
144 */
145class PointerController : public PointerControllerInterface, public MessageHandler {
146protected:
147    virtual ~PointerController();
148
149public:
150    enum InactivityTimeout {
151        INACTIVITY_TIMEOUT_NORMAL = 0,
152        INACTIVITY_TIMEOUT_SHORT = 1,
153    };
154
155    PointerController(const sp<PointerControllerPolicyInterface>& policy,
156            const sp<Looper>& looper, const sp<SpriteController>& spriteController);
157
158    virtual bool getBounds(float* outMinX, float* outMinY,
159            float* outMaxX, float* outMaxY) const;
160    virtual void move(float deltaX, float deltaY);
161    virtual void setButtonState(int32_t buttonState);
162    virtual int32_t getButtonState() const;
163    virtual void setPosition(float x, float y);
164    virtual void getPosition(float* outX, float* outY) const;
165    virtual void fade(Transition transition);
166    virtual void unfade(Transition transition);
167
168    virtual void setPresentation(Presentation presentation);
169    virtual void setSpots(const PointerCoords* spotCoords,
170            const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
171    virtual void clearSpots();
172
173    void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
174    void setPointerIcon(const SpriteIcon& icon);
175    void setInactivityTimeout(InactivityTimeout inactivityTimeout);
176
177private:
178    static const size_t MAX_RECYCLED_SPRITES = 12;
179    static const size_t MAX_SPOTS = 12;
180
181    enum {
182        MSG_ANIMATE,
183        MSG_INACTIVITY_TIMEOUT,
184    };
185
186    struct Spot {
187        static const uint32_t INVALID_ID = 0xffffffff;
188
189        uint32_t id;
190        sp<Sprite> sprite;
191        float alpha;
192        float scale;
193        float x, y;
194
195        inline Spot(uint32_t id, const sp<Sprite>& sprite)
196                : id(id), sprite(sprite), alpha(1.0f), scale(1.0f),
197                  x(0.0f), y(0.0f), lastIcon(NULL) { }
198
199        void updateSprite(const SpriteIcon* icon, float x, float y);
200
201    private:
202        const SpriteIcon* lastIcon;
203    };
204
205    mutable Mutex mLock;
206
207    sp<PointerControllerPolicyInterface> mPolicy;
208    sp<Looper> mLooper;
209    sp<SpriteController> mSpriteController;
210    sp<WeakMessageHandler> mHandler;
211
212    PointerResources mResources;
213
214    struct Locked {
215        bool animationPending;
216        nsecs_t animationTime;
217
218        int32_t displayWidth;
219        int32_t displayHeight;
220        int32_t displayOrientation;
221
222        InactivityTimeout inactivityTimeout;
223
224        Presentation presentation;
225        bool presentationChanged;
226
227        int32_t pointerFadeDirection;
228        float pointerX;
229        float pointerY;
230        float pointerAlpha;
231        sp<Sprite> pointerSprite;
232        SpriteIcon pointerIcon;
233        bool pointerIconChanged;
234
235        int32_t buttonState;
236
237        Vector<Spot*> spots;
238        Vector<sp<Sprite> > recycledSprites;
239    } mLocked;
240
241    bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
242    void setPositionLocked(float x, float y);
243
244    void handleMessage(const Message& message);
245    void doAnimate();
246    void doInactivityTimeout();
247
248    void startAnimationLocked();
249
250    void resetInactivityTimeoutLocked();
251    void removeInactivityTimeoutLocked();
252    void updatePointerLocked();
253
254    Spot* getSpotLocked(uint32_t id);
255    Spot* createAndAddSpotLocked(uint32_t id);
256    Spot* removeFirstFadingSpotLocked();
257    void releaseSpotLocked(Spot* spot);
258    void fadeOutAndReleaseSpotLocked(Spot* spot);
259    void fadeOutAndReleaseAllSpotsLocked();
260
261    void loadResources();
262};
263
264} // namespace android
265
266#endif // _UI_POINTER_CONTROLLER_H
267