Hold a weak reference to PointerController when handling vsync

Currently PointerController starts listening to display events
immediately (in its constructor) and never explicitly removes
the callback. The reference dangling from the looper
prevents the PointerController instance from being deleted
when all the clients have released their references.

As a result, when USB or BT mouse is disconnected,
the mouse stays frozen on screen and only goes away
after a 15 sec inactivity timeout.

This change introduces an intermediary LooperCallback
which holds only a weak reference to PointerController.
The pointer now disappears immediately upon mouse
disconnect.

Bug: 30824220
Change-Id: I5f7208dbfa381b3e21f248cc0da402f307faa184
This commit is contained in:
Vladislav Kaznacheev
2016-09-09 10:03:31 -07:00
parent fd97e7bc8c
commit 33c5903e77
2 changed files with 26 additions and 1 deletions

View File

@@ -36,6 +36,29 @@
namespace android {
// --- WeakLooperCallback ---
class WeakLooperCallback: public LooperCallback {
protected:
virtual ~WeakLooperCallback() { }
public:
WeakLooperCallback(const wp<LooperCallback>& callback) :
mCallback(callback) {
}
virtual int handleEvent(int fd, int events, void* data) {
sp<LooperCallback> callback = mCallback.promote();
if (callback != NULL) {
return callback->handleEvent(fd, events, data);
}
return 0; // the client is gone, remove the callback
}
private:
wp<LooperCallback> mCallback;
};
// --- PointerController ---
// Time to wait before starting the fade when the pointer is inactive.
@@ -57,10 +80,11 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>&
const sp<Looper>& looper, const sp<SpriteController>& spriteController) :
mPolicy(policy), mLooper(looper), mSpriteController(spriteController) {
mHandler = new WeakMessageHandler(this);
mCallback = new WeakLooperCallback(this);
if (mDisplayEventReceiver.initCheck() == NO_ERROR) {
mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK,
Looper::EVENT_INPUT, this, nullptr);
Looper::EVENT_INPUT, mCallback, nullptr);
} else {
ALOGE("Failed to initialize DisplayEventReceiver.");
}

View File

@@ -144,6 +144,7 @@ private:
sp<Looper> mLooper;
sp<SpriteController> mSpriteController;
sp<WeakMessageHandler> mHandler;
sp<LooperCallback> mCallback;
DisplayEventReceiver mDisplayEventReceiver;