1 /* 2 * Copyright (C) 2022 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 package com.android.server.wm; 18 19 import android.content.Context; 20 import android.os.IBinder; 21 import android.os.RemoteException; 22 import android.window.ITaskFpsCallback; 23 24 import java.util.HashMap; 25 26 final class TaskFpsCallbackController { 27 28 private final Context mContext; 29 private final HashMap<IBinder, Long> mTaskFpsCallbacks; 30 private final HashMap<IBinder, IBinder.DeathRecipient> mDeathRecipients; 31 TaskFpsCallbackController(Context context)32 TaskFpsCallbackController(Context context) { 33 mContext = context; 34 mTaskFpsCallbacks = new HashMap<>(); 35 mDeathRecipients = new HashMap<>(); 36 } 37 registerListener(int taskId, ITaskFpsCallback callback)38 void registerListener(int taskId, ITaskFpsCallback callback) { 39 if (callback == null) { 40 return; 41 } 42 43 IBinder binder = callback.asBinder(); 44 if (mTaskFpsCallbacks.containsKey(binder)) { 45 return; 46 } 47 48 final long nativeListener = nativeRegister(callback, taskId); 49 mTaskFpsCallbacks.put(binder, nativeListener); 50 51 final IBinder.DeathRecipient deathRecipient = () -> unregisterListener(callback); 52 try { 53 binder.linkToDeath(deathRecipient, 0); 54 mDeathRecipients.put(binder, deathRecipient); 55 } catch (RemoteException e) { 56 // ignore 57 } 58 } 59 unregisterListener(ITaskFpsCallback callback)60 void unregisterListener(ITaskFpsCallback callback) { 61 if (callback == null) { 62 return; 63 } 64 65 IBinder binder = callback.asBinder(); 66 if (!mTaskFpsCallbacks.containsKey(binder)) { 67 return; 68 } 69 70 binder.unlinkToDeath(mDeathRecipients.get(binder), 0); 71 mDeathRecipients.remove(binder); 72 73 nativeUnregister(mTaskFpsCallbacks.get(binder)); 74 mTaskFpsCallbacks.remove(binder); 75 } 76 nativeRegister(ITaskFpsCallback callback, int taskId)77 private static native long nativeRegister(ITaskFpsCallback callback, int taskId); nativeUnregister(long ptr)78 private static native void nativeUnregister(long ptr); 79 } 80