Loading core/java/com/android/internal/util/FunctionalUtils.java +27 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.RemoteException; import android.util.ExceptionUtils; import android.util.ExceptionUtils; import java.util.function.BiConsumer; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Function; import java.util.function.Supplier; import java.util.function.Supplier; Loading Loading @@ -195,6 +196,32 @@ public class FunctionalUtils { } } } } /** * A {@link BiFunction} that allows throwing checked exceptions from its single abstract method. * * Can be used together with {@link #uncheckExceptions} to effectively turn a lambda expression * that throws a checked exception into a regular {@link BiFunction} * * @param <T> see {@link BiFunction} * @param <U> see {@link BiFunction} * @param <R> see {@link BiFunction} */ @FunctionalInterface @SuppressWarnings("FunctionalInterfaceMethodChanged") public interface ThrowingBiFunction<T, U, R> extends BiFunction<T, U, R> { /** @see ThrowingFunction */ R applyOrThrow(T t, U u) throws Exception; @Override default R apply(T t, U u) { try { return applyOrThrow(t, u); } catch (Exception ex) { throw ExceptionUtils.propagate(ex); } } } /** /** * A {@link BiConsumer} that allows throwing checked exceptions from its single abstract method. * A {@link BiConsumer} that allows throwing checked exceptions from its single abstract method. * * Loading telephony/java/android/telephony/SubscriptionManager.java +82 −64 Original line number Original line Diff line number Diff line Loading @@ -148,20 +148,24 @@ public class SubscriptionManager { public static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY = public static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY = "cache_key.telephony.get_active_data_sub_id"; "cache_key.telephony.get_active_data_sub_id"; /** @hide */ public static final String CACHE_KEY_SLOT_INDEX_PROPERTY = "cache_key.telephony.get_slot_index"; private static final int MAX_CACHE_SIZE = 4; private static final int MAX_CACHE_SIZE = 4; private static class SubscriptionPropertyInvalidatedCache<T> private static class VoidPropertyInvalidatedCache<T> extends PropertyInvalidatedCache<Void, T> { extends PropertyInvalidatedCache<Void, T> { private final FunctionalUtils.ThrowingFunction<ISub, T> mSubscriptionInterfaceMethod; private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod; private final String mCacheKeyProperty; private final String mCacheKeyProperty; private final T mDefaultValue; private final T mDefaultValue; SubscriptionPropertyInvalidatedCache( VoidPropertyInvalidatedCache( FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod, FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod, String cacheKeyProperty, String cacheKeyProperty, T defaultValue) { T defaultValue) { super(MAX_CACHE_SIZE, cacheKeyProperty); super(MAX_CACHE_SIZE, cacheKeyProperty); mSubscriptionInterfaceMethod = subscriptionInterfaceMethod; mInterfaceMethod = subscriptionInterfaceMethod; mCacheKeyProperty = cacheKeyProperty; mCacheKeyProperty = cacheKeyProperty; mDefaultValue = defaultValue; mDefaultValue = defaultValue; } } Loading @@ -173,7 +177,41 @@ public class SubscriptionManager { try { try { ISub iSub = TelephonyManager.getSubscriptionService(); ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { if (iSub != null) { result = mSubscriptionInterfaceMethod.applyOrThrow(iSub); result = mInterfaceMethod.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 class IntegerPropertyInvalidatedCache<T> extends PropertyInvalidatedCache<Integer, T> { private final FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> mInterfaceMethod; private final String mCacheKeyProperty; private final T mDefaultValue; IntegerPropertyInvalidatedCache( FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod, String cacheKeyProperty, T defaultValue) { super(MAX_CACHE_SIZE, cacheKeyProperty); mInterfaceMethod = subscriptionInterfaceMethod; mCacheKeyProperty = cacheKeyProperty; mDefaultValue = defaultValue; } @Override protected T recompute(Integer query) { T result = mDefaultValue; try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { result = mInterfaceMethod.applyOrThrow(iSub, query); } } } catch (Exception ex) { } catch (Exception ex) { Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty); Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty); Loading @@ -184,26 +222,37 @@ public class SubscriptionManager { } } } } private static SubscriptionPropertyInvalidatedCache<Integer> sDefaultSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sDefaultSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultSubId, new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static SubscriptionPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultDataSubId, new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId, CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY, CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static PropertyInvalidatedCache<Void, Integer> sDefaultSmsSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sDefaultSmsSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId, new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId, CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY, CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static PropertyInvalidatedCache<Void, Integer> sActiveDataSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sActiveDataSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId, new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId, CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY, CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static IntegerPropertyInvalidatedCache<Integer> sSlotIndexCache = new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex, CACHE_KEY_SLOT_INDEX_PROPERTY, INVALID_SIM_SLOT_INDEX); /** Cache depends on getDefaultSubId, so we use the defaultSubId cache key */ private static IntegerPropertyInvalidatedCache<Integer> sPhoneIdCache = new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY, INVALID_PHONE_INDEX); /** /** * Generates a content {@link Uri} used to receive updates on simInfo change * Generates a content {@link Uri} used to receive updates on simInfo change * on the given subscriptionId * on the given subscriptionId Loading Loading @@ -1246,7 +1295,6 @@ public class SubscriptionManager { } } return subInfo; return subInfo; } } /** /** Loading Loading @@ -1816,25 +1864,7 @@ public class SubscriptionManager { * subscriptionId doesn't have an associated slot index. * subscriptionId doesn't have an associated slot index. */ */ public static int getSlotIndex(int subscriptionId) { public static int getSlotIndex(int subscriptionId) { if (!isValidSubscriptionId(subscriptionId)) { return sSlotIndexCache.query(subscriptionId); if (DBG) { logd("[getSlotIndex]- supplied subscriptionId is invalid."); } } int result = INVALID_SIM_SLOT_INDEX; try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { result = iSub.getSlotIndex(subscriptionId); } } catch (RemoteException ex) { // ignore it } return result; } } /** /** Loading Loading @@ -1873,27 +1903,7 @@ public class SubscriptionManager { /** @hide */ /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public static int getPhoneId(int subId) { public static int getPhoneId(int subId) { if (!isValidSubscriptionId(subId)) { return sPhoneIdCache.query(subId); if (DBG) { logd("[getPhoneId]- fail"); } return INVALID_PHONE_INDEX; } int result = INVALID_PHONE_INDEX; try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { result = iSub.getPhoneId(subId); } } catch (RemoteException ex) { // ignore it } if (VDBG) logd("[getPhoneId]- phoneId=" + result); return result; } } private static void logd(String msg) { private static void logd(String msg) { Loading Loading @@ -3326,16 +3336,9 @@ public class SubscriptionManager { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY); PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY); } } /** /** @hide */ * Clears all process-local binder caches. public static void invalidateSlotIndexCaches() { * PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SLOT_INDEX_PROPERTY); * @hide */ public static void clearCaches() { sDefaultSubIdCache.clear(); sDefaultDataSubIdCache.clear(); sActiveDataSubIdCache.clear(); sDefaultSmsSubIdCache.clear(); } } /** /** Loading @@ -3348,5 +3351,20 @@ public class SubscriptionManager { sDefaultDataSubIdCache.disableLocal(); sDefaultDataSubIdCache.disableLocal(); sActiveDataSubIdCache.disableLocal(); sActiveDataSubIdCache.disableLocal(); sDefaultSmsSubIdCache.disableLocal(); sDefaultSmsSubIdCache.disableLocal(); sSlotIndexCache.disableLocal(); sPhoneIdCache.disableLocal(); } /** * Clears all process-local binder caches. * * @hide */ public static void clearCaches() { sDefaultSubIdCache.clear(); sDefaultDataSubIdCache.clear(); sActiveDataSubIdCache.clear(); sDefaultSmsSubIdCache.clear(); sSlotIndexCache.clear(); sPhoneIdCache.clear(); } } } } Loading
core/java/com/android/internal/util/FunctionalUtils.java +27 −0 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.os.RemoteException; import android.util.ExceptionUtils; import android.util.ExceptionUtils; import java.util.function.BiConsumer; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Function; import java.util.function.Supplier; import java.util.function.Supplier; Loading Loading @@ -195,6 +196,32 @@ public class FunctionalUtils { } } } } /** * A {@link BiFunction} that allows throwing checked exceptions from its single abstract method. * * Can be used together with {@link #uncheckExceptions} to effectively turn a lambda expression * that throws a checked exception into a regular {@link BiFunction} * * @param <T> see {@link BiFunction} * @param <U> see {@link BiFunction} * @param <R> see {@link BiFunction} */ @FunctionalInterface @SuppressWarnings("FunctionalInterfaceMethodChanged") public interface ThrowingBiFunction<T, U, R> extends BiFunction<T, U, R> { /** @see ThrowingFunction */ R applyOrThrow(T t, U u) throws Exception; @Override default R apply(T t, U u) { try { return applyOrThrow(t, u); } catch (Exception ex) { throw ExceptionUtils.propagate(ex); } } } /** /** * A {@link BiConsumer} that allows throwing checked exceptions from its single abstract method. * A {@link BiConsumer} that allows throwing checked exceptions from its single abstract method. * * Loading
telephony/java/android/telephony/SubscriptionManager.java +82 −64 Original line number Original line Diff line number Diff line Loading @@ -148,20 +148,24 @@ public class SubscriptionManager { public static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY = public static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY = "cache_key.telephony.get_active_data_sub_id"; "cache_key.telephony.get_active_data_sub_id"; /** @hide */ public static final String CACHE_KEY_SLOT_INDEX_PROPERTY = "cache_key.telephony.get_slot_index"; private static final int MAX_CACHE_SIZE = 4; private static final int MAX_CACHE_SIZE = 4; private static class SubscriptionPropertyInvalidatedCache<T> private static class VoidPropertyInvalidatedCache<T> extends PropertyInvalidatedCache<Void, T> { extends PropertyInvalidatedCache<Void, T> { private final FunctionalUtils.ThrowingFunction<ISub, T> mSubscriptionInterfaceMethod; private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod; private final String mCacheKeyProperty; private final String mCacheKeyProperty; private final T mDefaultValue; private final T mDefaultValue; SubscriptionPropertyInvalidatedCache( VoidPropertyInvalidatedCache( FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod, FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod, String cacheKeyProperty, String cacheKeyProperty, T defaultValue) { T defaultValue) { super(MAX_CACHE_SIZE, cacheKeyProperty); super(MAX_CACHE_SIZE, cacheKeyProperty); mSubscriptionInterfaceMethod = subscriptionInterfaceMethod; mInterfaceMethod = subscriptionInterfaceMethod; mCacheKeyProperty = cacheKeyProperty; mCacheKeyProperty = cacheKeyProperty; mDefaultValue = defaultValue; mDefaultValue = defaultValue; } } Loading @@ -173,7 +177,41 @@ public class SubscriptionManager { try { try { ISub iSub = TelephonyManager.getSubscriptionService(); ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { if (iSub != null) { result = mSubscriptionInterfaceMethod.applyOrThrow(iSub); result = mInterfaceMethod.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 class IntegerPropertyInvalidatedCache<T> extends PropertyInvalidatedCache<Integer, T> { private final FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> mInterfaceMethod; private final String mCacheKeyProperty; private final T mDefaultValue; IntegerPropertyInvalidatedCache( FunctionalUtils.ThrowingBiFunction<ISub, Integer, T> subscriptionInterfaceMethod, String cacheKeyProperty, T defaultValue) { super(MAX_CACHE_SIZE, cacheKeyProperty); mInterfaceMethod = subscriptionInterfaceMethod; mCacheKeyProperty = cacheKeyProperty; mDefaultValue = defaultValue; } @Override protected T recompute(Integer query) { T result = mDefaultValue; try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { result = mInterfaceMethod.applyOrThrow(iSub, query); } } } catch (Exception ex) { } catch (Exception ex) { Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty); Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty); Loading @@ -184,26 +222,37 @@ public class SubscriptionManager { } } } } private static SubscriptionPropertyInvalidatedCache<Integer> sDefaultSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sDefaultSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultSubId, new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static SubscriptionPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultDataSubId, new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId, CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY, CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static PropertyInvalidatedCache<Void, Integer> sDefaultSmsSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sDefaultSmsSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId, new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId, CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY, CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static PropertyInvalidatedCache<Void, Integer> sActiveDataSubIdCache = private static VoidPropertyInvalidatedCache<Integer> sActiveDataSubIdCache = new SubscriptionPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId, new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId, CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY, CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY, INVALID_SUBSCRIPTION_ID); INVALID_SUBSCRIPTION_ID); private static IntegerPropertyInvalidatedCache<Integer> sSlotIndexCache = new IntegerPropertyInvalidatedCache<>(ISub::getSlotIndex, CACHE_KEY_SLOT_INDEX_PROPERTY, INVALID_SIM_SLOT_INDEX); /** Cache depends on getDefaultSubId, so we use the defaultSubId cache key */ private static IntegerPropertyInvalidatedCache<Integer> sPhoneIdCache = new IntegerPropertyInvalidatedCache<>(ISub::getPhoneId, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY, INVALID_PHONE_INDEX); /** /** * Generates a content {@link Uri} used to receive updates on simInfo change * Generates a content {@link Uri} used to receive updates on simInfo change * on the given subscriptionId * on the given subscriptionId Loading Loading @@ -1246,7 +1295,6 @@ public class SubscriptionManager { } } return subInfo; return subInfo; } } /** /** Loading Loading @@ -1816,25 +1864,7 @@ public class SubscriptionManager { * subscriptionId doesn't have an associated slot index. * subscriptionId doesn't have an associated slot index. */ */ public static int getSlotIndex(int subscriptionId) { public static int getSlotIndex(int subscriptionId) { if (!isValidSubscriptionId(subscriptionId)) { return sSlotIndexCache.query(subscriptionId); if (DBG) { logd("[getSlotIndex]- supplied subscriptionId is invalid."); } } int result = INVALID_SIM_SLOT_INDEX; try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { result = iSub.getSlotIndex(subscriptionId); } } catch (RemoteException ex) { // ignore it } return result; } } /** /** Loading Loading @@ -1873,27 +1903,7 @@ public class SubscriptionManager { /** @hide */ /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public static int getPhoneId(int subId) { public static int getPhoneId(int subId) { if (!isValidSubscriptionId(subId)) { return sPhoneIdCache.query(subId); if (DBG) { logd("[getPhoneId]- fail"); } return INVALID_PHONE_INDEX; } int result = INVALID_PHONE_INDEX; try { ISub iSub = TelephonyManager.getSubscriptionService(); if (iSub != null) { result = iSub.getPhoneId(subId); } } catch (RemoteException ex) { // ignore it } if (VDBG) logd("[getPhoneId]- phoneId=" + result); return result; } } private static void logd(String msg) { private static void logd(String msg) { Loading Loading @@ -3326,16 +3336,9 @@ public class SubscriptionManager { PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY); PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY); } } /** /** @hide */ * Clears all process-local binder caches. public static void invalidateSlotIndexCaches() { * PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SLOT_INDEX_PROPERTY); * @hide */ public static void clearCaches() { sDefaultSubIdCache.clear(); sDefaultDataSubIdCache.clear(); sActiveDataSubIdCache.clear(); sDefaultSmsSubIdCache.clear(); } } /** /** Loading @@ -3348,5 +3351,20 @@ public class SubscriptionManager { sDefaultDataSubIdCache.disableLocal(); sDefaultDataSubIdCache.disableLocal(); sActiveDataSubIdCache.disableLocal(); sActiveDataSubIdCache.disableLocal(); sDefaultSmsSubIdCache.disableLocal(); sDefaultSmsSubIdCache.disableLocal(); sSlotIndexCache.disableLocal(); sPhoneIdCache.disableLocal(); } /** * Clears all process-local binder caches. * * @hide */ public static void clearCaches() { sDefaultSubIdCache.clear(); sDefaultDataSubIdCache.clear(); sActiveDataSubIdCache.clear(); sDefaultSmsSubIdCache.clear(); sSlotIndexCache.clear(); sPhoneIdCache.clear(); } } } }