Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3730a1bc authored by Rikka's avatar Rikka Committed by Rikka Takanashi
Browse files

Fix com.android.server.wm.TaskFpsCallbackController#unregisterListener method NEVER works

In com.android.server.wm.TaskFpsCallbackController class, ITaskFpsCallback (which extends IInterface) is used as the key for the HashMap. As ITaskFpsCallback instance is created every time, the unregisterListener method will NEVER work.

The correct usage is to use ITaskFpsCallback#asBinder as the key, just like what RemoteCallbackList do.

Change-Id: I16321d6784402105aea90a816f9ab23bd72e4635
parent b8ceb69f
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -26,8 +26,8 @@ import java.util.HashMap;
final class TaskFpsCallbackController {

    private final Context mContext;
    private final HashMap<ITaskFpsCallback, Long> mTaskFpsCallbacks;
    private final HashMap<ITaskFpsCallback, IBinder.DeathRecipient> mDeathRecipients;
    private final HashMap<IBinder, Long> mTaskFpsCallbacks;
    private final HashMap<IBinder, IBinder.DeathRecipient> mDeathRecipients;

    TaskFpsCallbackController(Context context) {
        mContext = context;
@@ -36,32 +36,42 @@ final class TaskFpsCallbackController {
    }

    void registerListener(int taskId, ITaskFpsCallback callback) {
        if (mTaskFpsCallbacks.containsKey(callback)) {
        if (callback == null) {
            return;
        }

        IBinder binder = callback.asBinder();
        if (mTaskFpsCallbacks.containsKey(binder)) {
            return;
        }

        final long nativeListener = nativeRegister(callback, taskId);
        mTaskFpsCallbacks.put(callback, nativeListener);
        mTaskFpsCallbacks.put(binder, nativeListener);

        final IBinder.DeathRecipient deathRecipient = () -> unregisterListener(callback);
        try {
            callback.asBinder().linkToDeath(deathRecipient, 0);
            mDeathRecipients.put(callback, deathRecipient);
            binder.linkToDeath(deathRecipient, 0);
            mDeathRecipients.put(binder, deathRecipient);
        } catch (RemoteException e) {
            // ignore
        }
    }

    void unregisterListener(ITaskFpsCallback callback) {
        if (!mTaskFpsCallbacks.containsKey(callback)) {
        if (callback == null) {
            return;
        }

        IBinder binder = callback.asBinder();
        if (!mTaskFpsCallbacks.containsKey(binder)) {
            return;
        }

        callback.asBinder().unlinkToDeath(mDeathRecipients.get(callback), 0);
        mDeathRecipients.remove(callback);
        binder.unlinkToDeath(mDeathRecipients.get(binder), 0);
        mDeathRecipients.remove(binder);

        nativeUnregister(mTaskFpsCallbacks.get(callback));
        mTaskFpsCallbacks.remove(callback);
        nativeUnregister(mTaskFpsCallbacks.get(binder));
        mTaskFpsCallbacks.remove(binder);
    }

    private static native long nativeRegister(ITaskFpsCallback callback, int taskId);