Add property invalidated cache to TelephonyManager.
Adding cache for the getSubscriptionId(PHoneAccountHandle) method.
We invalidate the cache in Telephony whenever phone account handles are
torn down to ensure that nobody has old cached data kicking around.
Test: Added unit test which confirms the number of AIDL calls when the
cache is operating as expected.
Test: Manual test; verified that I can see the property invalidated cache
logs which indicate that there are cache hits going on.
Bug: 224654574
Change-Id: I11c7c3b6ffa4111fbee5f451151e7f8f245908d1
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index f76e0fa..59d2726 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -31,6 +31,7 @@
import android.annotation.RequiresPermission;
import android.app.AppOpsManager;
import android.app.PendingIntent;
+import android.app.PropertyInvalidatedCache;
import android.app.compat.CompatChanges;
import android.app.role.RoleManager;
import android.compat.annotation.ChangeId;
@@ -2340,7 +2341,7 @@
mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
mNotifyUserActivity = new AtomicBoolean(false);
-
+ PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
publish();
}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 41937c3..fec6ee4 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -16,6 +16,7 @@
package com.android.services.telephony;
+import android.app.PropertyInvalidatedCache;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -1593,6 +1594,9 @@
}
mAccounts.clear();
}
+ // Invalidate the TelephonyManager cache which maps phone account handles to sub ids since
+ // all the phone account handles are being recreated at this point.
+ PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
}
/**
diff --git a/tests/src/com/android/services/telephony/TelephonyManagerTest.java b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
index 2202bc7..cf1ae8f 100644
--- a/tests/src/com/android/services/telephony/TelephonyManagerTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
@@ -16,14 +16,19 @@
package com.android.services.telephony;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.PropertyInvalidatedCache;
+import android.content.ComponentName;
import android.content.Context;
+import android.telecom.PhoneAccountHandle;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
@@ -48,6 +53,12 @@
public class TelephonyManagerTest {
private static final String PKG_NAME = "Unittest.TelephonyManagerTest";
private static final String TAG = "TelephonyManagerTest";
+ private static final PhoneAccountHandle TEST_HANDLE1 = new PhoneAccountHandle(
+ new ComponentName("com.test", "Test"), "1");
+ private static final int TEST_SUBID_1 = 1;
+ private static final PhoneAccountHandle TEST_HANDLE2 = new PhoneAccountHandle(
+ new ComponentName("com.test", "Test"), "2");
+ private static final int TEST_SUBID_2 = 2;
private ITelephony mMockITelephony;
private SubscriptionManager mMockSubscriptionManager;
@@ -180,4 +191,31 @@
EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
}
}
+
+ /**
+ * Verifies that {@link TelephonyManager#getSubscriptionId(PhoneAccountHandle)} is properly
+ * using a property invalidated cache.
+ * @throws Exception
+ */
+ @Test
+ public void testGetSubscriptionIdCache() throws Exception {
+ PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
+ when(mMockITelephony.getSubIdForPhoneAccountHandle(eq(TEST_HANDLE1),
+ anyString(), anyString())).thenReturn(TEST_SUBID_1);
+ when(mMockITelephony.getSubIdForPhoneAccountHandle(eq(TEST_HANDLE2),
+ anyString(), anyString())).thenReturn(TEST_SUBID_2);
+
+ // Ensure queries for phone account handles come back consistently.
+ assertEquals(TEST_SUBID_1, mTelephonyManager.getSubscriptionId(TEST_HANDLE1));
+ assertEquals(TEST_SUBID_1, mTelephonyManager.getSubscriptionId(TEST_HANDLE1));
+ assertEquals(TEST_SUBID_2, mTelephonyManager.getSubscriptionId(TEST_HANDLE2));
+ assertEquals(TEST_SUBID_2, mTelephonyManager.getSubscriptionId(TEST_HANDLE2));
+
+ // We should have only had a single call to the underlying AIDL, however. The cache should
+ // have protected us from calling this multiple times.
+ verify(mMockITelephony, times(1)).getSubIdForPhoneAccountHandle(eq(TEST_HANDLE1),
+ anyString(), anyString());
+ verify(mMockITelephony, times(1)).getSubIdForPhoneAccountHandle(eq(TEST_HANDLE2),
+ anyString(), anyString());
+ }
}