From 767cda30ef4d389885520d71961bf84082526628 Mon Sep 17 00:00:00 2001 From: Kevin Jeon Date: Tue, 17 Nov 2020 01:40:16 +0000 Subject: [PATCH] Cache the telecom service in getTelecomService() This change caches the results of getTelecomService() and implements a death recipient that clears the cache when necessary. Bug: 173460628 Bug: 173039862 Test: manual testing (phone calls, dialer tab transitions) Change-Id: I438d479c78319eafa917ba661d7cbd49600fff2c --- .../java/android/telecom/TelecomManager.java | 46 +++++++++++++++++-- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 7143bef8d608c..960b0df400616 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -32,6 +32,7 @@ import android.content.Intent; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; @@ -42,6 +43,7 @@ import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import com.android.internal.annotations.GuardedBy; import com.android.internal.telecom.ITelecomService; import java.lang.annotation.Retention; @@ -943,6 +945,15 @@ public class TelecomManager { private static final String TAG = "TelecomManager"; + + /** Cached service handles, cleared by resetServiceCache() at death */ + private static final Object CACHE_LOCK = new Object(); + + @GuardedBy("CACHE_LOCK") + private static ITelecomService sTelecomService; + @GuardedBy("CACHE_LOCK") + private static final DeathRecipient SERVICE_DEATH = new DeathRecipient(); + private final Context mContext; private final ITelecomService mTelecomServiceOverride; @@ -2472,11 +2483,36 @@ public class TelecomManager { if (mTelecomServiceOverride != null) { return mTelecomServiceOverride; } - ITelecomService service = ITelecomService.Stub.asInterface( - ServiceManager.getService(Context.TELECOM_SERVICE)); - if (service == null) { - Log.w(TAG, "Telecom Service not found."); + if (sTelecomService == null) { + ITelecomService temp = ITelecomService.Stub.asInterface( + ServiceManager.getService(Context.TELECOM_SERVICE)); + synchronized (CACHE_LOCK) { + if (sTelecomService == null && temp != null) { + try { + sTelecomService = temp; + sTelecomService.asBinder().linkToDeath(SERVICE_DEATH, 0); + } catch (Exception e) { + sTelecomService = null; + } + } + } + } + return sTelecomService; + } + + private static class DeathRecipient implements IBinder.DeathRecipient { + @Override + public void binderDied() { + resetServiceCache(); + } + } + + private static void resetServiceCache() { + synchronized (CACHE_LOCK) { + if (sTelecomService != null) { + sTelecomService.asBinder().unlinkToDeath(SERVICE_DEATH, 0); + sTelecomService = null; + } } - return service; } }