Refactor SubscriptionManager caching code

Create a genericized class to use for SubscriptionManager caching calls
in order to avoid duplicating logic that fetches values from ISub.

Bug: 151953109
Test: atest android.telephony.cts.SubscriptionManagerTest
Change-Id: I6682ded8aec8cb3e50521584c177df6d5dae8c49
diff --git a/Android.bp b/Android.bp
index 4fd129d..a604b8f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1138,6 +1138,7 @@
         "core/java/com/android/internal/os/SomeArgs.java",
         "core/java/com/android/internal/util/BitwiseInputStream.java",
         "core/java/com/android/internal/util/BitwiseOutputStream.java",
+        "core/java/com/android/internal/util/FunctionalUtils.java",
         "core/java/com/android/internal/util/HexDump.java",
         "core/java/com/android/internal/util/IndentingPrintWriter.java",
         "core/java/com/android/internal/util/Preconditions.java",
diff --git a/telephony/framework-telephony-jarjar-rules.txt b/telephony/framework-telephony-jarjar-rules.txt
index 212eba1..e1bb901 100644
--- a/telephony/framework-telephony-jarjar-rules.txt
+++ b/telephony/framework-telephony-jarjar-rules.txt
@@ -4,6 +4,7 @@
 rule com.android.internal.os.SomeArgs* android.telephony.SomeArgs@1
 rule com.android.internal.util.BitwiseInputStream* android.telephony.BitwiseInputStream@1
 rule com.android.internal.util.BitwiseOutputStream* android.telephony.BitwiseOutputStream@1
+rule com.android.internal.util.FunctionalUtils* android.telephony.FunctionalUtils@1
 rule com.android.internal.util.Preconditions* android.telephony.Preconditions@1
 rule com.android.internal.util.IndentingPrintWriter* android.telephony.IndentingPrintWriter@1
 rule com.android.internal.util.HexDump* android.telephony.HexDump@1
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 562b3cd..85f1720 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -63,6 +63,7 @@
 import com.android.internal.telephony.ISub;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.util.HandlerExecutor;
+import com.android.internal.util.FunctionalUtils;
 import com.android.internal.util.Preconditions;
 import com.android.telephony.Rlog;
 
@@ -145,21 +146,49 @@
 
     private static final int MAX_CACHE_SIZE = 4;
 
-    private static PropertyInvalidatedCache<Void, Integer> sDefaultSubIdCache =
-            new PropertyInvalidatedCache<Void, Integer>(
-                    MAX_CACHE_SIZE, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY) {
-            @Override
-            protected Integer recompute(Void query) {
-                return getDefaultSubscriptionIdInternal();
-            }};
+    private static class SubscriptionPropertyInvalidatedCache<T>
+            extends PropertyInvalidatedCache<Void, T> {
+        private final FunctionalUtils.ThrowingFunction<ISub, T> mSubscriptionInterfaceMethod;
+        private final String mCacheKeyProperty;
+        private final T mDefaultValue;
 
-    private static PropertyInvalidatedCache<Void, Integer> sDefaultDataSubIdCache =
-            new PropertyInvalidatedCache<Void, Integer>(
-                    MAX_CACHE_SIZE, CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY) {
-            @Override
-            protected Integer recompute(Void query) {
-                return getDefaultDataSubscriptionIdInternal();
-            }};
+        SubscriptionPropertyInvalidatedCache(
+                FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod,
+                String cacheKeyProperty,
+                T defaultValue) {
+            super(MAX_CACHE_SIZE, cacheKeyProperty);
+            mSubscriptionInterfaceMethod = subscriptionInterfaceMethod;
+            mCacheKeyProperty = cacheKeyProperty;
+            mDefaultValue = defaultValue;
+        }
+
+        @Override
+        protected T recompute(Void aVoid) {
+            T result = mDefaultValue;
+
+            try {
+                ISub iSub = TelephonyManager.getSubscriptionService();
+                if (iSub != null) {
+                    result = mSubscriptionInterfaceMethod.applyOrThrow(iSub);
+                }
+            } catch (Exception ex) {
+                Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
+            }
+
+            if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
+            return result;
+        }
+    }
+
+    private static SubscriptionPropertyInvalidatedCache<Integer> sDefaultSubIdCache =
+            new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultSubId,
+                    CACHE_KEY_DEFAULT_SUB_ID_PROPERTY,
+                    INVALID_SUBSCRIPTION_ID);
+
+    private static SubscriptionPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache =
+            new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
+                    CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY,
+                    INVALID_SUBSCRIPTION_ID);
 
     private static PropertyInvalidatedCache<Void, Integer> sActiveDataSubIdCache =
             new PropertyInvalidatedCache<Void, Integer>(
@@ -1886,22 +1915,6 @@
         return sDefaultSubIdCache.query(null);
     }
 
-    private static int getDefaultSubscriptionIdInternal() {
-        int subId = INVALID_SUBSCRIPTION_ID;
-
-        try {
-            ISub iSub = TelephonyManager.getSubscriptionService();
-            if (iSub != null) {
-                subId = iSub.getDefaultSubId();
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        if (VDBG) logd("getDefaultSubId=" + subId);
-        return subId;
-    }
-
     /**
      * Returns the system's default voice subscription id.
      *
@@ -2055,22 +2068,6 @@
         return sDefaultDataSubIdCache.query(null);
     }
 
-    private static int getDefaultDataSubscriptionIdInternal() {
-        int subId = INVALID_SUBSCRIPTION_ID;
-
-        try {
-            ISub iSub = TelephonyManager.getSubscriptionService();
-            if (iSub != null) {
-                subId = iSub.getDefaultDataSubId();
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        if (VDBG) logd("getDefaultDataSubscriptionId, sub id = " + subId);
-        return subId;
-    }
-
     /**
      * Set the subscription which will be used by default for data, with the subscription which
      * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied