Merge changes from topic "rvc-telephony-caching" into rvc-dev

* changes:
  Cache getPhoneId and getSlotIndex binder calls.
  Refactor SubscriptionManager caching code
  Cache getDefaultSmsSubscriptionId Binder calls
  Cache getActiveDataSubscriptionId Binder calls
This commit is contained in:
Collin Fijalkovich
2020-05-05 16:30:39 +00:00
committed by Android (Google) Code Review
3 changed files with 175 additions and 109 deletions

View File

@@ -1121,6 +1121,7 @@ filegroup {
"core/java/com/android/internal/os/SomeArgs.java", "core/java/com/android/internal/os/SomeArgs.java",
"core/java/com/android/internal/util/BitwiseInputStream.java", "core/java/com/android/internal/util/BitwiseInputStream.java",
"core/java/com/android/internal/util/BitwiseOutputStream.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/HexDump.java",
"core/java/com/android/internal/util/IndentingPrintWriter.java", "core/java/com/android/internal/util/IndentingPrintWriter.java",
"core/java/com/android/internal/util/Preconditions.java", "core/java/com/android/internal/util/Preconditions.java",

View File

@@ -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;
@@ -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.
* *

View File

@@ -63,6 +63,7 @@ import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.ISub; import com.android.internal.telephony.ISub;
import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.util.HandlerExecutor; import com.android.internal.telephony.util.HandlerExecutor;
import com.android.internal.util.FunctionalUtils;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import com.android.telephony.Rlog; import com.android.telephony.Rlog;
@@ -139,23 +140,118 @@ public class SubscriptionManager {
public static final String CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY = public static final String CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY =
"cache_key.telephony.get_default_data_sub_id"; "cache_key.telephony.get_default_data_sub_id";
/** @hide */
public static final String CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY =
"cache_key.telephony.get_default_sms_sub_id";
/** @hide */
public static final String CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY =
"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 PropertyInvalidatedCache<Void, Integer> sDefaultSubIdCache = private static class VoidPropertyInvalidatedCache<T>
new PropertyInvalidatedCache<Void, Integer>( extends PropertyInvalidatedCache<Void, T> {
MAX_CACHE_SIZE, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY) { private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod;
@Override private final String mCacheKeyProperty;
protected Integer recompute(Void query) { private final T mDefaultValue;
return getDefaultSubscriptionIdInternal();
}};
private static PropertyInvalidatedCache<Void, Integer> sDefaultDataSubIdCache = VoidPropertyInvalidatedCache(
new PropertyInvalidatedCache<Void, Integer>( FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod,
MAX_CACHE_SIZE, CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY) { String cacheKeyProperty,
@Override T defaultValue) {
protected Integer recompute(Void query) { super(MAX_CACHE_SIZE, cacheKeyProperty);
return getDefaultDataSubscriptionIdInternal(); mInterfaceMethod = subscriptionInterfaceMethod;
}}; mCacheKeyProperty = cacheKeyProperty;
mDefaultValue = defaultValue;
}
@Override
protected T recompute(Void aVoid) {
T result = mDefaultValue;
try {
ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
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) {
Rlog.w(LOG_TAG, "Failed to recompute cache key for " + mCacheKeyProperty);
}
if (VDBG) logd("recomputing " + mCacheKeyProperty + ", result = " + result);
return result;
}
}
private static VoidPropertyInvalidatedCache<Integer> sDefaultSubIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getDefaultSubId,
CACHE_KEY_DEFAULT_SUB_ID_PROPERTY,
INVALID_SUBSCRIPTION_ID);
private static VoidPropertyInvalidatedCache<Integer> sDefaultDataSubIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getDefaultDataSubId,
CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY,
INVALID_SUBSCRIPTION_ID);
private static VoidPropertyInvalidatedCache<Integer> sDefaultSmsSubIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getDefaultSmsSubId,
CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY,
INVALID_SUBSCRIPTION_ID);
private static VoidPropertyInvalidatedCache<Integer> sActiveDataSubIdCache =
new VoidPropertyInvalidatedCache<>(ISub::getActiveDataSubscriptionId,
CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY,
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
@@ -1199,7 +1295,6 @@ public class SubscriptionManager {
} }
return subInfo; return subInfo;
} }
/** /**
@@ -1769,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;
} }
/** /**
@@ -1826,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) {
@@ -1870,22 +1927,6 @@ public class SubscriptionManager {
return sDefaultSubIdCache.query(null); 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. * Returns the system's default voice subscription id.
* *
@@ -1972,19 +2013,7 @@ public class SubscriptionManager {
* @return the default SMS subscription Id. * @return the default SMS subscription Id.
*/ */
public static int getDefaultSmsSubscriptionId() { public static int getDefaultSmsSubscriptionId() {
int subId = INVALID_SUBSCRIPTION_ID; return sDefaultSmsSubIdCache.query(null);
try {
ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
subId = iSub.getDefaultSmsSubId();
}
} catch (RemoteException ex) {
// ignore it
}
if (VDBG) logd("getDefaultSmsSubscriptionId, sub id = " + subId);
return subId;
} }
/** /**
@@ -2039,22 +2068,6 @@ public class SubscriptionManager {
return sDefaultDataSubIdCache.query(null); 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 * 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 * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
@@ -3285,14 +3298,7 @@ public class SubscriptionManager {
* SubscriptionManager.INVALID_SUBSCRIPTION_ID if not. * SubscriptionManager.INVALID_SUBSCRIPTION_ID if not.
*/ */
public static int getActiveDataSubscriptionId() { public static int getActiveDataSubscriptionId() {
try { return sActiveDataSubIdCache.query(null);
ISub iSub = TelephonyManager.getSubscriptionService();
if (iSub != null) {
return iSub.getActiveDataSubscriptionId();
}
} catch (RemoteException ex) {
}
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
} }
/** /**
@@ -3320,13 +3326,45 @@ public class SubscriptionManager {
PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY); PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY);
} }
/** @hide */
public static void invalidateDefaultSmsSubIdCaches() {
PropertyInvalidatedCache.invalidateCache(CACHE_KEY_DEFAULT_SMS_SUB_ID_PROPERTY);
}
/** @hide */
public static void invalidateActiveDataSubIdCaches() {
PropertyInvalidatedCache.invalidateCache(CACHE_KEY_ACTIVE_DATA_SUB_ID_PROPERTY);
}
/** @hide */
public static void invalidateSlotIndexCaches() {
PropertyInvalidatedCache.invalidateCache(CACHE_KEY_SLOT_INDEX_PROPERTY);
}
/** /**
* Clears all process-local binder caches. * Allows a test process to disable client-side caching operations.
* *
* @hide * @hide
*/ */
public static void disableCaching() {
sDefaultSubIdCache.disableLocal();
sDefaultDataSubIdCache.disableLocal();
sActiveDataSubIdCache.disableLocal();
sDefaultSmsSubIdCache.disableLocal();
sSlotIndexCache.disableLocal();
sPhoneIdCache.disableLocal();
}
/**
* Clears all process-local binder caches.
*
* @hide */
public static void clearCaches() { public static void clearCaches() {
sDefaultSubIdCache.clear(); sDefaultSubIdCache.clear();
sDefaultDataSubIdCache.clear(); sDefaultDataSubIdCache.clear();
sActiveDataSubIdCache.clear();
sDefaultSmsSubIdCache.clear();
sSlotIndexCache.clear();
sPhoneIdCache.clear();
} }
} }