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
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 7143bef..960b0df4 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -32,6 +32,7 @@
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.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 @@
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 @@
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 service;
+ 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;
+ }
+ }
}
}