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
This commit is contained in:
Kevin Jeon
2020-11-17 01:40:16 +00:00
parent 324710c1ba
commit 767cda30ef

View File

@@ -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;
}
}