PointerController.cpp revision 05dc66ada6b61a6bdf806ffaa62617ac5394695d
1b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown/*
2b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Copyright (C) 2010 The Android Open Source Project
3b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
4b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * you may not use this file except in compliance with the License.
6b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * You may obtain a copy of the License at
7b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
8b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
10b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Unless required by applicable law or agreed to in writing, software
11b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * See the License for the specific language governing permissions and
14b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * limitations under the License.
15b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown */
16b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
17b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#define LOG_TAG "PointerController"
18b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
19b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown//#define LOG_NDEBUG 0
20b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
21b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown// Log debug messages about pointer updates
22b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#define DEBUG_POINTER_UPDATES 0
23b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
24b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include "PointerController.h"
25b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
26b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include <cutils/log.h>
27b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
28b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include <SkBitmap.h>
29b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include <SkCanvas.h>
30b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include <SkColor.h>
31b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include <SkPaint.h>
32b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include <SkXfermode.h>
33b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
34b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownnamespace android {
35b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
36b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown// --- PointerController ---
37b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
3805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown// Time to wait before starting the fade when the pointer is inactive.
3905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownstatic const nsecs_t INACTIVITY_FADE_DELAY_TIME_NORMAL = 15 * 1000 * 1000000LL; // 15 seconds
4005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownstatic const nsecs_t INACTIVITY_FADE_DELAY_TIME_SHORT = 3 * 1000 * 1000000LL; // 3 seconds
4105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
4205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown// Time to spend fading out the pointer completely.
4305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownstatic const nsecs_t FADE_DURATION = 500 * 1000000LL; // 500 ms
4405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
4505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown// Time to wait between frames.
4605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownstatic const nsecs_t FADE_FRAME_INTERVAL = 1000000000LL / 60;
4705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
4805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown// Amount to subtract from alpha per frame.
4905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownstatic const float FADE_DECAY_PER_FRAME = float(FADE_FRAME_INTERVAL) / FADE_DURATION;
5005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
5105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
5205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff BrownPointerController::PointerController(const sp<Looper>& looper, int32_t pointerLayer) :
5305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mLooper(looper), mPointerLayer(pointerLayer) {
54b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
55b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
56b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.displayWidth = -1;
57b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.displayHeight = -1;
58b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.displayOrientation = DISPLAY_ORIENTATION_0;
59b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
60b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.pointerX = 0;
61b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.pointerY = 0;
62b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.buttonState = 0;
63b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
64b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.iconBitmap = NULL;
65b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.iconHotSpotX = 0;
66b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.iconHotSpotY = 0;
67b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
6805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    mLocked.fadeAlpha = 1;
6905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    mLocked.inactivityFadeDelay = INACTIVITY_FADE_DELAY_NORMAL;
7005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
71b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.wantVisible = false;
72b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.visible = false;
73b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.drawn = false;
7405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
7505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    mHandler = new WeakMessageHandler(this);
76b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
77b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
78b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff BrownPointerController::~PointerController() {
7905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    mLooper->removeMessages(mHandler);
8005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
81b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mSurfaceControl != NULL) {
82b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mSurfaceControl->clear();
83b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mSurfaceControl.clear();
84b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
85b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
86b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mSurfaceComposerClient != NULL) {
87b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mSurfaceComposerClient->dispose();
88b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mSurfaceComposerClient.clear();
89b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
90b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
91b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    delete mLocked.iconBitmap;
92b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
93b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
94b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownbool PointerController::getBounds(float* outMinX, float* outMinY,
95b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        float* outMaxX, float* outMaxY) const {
96b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
97b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
98b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    return getBoundsLocked(outMinX, outMinY, outMaxX, outMaxY);
99b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
100b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
101b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownbool PointerController::getBoundsLocked(float* outMinX, float* outMinY,
102b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        float* outMaxX, float* outMaxY) const {
103b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mLocked.displayWidth <= 0 || mLocked.displayHeight <= 0) {
104b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        return false;
105b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
106b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
107b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    *outMinX = 0;
108b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    *outMinY = 0;
109b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    switch (mLocked.displayOrientation) {
110b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    case DISPLAY_ORIENTATION_90:
111b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    case DISPLAY_ORIENTATION_270:
112b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        *outMaxX = mLocked.displayHeight;
113b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        *outMaxY = mLocked.displayWidth;
114b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        break;
115b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    default:
116b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        *outMaxX = mLocked.displayWidth;
117b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        *outMaxY = mLocked.displayHeight;
118b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        break;
119b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
120b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    return true;
121b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
122b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
123b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::move(float deltaX, float deltaY) {
124b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#if DEBUG_POINTER_UPDATES
125b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    LOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
126b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#endif
127b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (deltaX == 0.0f && deltaY == 0.0f) {
128b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        return;
129b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
130b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
131b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
132b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
133b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
134b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
135b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
136b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::setButtonState(uint32_t buttonState) {
137b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#if DEBUG_POINTER_UPDATES
138b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    LOGD("Set button state 0x%08x", buttonState);
139b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#endif
140b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
141b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
142b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mLocked.buttonState != buttonState) {
143b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mLocked.buttonState = buttonState;
14405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        unfadeBeforeUpdateLocked();
145b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        updateLocked();
146b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
147b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
148b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
149b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownuint32_t PointerController::getButtonState() const {
150b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
151b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
152b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    return mLocked.buttonState;
153b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
154b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
155b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::setPosition(float x, float y) {
156b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#if DEBUG_POINTER_UPDATES
157b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    LOGD("Set pointer position to x=%0.3f, y=%0.3f", x, y);
158b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#endif
159b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
160b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
161b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    setPositionLocked(x, y);
162b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
163b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
164b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::setPositionLocked(float x, float y) {
165b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    float minX, minY, maxX, maxY;
166b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
167b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (x <= minX) {
168b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = minX;
169b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        } else if (x >= maxX) {
170b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = maxX;
171b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        } else {
172b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = x;
173b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
174b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (y <= minY) {
175b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = minY;
176b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        } else if (y >= maxY) {
177b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = maxY;
178b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        } else {
179b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = y;
180b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
18105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        unfadeBeforeUpdateLocked();
182b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        updateLocked();
183b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
184b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
185b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
186b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::getPosition(float* outX, float* outY) const {
187b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
188b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
189b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    *outX = mLocked.pointerX;
190b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    *outY = mLocked.pointerY;
191b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
192b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
19305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::fade() {
19405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    AutoMutex _l(mLock);
19505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
19605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    startFadeLocked();
19705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
19805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
19905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::unfade() {
20005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    AutoMutex _l(mLock);
20105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
20205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (unfadeBeforeUpdateLocked()) {
20305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        updateLocked();
20405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
20505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
20605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
20705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::setInactivityFadeDelay(InactivityFadeDelay inactivityFadeDelay) {
20805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    AutoMutex _l(mLock);
20905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
21005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (mLocked.inactivityFadeDelay != inactivityFadeDelay) {
21105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mLocked.inactivityFadeDelay = inactivityFadeDelay;
21205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        startInactivityFadeDelayLocked();
21305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
21405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
21505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
216b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::updateLocked() {
217b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    bool wantVisibleAndHavePointerIcon = mLocked.wantVisible && mLocked.iconBitmap;
218b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
219b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (wantVisibleAndHavePointerIcon) {
220b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        // Want the pointer to be visible.
221b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        // Ensure the surface is created and drawn.
222b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (!createSurfaceIfNeededLocked() || !drawPointerIfNeededLocked()) {
223b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            return;
224b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
225b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    } else {
226b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        // Don't want the pointer to be visible.
227b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        // If it is not visible then we are done.
228b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (mSurfaceControl == NULL || !mLocked.visible) {
229b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            return;
230b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
231b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
232b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
233b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    status_t status = mSurfaceComposerClient->openTransaction();
234b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (status) {
235b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        LOGE("Error opening surface transaction to update pointer surface.");
236b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        return;
237b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
238b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
239b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (wantVisibleAndHavePointerIcon) {
240b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        status = mSurfaceControl->setPosition(
241b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                mLocked.pointerX - mLocked.iconHotSpotX,
242b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                mLocked.pointerY - mLocked.iconHotSpotY);
243b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (status) {
244b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            LOGE("Error %d moving pointer surface.", status);
245b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            goto CloseTransaction;
246b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
247b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
24805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        status = mSurfaceControl->setAlpha(mLocked.fadeAlpha);
24905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        if (status) {
25005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            LOGE("Error %d setting pointer surface alpha.", status);
25105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            goto CloseTransaction;
25205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        }
25305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
254b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (!mLocked.visible) {
255b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            status = mSurfaceControl->setLayer(mPointerLayer);
256b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            if (status) {
257b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                LOGE("Error %d setting pointer surface layer.", status);
258b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                goto CloseTransaction;
259b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            }
260b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
261b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            status = mSurfaceControl->show(mPointerLayer);
262b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            if (status) {
263b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                LOGE("Error %d showing pointer surface.", status);
264b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                goto CloseTransaction;
265b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            }
266b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
267b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.visible = true;
268b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
269b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    } else {
270b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (mLocked.visible) {
271b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            status = mSurfaceControl->hide();
272b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            if (status) {
273b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                LOGE("Error %d hiding pointer surface.", status);
274b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                goto CloseTransaction;
275b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            }
276b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
277b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.visible = false;
278b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
279b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
280b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
281b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff BrownCloseTransaction:
282b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    status = mSurfaceComposerClient->closeTransaction();
283b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (status) {
284b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        LOGE("Error closing surface transaction to update pointer surface.");
285b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
286b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
287b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
288b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::setDisplaySize(int32_t width, int32_t height) {
289b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
290b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
291b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
292b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mLocked.displayWidth = width;
293b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mLocked.displayHeight = height;
294b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
295b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        float minX, minY, maxX, maxY;
296b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
297b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = (minX + maxX) * 0.5f;
298b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = (minY + maxY) * 0.5f;
299b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        } else {
300b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = 0;
301b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = 0;
302b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
303b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
304b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        updateLocked();
305b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
306b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
307b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
308b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::setDisplayOrientation(int32_t orientation) {
309b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
310b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
311b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mLocked.displayOrientation != orientation) {
312b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        float absoluteX, absoluteY;
313b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
314b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        // Map from oriented display coordinates to absolute display coordinates.
315b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        switch (mLocked.displayOrientation) {
316b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_90:
317b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteX = mLocked.displayWidth - mLocked.pointerY;
318b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteY = mLocked.pointerX;
319b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
320b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_180:
321b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteX = mLocked.displayWidth - mLocked.pointerX;
322b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteY = mLocked.displayHeight - mLocked.pointerY;
323b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
324b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_270:
325b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteX = mLocked.pointerY;
326b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteY = mLocked.displayHeight - mLocked.pointerX;
327b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
328b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        default:
329b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteX = mLocked.pointerX;
330b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            absoluteY = mLocked.pointerY;
331b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
332b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
333b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
334b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        // Map from absolute display coordinates to oriented display coordinates.
335b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        switch (orientation) {
336b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_90:
337b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = absoluteY;
338b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = mLocked.displayWidth - absoluteX;
339b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
340b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_180:
341b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = mLocked.displayWidth - absoluteX;
342b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = mLocked.displayHeight - absoluteY;
343b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
344b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        case DISPLAY_ORIENTATION_270:
345b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = mLocked.displayHeight - absoluteY;
346b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = absoluteX;
347b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
348b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        default:
349b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerX = absoluteX;
350b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            mLocked.pointerY = absoluteY;
351b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            break;
352b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
353b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
354b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mLocked.displayOrientation = orientation;
355b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
356b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        updateLocked();
357b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
358b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
359b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
360b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownvoid PointerController::setPointerIcon(const SkBitmap* bitmap, float hotSpotX, float hotSpotY) {
361b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    AutoMutex _l(mLock);
362b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
363f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown    if (mLocked.iconBitmap) {
364f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown        delete mLocked.iconBitmap;
365f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown        mLocked.iconBitmap = NULL;
366f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown    }
367f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown
368f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown    if (bitmap) {
369f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown        mLocked.iconBitmap = new SkBitmap();
370f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown        bitmap->copyTo(mLocked.iconBitmap, SkBitmap::kARGB_8888_Config);
371f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown    }
372f5a2ff6f2e5c5ba9dc7ab16f3b7f8f05daf3c159Jeff Brown
373b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.iconHotSpotX = hotSpotX;
374b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.iconHotSpotY = hotSpotY;
375b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.drawn = false;
376b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
377b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
378b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownbool PointerController::createSurfaceIfNeededLocked() {
379b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (!mLocked.iconBitmap) {
380b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        // If we don't have a pointer icon, then no point allocating a surface now.
381b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        return false;
382b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
383b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
384b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mSurfaceComposerClient == NULL) {
385b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mSurfaceComposerClient = new SurfaceComposerClient();
386b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
387b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
388b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (mSurfaceControl == NULL) {
389b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        mSurfaceControl = mSurfaceComposerClient->createSurface(getpid(),
390b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                String8("Pointer Icon"), 0,
391b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                mLocked.iconBitmap->width(), mLocked.iconBitmap->height(),
392b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown                PIXEL_FORMAT_RGBA_8888);
393b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (mSurfaceControl == NULL) {
394b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            LOGE("Error creating pointer surface.");
395b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            return false;
396b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
397b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
398b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    return true;
399b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
400b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
401b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownbool PointerController::drawPointerIfNeededLocked() {
402b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (!mLocked.drawn) {
403b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (!mLocked.iconBitmap) {
404b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            return false;
405b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
406b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
407b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (!resizeSurfaceLocked(mLocked.iconBitmap->width(), mLocked.iconBitmap->height())) {
408b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            return false;
409b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
410b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
411b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        sp<Surface> surface = mSurfaceControl->getSurface();
412b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
413b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        Surface::SurfaceInfo surfaceInfo;
414b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        status_t status = surface->lock(&surfaceInfo);
415b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (status) {
416b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            LOGE("Error %d locking pointer surface before drawing.", status);
417b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            return false;
418b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
419b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
420b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        SkBitmap surfaceBitmap;
421b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        ssize_t bpr = surfaceInfo.s * bytesPerPixel(surfaceInfo.format);
422b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        surfaceBitmap.setConfig(SkBitmap::kARGB_8888_Config, surfaceInfo.w, surfaceInfo.h, bpr);
423b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        surfaceBitmap.setPixels(surfaceInfo.bits);
424b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
425b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        SkCanvas surfaceCanvas;
426b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        surfaceCanvas.setBitmapDevice(surfaceBitmap);
427b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
428b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        SkPaint paint;
429b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        paint.setXfermodeMode(SkXfermode::kSrc_Mode);
430b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        surfaceCanvas.drawBitmap(*mLocked.iconBitmap, 0, 0, &paint);
431b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
432b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        status = surface->unlockAndPost();
433b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        if (status) {
434b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            LOGE("Error %d unlocking pointer surface after drawing.", status);
435b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown            return false;
436b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        }
437b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
438b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
439b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    mLocked.drawn = true;
440b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    return true;
441b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
442b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
443b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brownbool PointerController::resizeSurfaceLocked(int32_t width, int32_t height) {
444b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    status_t status = mSurfaceComposerClient->openTransaction();
445b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (status) {
446b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        LOGE("Error opening surface transaction to resize pointer surface.");
447b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        return false;
448b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
449b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
450b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    status = mSurfaceControl->setSize(width, height);
451b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (status) {
452b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        LOGE("Error %d setting pointer surface size.", status);
453b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        return false;
454b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
455b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
456b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    status = mSurfaceComposerClient->closeTransaction();
457b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    if (status) {
458b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        LOGE("Error closing surface transaction to resize pointer surface.");
459b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown        return false;
460b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    }
461b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
462b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown    return true;
463b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown}
464b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
46505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::handleMessage(const Message& message) {
46605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    switch (message.what) {
46705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    case MSG_FADE_STEP: {
46805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        AutoMutex _l(mLock);
46905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        fadeStepLocked();
47005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        break;
47105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
47205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
47305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
47405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
47505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownbool PointerController::unfadeBeforeUpdateLocked() {
47605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    sendFadeStepMessageDelayedLocked(getInactivityFadeDelayTimeLocked());
47705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
47805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (isFadingLocked()) {
47905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mLocked.wantVisible = true;
48005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mLocked.fadeAlpha = 1;
48105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        return true; // update required to effect the unfade
48205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
48305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    return false; // update not required
48405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
48505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
48605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::startFadeLocked() {
48705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (!isFadingLocked()) {
48805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        sendFadeStepMessageDelayedLocked(0);
48905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
49005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
49105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
49205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::startInactivityFadeDelayLocked() {
49305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (!isFadingLocked()) {
49405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        sendFadeStepMessageDelayedLocked(getInactivityFadeDelayTimeLocked());
49505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
49605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
49705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
49805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::fadeStepLocked() {
49905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    if (mLocked.wantVisible) {
50005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        mLocked.fadeAlpha -= FADE_DECAY_PER_FRAME;
50105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        if (mLocked.fadeAlpha < 0) {
50205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            mLocked.fadeAlpha = 0;
50305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            mLocked.wantVisible = false;
50405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        } else {
50505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            sendFadeStepMessageDelayedLocked(FADE_FRAME_INTERVAL);
50605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        }
50705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown        updateLocked();
50805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    }
50905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
51005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
51105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownbool PointerController::isFadingLocked() {
51205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    return !mLocked.wantVisible || mLocked.fadeAlpha != 1;
51305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
51405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
51505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownnsecs_t PointerController::getInactivityFadeDelayTimeLocked() {
51605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    return mLocked.inactivityFadeDelay == INACTIVITY_FADE_DELAY_SHORT
51705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown            ? INACTIVITY_FADE_DELAY_TIME_SHORT : INACTIVITY_FADE_DELAY_TIME_NORMAL;
51805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
51905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
52005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid PointerController::sendFadeStepMessageDelayedLocked(nsecs_t delayTime) {
52105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    mLooper->removeMessages(mHandler, MSG_FADE_STEP);
52205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown    mLooper->sendMessageDelayed(delayTime, mHandler, Message(MSG_FADE_STEP));
52305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown}
52405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown
525b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown} // namespace android
526