Merge "Switch to callback animation" am: 51060f3f7a am: 5267d92272
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1399752 Change-Id: I3e4d82a9a2f9e9f4f1232a2de21a55cc19a2168a
This commit is contained in:
@@ -168,7 +168,7 @@ void MouseCursorController::fade(PointerControllerInterface::Transition transiti
|
|||||||
updatePointerLocked();
|
updatePointerLocked();
|
||||||
} else {
|
} else {
|
||||||
mLocked.pointerFadeDirection = -1;
|
mLocked.pointerFadeDirection = -1;
|
||||||
mContext.startAnimation();
|
startAnimationLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ void MouseCursorController::unfade(PointerControllerInterface::Transition transi
|
|||||||
updatePointerLocked();
|
updatePointerLocked();
|
||||||
} else {
|
} else {
|
||||||
mLocked.pointerFadeDirection = 1;
|
mLocked.pointerFadeDirection = 1;
|
||||||
mContext.startAnimation();
|
startAnimationLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,10 +312,9 @@ void MouseCursorController::setCustomPointerIcon(const SpriteIcon& icon) {
|
|||||||
updatePointerLocked();
|
updatePointerLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MouseCursorController::doFadingAnimation(nsecs_t timestamp, bool keepAnimating) {
|
bool MouseCursorController::doFadingAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
|
||||||
nsecs_t frameDelay = timestamp - mContext.getAnimationTime();
|
nsecs_t frameDelay = timestamp - mContext.getAnimationTime();
|
||||||
|
bool keepAnimating = false;
|
||||||
std::scoped_lock lock(mLock);
|
|
||||||
|
|
||||||
// Animate pointer fade.
|
// Animate pointer fade.
|
||||||
if (mLocked.pointerFadeDirection < 0) {
|
if (mLocked.pointerFadeDirection < 0) {
|
||||||
@@ -337,13 +336,10 @@ bool MouseCursorController::doFadingAnimation(nsecs_t timestamp, bool keepAnimat
|
|||||||
}
|
}
|
||||||
updatePointerLocked();
|
updatePointerLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
return keepAnimating;
|
return keepAnimating;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MouseCursorController::doBitmapAnimation(nsecs_t timestamp) {
|
bool MouseCursorController::doBitmapAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
|
||||||
std::scoped_lock lock(mLock);
|
|
||||||
|
|
||||||
std::map<int32_t, PointerAnimation>::const_iterator iter =
|
std::map<int32_t, PointerAnimation>::const_iterator iter =
|
||||||
mLocked.animationResources.find(mLocked.requestedPointerType);
|
mLocked.animationResources.find(mLocked.requestedPointerType);
|
||||||
if (iter == mLocked.animationResources.end()) {
|
if (iter == mLocked.animationResources.end()) {
|
||||||
@@ -364,7 +360,6 @@ bool MouseCursorController::doBitmapAnimation(nsecs_t timestamp) {
|
|||||||
|
|
||||||
spriteController->closeTransaction();
|
spriteController->closeTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep animating.
|
// Keep animating.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -399,7 +394,7 @@ void MouseCursorController::updatePointerLocked() REQUIRES(mLock) {
|
|||||||
if (anim_iter != mLocked.animationResources.end()) {
|
if (anim_iter != mLocked.animationResources.end()) {
|
||||||
mLocked.animationFrameIndex = 0;
|
mLocked.animationFrameIndex = 0;
|
||||||
mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
|
mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||||
mContext.startAnimation();
|
startAnimationLocked();
|
||||||
}
|
}
|
||||||
mLocked.pointerSprite->setIcon(iter->second);
|
mLocked.pointerSprite->setIcon(iter->second);
|
||||||
} else {
|
} else {
|
||||||
@@ -457,4 +452,38 @@ bool MouseCursorController::resourcesLoaded() {
|
|||||||
return mLocked.resourcesLoaded;
|
return mLocked.resourcesLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MouseCursorController::doAnimations(nsecs_t timestamp) {
|
||||||
|
std::scoped_lock lock(mLock);
|
||||||
|
bool keepFading = doFadingAnimationLocked(timestamp);
|
||||||
|
bool keepBitmap = doBitmapAnimationLocked(timestamp);
|
||||||
|
bool keepAnimating = keepFading || keepBitmap;
|
||||||
|
if (!keepAnimating) {
|
||||||
|
/*
|
||||||
|
* We know that this callback will be removed before another
|
||||||
|
* is added. mLock in PointerAnimator will not be released
|
||||||
|
* until after this is removed, and adding another callback
|
||||||
|
* requires that lock. Thus it's safe to set mLocked.animating
|
||||||
|
* here.
|
||||||
|
*/
|
||||||
|
mLocked.animating = false;
|
||||||
|
}
|
||||||
|
return keepAnimating;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseCursorController::startAnimationLocked() REQUIRES(mLock) {
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
if (mLocked.animating) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mLocked.animating = true;
|
||||||
|
|
||||||
|
std::function<bool(nsecs_t)> func = std::bind(&MouseCursorController::doAnimations, this, _1);
|
||||||
|
/*
|
||||||
|
* Using -1 for displayId here to avoid removing the callback
|
||||||
|
* if a TouchSpotController with the same display is removed.
|
||||||
|
*/
|
||||||
|
mContext.addAnimationCallback(-1, func);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <utils/Looper.h>
|
#include <utils/Looper.h>
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -61,8 +62,7 @@ public:
|
|||||||
void getAdditionalMouseResources();
|
void getAdditionalMouseResources();
|
||||||
bool isViewportValid();
|
bool isViewportValid();
|
||||||
|
|
||||||
bool doBitmapAnimation(nsecs_t timestamp);
|
bool doAnimations(nsecs_t timestamp);
|
||||||
bool doFadingAnimation(nsecs_t timestamp, bool keepAnimating);
|
|
||||||
|
|
||||||
bool resourcesLoaded();
|
bool resourcesLoaded();
|
||||||
|
|
||||||
@@ -96,6 +96,8 @@ private:
|
|||||||
|
|
||||||
int32_t buttonState;
|
int32_t buttonState;
|
||||||
|
|
||||||
|
bool animating{false};
|
||||||
|
|
||||||
} mLocked GUARDED_BY(mLock);
|
} mLocked GUARDED_BY(mLock);
|
||||||
|
|
||||||
bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
|
bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
|
||||||
@@ -104,6 +106,11 @@ private:
|
|||||||
void updatePointerLocked();
|
void updatePointerLocked();
|
||||||
|
|
||||||
void loadResourcesLocked(bool getAdditionalMouseResources);
|
void loadResourcesLocked(bool getAdditionalMouseResources);
|
||||||
|
|
||||||
|
bool doBitmapAnimationLocked(nsecs_t timestamp);
|
||||||
|
bool doFadingAnimationLocked(nsecs_t timestamp);
|
||||||
|
|
||||||
|
void startAnimationLocked();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ std::shared_ptr<PointerController> PointerController::create(
|
|||||||
|
|
||||||
controller->mContext.setHandlerController(controller);
|
controller->mContext.setHandlerController(controller);
|
||||||
controller->mContext.setCallbackController(controller);
|
controller->mContext.setCallbackController(controller);
|
||||||
controller->mContext.initializeDisplayEventReceiver();
|
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,24 +188,6 @@ void PointerController::setCustomPointerIcon(const SpriteIcon& icon) {
|
|||||||
mCursorController.setCustomPointerIcon(icon);
|
mCursorController.setCustomPointerIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerController::doAnimate(nsecs_t timestamp) {
|
|
||||||
std::scoped_lock lock(mLock);
|
|
||||||
|
|
||||||
mContext.setAnimationPending(false);
|
|
||||||
|
|
||||||
bool keepFading = false;
|
|
||||||
keepFading = mCursorController.doFadingAnimation(timestamp, keepFading);
|
|
||||||
|
|
||||||
for (auto& [displayID, spotController] : mLocked.spotControllers) {
|
|
||||||
keepFading = spotController.doFadingAnimation(timestamp, keepFading);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool keepBitmapFlipping = mCursorController.doBitmapAnimation(timestamp);
|
|
||||||
if (keepFading || keepBitmapFlipping) {
|
|
||||||
mContext.startAnimation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PointerController::doInactivityTimeout() {
|
void PointerController::doInactivityTimeout() {
|
||||||
fade(Transition::GRADUAL);
|
fade(Transition::GRADUAL);
|
||||||
}
|
}
|
||||||
@@ -221,6 +202,11 @@ void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>&
|
|||||||
for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
|
for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
|
||||||
int32_t displayID = it->first;
|
int32_t displayID = it->first;
|
||||||
if (!displayIdSet.count(displayID)) {
|
if (!displayIdSet.count(displayID)) {
|
||||||
|
/*
|
||||||
|
* Ensures that an in-progress animation won't dereference
|
||||||
|
* a null pointer to TouchSpotController.
|
||||||
|
*/
|
||||||
|
mContext.removeAnimationCallback(displayID);
|
||||||
it = mLocked.spotControllers.erase(it);
|
it = mLocked.spotControllers.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ public:
|
|||||||
void setCustomPointerIcon(const SpriteIcon& icon);
|
void setCustomPointerIcon(const SpriteIcon& icon);
|
||||||
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
|
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
|
||||||
void doInactivityTimeout();
|
void doInactivityTimeout();
|
||||||
void doAnimate(nsecs_t timestamp);
|
|
||||||
void reloadPointerResources();
|
void reloadPointerResources();
|
||||||
void onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports);
|
void onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports);
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ PointerControllerContext::PointerControllerContext(
|
|||||||
mSpriteController(spriteController),
|
mSpriteController(spriteController),
|
||||||
mHandler(new MessageHandler()),
|
mHandler(new MessageHandler()),
|
||||||
mCallback(new LooperCallback()),
|
mCallback(new LooperCallback()),
|
||||||
mController(controller) {
|
mController(controller),
|
||||||
|
mAnimator(*this) {
|
||||||
std::scoped_lock lock(mLock);
|
std::scoped_lock lock(mLock);
|
||||||
mLocked.inactivityTimeout = InactivityTimeout::NORMAL;
|
mLocked.inactivityTimeout = InactivityTimeout::NORMAL;
|
||||||
mLocked.animationPending = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerControllerContext::~PointerControllerContext() {
|
PointerControllerContext::~PointerControllerContext() {
|
||||||
@@ -57,15 +57,6 @@ void PointerControllerContext::setInactivityTimeout(InactivityTimeout inactivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerControllerContext::startAnimation() {
|
|
||||||
std::scoped_lock lock(mLock);
|
|
||||||
if (!mLocked.animationPending) {
|
|
||||||
mLocked.animationPending = true;
|
|
||||||
mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
|
|
||||||
mDisplayEventReceiver.requestNextVsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PointerControllerContext::resetInactivityTimeout() {
|
void PointerControllerContext::resetInactivityTimeout() {
|
||||||
std::scoped_lock lock(mLock);
|
std::scoped_lock lock(mLock);
|
||||||
resetInactivityTimeoutLocked();
|
resetInactivityTimeoutLocked();
|
||||||
@@ -85,14 +76,8 @@ void PointerControllerContext::removeInactivityTimeout() {
|
|||||||
mLooper->removeMessages(mHandler, MessageHandler::MSG_INACTIVITY_TIMEOUT);
|
mLooper->removeMessages(mHandler, MessageHandler::MSG_INACTIVITY_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerControllerContext::setAnimationPending(bool animationPending) {
|
nsecs_t PointerControllerContext::getAnimationTime() REQUIRES(mAnimator.mLock) {
|
||||||
std::scoped_lock lock(mLock);
|
return mAnimator.getAnimationTimeLocked();
|
||||||
mLocked.animationPending = animationPending;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsecs_t PointerControllerContext::getAnimationTime() {
|
|
||||||
std::scoped_lock lock(mLock);
|
|
||||||
return mLocked.animationTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerControllerContext::setHandlerController(std::shared_ptr<PointerController> controller) {
|
void PointerControllerContext::setHandlerController(std::shared_ptr<PointerController> controller) {
|
||||||
@@ -112,31 +97,8 @@ sp<SpriteController> PointerControllerContext::getSpriteController() {
|
|||||||
return mSpriteController;
|
return mSpriteController;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerControllerContext::initializeDisplayEventReceiver() {
|
|
||||||
if (mDisplayEventReceiver.initCheck() == NO_ERROR) {
|
|
||||||
mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK, Looper::EVENT_INPUT,
|
|
||||||
mCallback, nullptr);
|
|
||||||
} else {
|
|
||||||
ALOGE("Failed to initialize DisplayEventReceiver.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PointerControllerContext::handleDisplayEvents() {
|
void PointerControllerContext::handleDisplayEvents() {
|
||||||
bool gotVsync = false;
|
mAnimator.handleVsyncEvents();
|
||||||
ssize_t n;
|
|
||||||
nsecs_t timestamp;
|
|
||||||
DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
|
|
||||||
while ((n = mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
|
|
||||||
for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
|
|
||||||
if (buf[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
|
|
||||||
timestamp = buf[i].header.timestamp;
|
|
||||||
gotVsync = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gotVsync) {
|
|
||||||
mController.doAnimate(timestamp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerControllerContext::MessageHandler::handleMessage(const Message& message) {
|
void PointerControllerContext::MessageHandler::handleMessage(const Message& message) {
|
||||||
@@ -176,4 +138,91 @@ int PointerControllerContext::LooperCallback::handleEvent(int /* fd */, int even
|
|||||||
return 1; // keep the callback
|
return 1; // keep the callback
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::addAnimationCallback(int32_t displayId,
|
||||||
|
std::function<bool(nsecs_t)> callback) {
|
||||||
|
mAnimator.addCallback(displayId, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::removeAnimationCallback(int32_t displayId) {
|
||||||
|
mAnimator.removeCallback(displayId);
|
||||||
|
}
|
||||||
|
|
||||||
|
PointerControllerContext::PointerAnimator::PointerAnimator(PointerControllerContext& context)
|
||||||
|
: mContext(context) {
|
||||||
|
initializeDisplayEventReceiver();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::PointerAnimator::initializeDisplayEventReceiver() {
|
||||||
|
if (mDisplayEventReceiver.initCheck() == NO_ERROR) {
|
||||||
|
mContext.mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK,
|
||||||
|
Looper::EVENT_INPUT, mContext.mCallback, nullptr);
|
||||||
|
} else {
|
||||||
|
ALOGE("Failed to initialize DisplayEventReceiver.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::PointerAnimator::addCallback(int32_t displayId,
|
||||||
|
std::function<bool(nsecs_t)> callback) {
|
||||||
|
std::scoped_lock lock(mLock);
|
||||||
|
mLocked.callbacks[displayId] = callback;
|
||||||
|
startAnimationLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::PointerAnimator::removeCallback(int32_t displayId) {
|
||||||
|
std::scoped_lock lock(mLock);
|
||||||
|
auto it = mLocked.callbacks.find(displayId);
|
||||||
|
if (it == mLocked.callbacks.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mLocked.callbacks.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::PointerAnimator::handleVsyncEvents() {
|
||||||
|
bool gotVsync = false;
|
||||||
|
ssize_t n;
|
||||||
|
nsecs_t timestamp;
|
||||||
|
DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
|
||||||
|
while ((n = mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
|
||||||
|
for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
|
||||||
|
if (buf[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
|
||||||
|
timestamp = buf[i].header.timestamp;
|
||||||
|
gotVsync = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gotVsync) {
|
||||||
|
std::scoped_lock lock(mLock);
|
||||||
|
mLocked.animationPending = false;
|
||||||
|
handleCallbacksLocked(timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsecs_t PointerControllerContext::PointerAnimator::getAnimationTimeLocked() REQUIRES(mLock) {
|
||||||
|
return mLocked.animationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::PointerAnimator::startAnimationLocked() REQUIRES(mLock) {
|
||||||
|
if (!mLocked.animationPending) {
|
||||||
|
mLocked.animationPending = true;
|
||||||
|
mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||||
|
mDisplayEventReceiver.requestNextVsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerControllerContext::PointerAnimator::handleCallbacksLocked(nsecs_t timestamp)
|
||||||
|
REQUIRES(mLock) {
|
||||||
|
for (auto it = mLocked.callbacks.begin(); it != mLocked.callbacks.end();) {
|
||||||
|
bool keepCallback = it->second(timestamp);
|
||||||
|
if (!keepCallback) {
|
||||||
|
it = mLocked.callbacks.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mLocked.callbacks.empty()) {
|
||||||
|
startAnimationLocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <utils/Looper.h>
|
#include <utils/Looper.h>
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -35,6 +36,8 @@
|
|||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
class PointerController;
|
class PointerController;
|
||||||
|
class MouseCursorController;
|
||||||
|
class TouchSpotController;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pointer resources.
|
* Pointer resources.
|
||||||
@@ -96,7 +99,6 @@ public:
|
|||||||
void startAnimation();
|
void startAnimation();
|
||||||
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
|
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
|
||||||
|
|
||||||
void setAnimationPending(bool animationPending);
|
|
||||||
nsecs_t getAnimationTime();
|
nsecs_t getAnimationTime();
|
||||||
|
|
||||||
void clearSpotsByDisplay(int32_t displayId);
|
void clearSpotsByDisplay(int32_t displayId);
|
||||||
@@ -107,9 +109,11 @@ public:
|
|||||||
sp<PointerControllerPolicyInterface> getPolicy();
|
sp<PointerControllerPolicyInterface> getPolicy();
|
||||||
sp<SpriteController> getSpriteController();
|
sp<SpriteController> getSpriteController();
|
||||||
|
|
||||||
void initializeDisplayEventReceiver();
|
|
||||||
void handleDisplayEvents();
|
void handleDisplayEvents();
|
||||||
|
|
||||||
|
void addAnimationCallback(int32_t displayId, std::function<bool(nsecs_t)> callback);
|
||||||
|
void removeAnimationCallback(int32_t displayId);
|
||||||
|
|
||||||
class MessageHandler : public virtual android::MessageHandler {
|
class MessageHandler : public virtual android::MessageHandler {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
@@ -127,22 +131,47 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class PointerAnimator {
|
||||||
|
public:
|
||||||
|
PointerAnimator(PointerControllerContext& context);
|
||||||
|
|
||||||
|
void addCallback(int32_t displayId, std::function<bool(nsecs_t)> callback);
|
||||||
|
void removeCallback(int32_t displayId);
|
||||||
|
void handleVsyncEvents();
|
||||||
|
nsecs_t getAnimationTimeLocked();
|
||||||
|
|
||||||
|
mutable std::mutex mLock;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Locked {
|
||||||
|
bool animationPending{false};
|
||||||
|
nsecs_t animationTime{systemTime(SYSTEM_TIME_MONOTONIC)};
|
||||||
|
|
||||||
|
std::unordered_map<int32_t, std::function<bool(nsecs_t)>> callbacks;
|
||||||
|
} mLocked GUARDED_BY(mLock);
|
||||||
|
|
||||||
|
DisplayEventReceiver mDisplayEventReceiver;
|
||||||
|
|
||||||
|
PointerControllerContext& mContext;
|
||||||
|
|
||||||
|
void initializeDisplayEventReceiver();
|
||||||
|
void startAnimationLocked();
|
||||||
|
void handleCallbacksLocked(nsecs_t timestamp);
|
||||||
|
};
|
||||||
|
|
||||||
sp<PointerControllerPolicyInterface> mPolicy;
|
sp<PointerControllerPolicyInterface> mPolicy;
|
||||||
sp<Looper> mLooper;
|
sp<Looper> mLooper;
|
||||||
sp<SpriteController> mSpriteController;
|
sp<SpriteController> mSpriteController;
|
||||||
sp<MessageHandler> mHandler;
|
sp<MessageHandler> mHandler;
|
||||||
sp<LooperCallback> mCallback;
|
sp<LooperCallback> mCallback;
|
||||||
|
|
||||||
DisplayEventReceiver mDisplayEventReceiver;
|
|
||||||
|
|
||||||
PointerController& mController;
|
PointerController& mController;
|
||||||
|
|
||||||
|
PointerAnimator mAnimator;
|
||||||
|
|
||||||
mutable std::mutex mLock;
|
mutable std::mutex mLock;
|
||||||
|
|
||||||
struct Locked {
|
struct Locked {
|
||||||
bool animationPending;
|
|
||||||
nsecs_t animationTime;
|
|
||||||
|
|
||||||
InactivityTimeout inactivityTimeout;
|
InactivityTimeout inactivityTimeout;
|
||||||
} mLocked GUARDED_BY(mLock);
|
} mLocked GUARDED_BY(mLock);
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,8 @@ TouchSpotController::Spot* TouchSpotController::getSpot(uint32_t id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TouchSpotController::Spot* TouchSpotController::createAndAddSpotLocked(uint32_t id,
|
TouchSpotController::Spot* TouchSpotController::createAndAddSpotLocked(uint32_t id,
|
||||||
std::vector<Spot*>& spots) {
|
std::vector<Spot*>& spots)
|
||||||
|
REQUIRES(mLock) {
|
||||||
// Remove spots until we have fewer than MAX_SPOTS remaining.
|
// Remove spots until we have fewer than MAX_SPOTS remaining.
|
||||||
while (spots.size() >= MAX_SPOTS) {
|
while (spots.size() >= MAX_SPOTS) {
|
||||||
Spot* spot = removeFirstFadingSpotLocked(spots);
|
Spot* spot = removeFirstFadingSpotLocked(spots);
|
||||||
@@ -186,14 +187,13 @@ void TouchSpotController::releaseSpotLocked(Spot* spot) REQUIRES(mLock) {
|
|||||||
if (mLocked.recycledSprites.size() < MAX_RECYCLED_SPRITES) {
|
if (mLocked.recycledSprites.size() < MAX_RECYCLED_SPRITES) {
|
||||||
mLocked.recycledSprites.push_back(spot->sprite);
|
mLocked.recycledSprites.push_back(spot->sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete spot;
|
delete spot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchSpotController::fadeOutAndReleaseSpotLocked(Spot* spot) REQUIRES(mLock) {
|
void TouchSpotController::fadeOutAndReleaseSpotLocked(Spot* spot) REQUIRES(mLock) {
|
||||||
if (spot->id != Spot::INVALID_ID) {
|
if (spot->id != Spot::INVALID_ID) {
|
||||||
spot->id = Spot::INVALID_ID;
|
spot->id = Spot::INVALID_ID;
|
||||||
mContext.startAnimation();
|
startAnimationLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,8 +209,24 @@ void TouchSpotController::reloadSpotResources() {
|
|||||||
mContext.getPolicy()->loadPointerResources(&mResources, mDisplayId);
|
mContext.getPolicy()->loadPointerResources(&mResources, mDisplayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TouchSpotController::doFadingAnimation(nsecs_t timestamp, bool keepAnimating) {
|
bool TouchSpotController::doAnimations(nsecs_t timestamp) {
|
||||||
std::scoped_lock lock(mLock);
|
std::scoped_lock lock(mLock);
|
||||||
|
bool keepAnimating = doFadingAnimationLocked(timestamp);
|
||||||
|
if (!keepAnimating) {
|
||||||
|
/*
|
||||||
|
* We know that this callback will be removed before another
|
||||||
|
* is added. mLock in PointerAnimator will not be released
|
||||||
|
* until after this is removed, and adding another callback
|
||||||
|
* requires that lock. Thus it's safe to set mLocked.animating
|
||||||
|
* here.
|
||||||
|
*/
|
||||||
|
mLocked.animating = false;
|
||||||
|
}
|
||||||
|
return keepAnimating;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TouchSpotController::doFadingAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
|
||||||
|
bool keepAnimating = false;
|
||||||
nsecs_t animationTime = mContext.getAnimationTime();
|
nsecs_t animationTime = mContext.getAnimationTime();
|
||||||
nsecs_t frameDelay = timestamp - animationTime;
|
nsecs_t frameDelay = timestamp - animationTime;
|
||||||
size_t numSpots = mLocked.displaySpots.size();
|
size_t numSpots = mLocked.displaySpots.size();
|
||||||
@@ -233,4 +249,16 @@ bool TouchSpotController::doFadingAnimation(nsecs_t timestamp, bool keepAnimatin
|
|||||||
return keepAnimating;
|
return keepAnimating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TouchSpotController::startAnimationLocked() REQUIRES(mLock) {
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
if (mLocked.animating) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mLocked.animating = true;
|
||||||
|
|
||||||
|
std::function<bool(nsecs_t)> func = std::bind(&TouchSpotController::doAnimations, this, _1);
|
||||||
|
mContext.addAnimationCallback(mDisplayId, func);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#ifndef _UI_TOUCH_SPOT_CONTROLLER_H
|
#ifndef _UI_TOUCH_SPOT_CONTROLLER_H
|
||||||
#define _UI_TOUCH_SPOT_CONTROLLER_H
|
#define _UI_TOUCH_SPOT_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "PointerControllerContext.h"
|
#include "PointerControllerContext.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
@@ -34,7 +36,7 @@ public:
|
|||||||
void clearSpots();
|
void clearSpots();
|
||||||
|
|
||||||
void reloadSpotResources();
|
void reloadSpotResources();
|
||||||
bool doFadingAnimation(nsecs_t timestamp, bool keepAnimating);
|
bool doAnimations(nsecs_t timestamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Spot {
|
struct Spot {
|
||||||
@@ -76,6 +78,8 @@ private:
|
|||||||
std::vector<Spot*> displaySpots;
|
std::vector<Spot*> displaySpots;
|
||||||
std::vector<sp<Sprite>> recycledSprites;
|
std::vector<sp<Sprite>> recycledSprites;
|
||||||
|
|
||||||
|
bool animating{false};
|
||||||
|
|
||||||
} mLocked GUARDED_BY(mLock);
|
} mLocked GUARDED_BY(mLock);
|
||||||
|
|
||||||
Spot* getSpot(uint32_t id, const std::vector<Spot*>& spots);
|
Spot* getSpot(uint32_t id, const std::vector<Spot*>& spots);
|
||||||
@@ -84,6 +88,8 @@ private:
|
|||||||
void releaseSpotLocked(Spot* spot);
|
void releaseSpotLocked(Spot* spot);
|
||||||
void fadeOutAndReleaseSpotLocked(Spot* spot);
|
void fadeOutAndReleaseSpotLocked(Spot* spot);
|
||||||
void fadeOutAndReleaseAllSpotsLocked();
|
void fadeOutAndReleaseAllSpotsLocked();
|
||||||
|
bool doFadingAnimationLocked(nsecs_t timestamp);
|
||||||
|
void startAnimationLocked();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
Reference in New Issue
Block a user