Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a131a0c6 authored by Collin Fijalkovich's avatar Collin Fijalkovich Committed by Android (Google) Code Review
Browse files

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
parents 9d3317b8 41f94629
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1121,6 +1121,7 @@ filegroup {
        "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",
+27 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.os.RemoteException;
import android.util.ExceptionUtils;

import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
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.
     *
+147 −109
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import com.android.internal.telephony.ISetOpportunisticDataCallback;
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;

@@ -139,23 +140,118 @@ public class SubscriptionManager {
    public static final String CACHE_KEY_DEFAULT_DATA_SUB_ID_PROPERTY =
            "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 PropertyInvalidatedCache<Void, Integer> sDefaultSubIdCache =
            new PropertyInvalidatedCache<Void, Integer>(
                    MAX_CACHE_SIZE, CACHE_KEY_DEFAULT_SUB_ID_PROPERTY) {
    private static class VoidPropertyInvalidatedCache<T>
            extends PropertyInvalidatedCache<Void, T> {
        private final FunctionalUtils.ThrowingFunction<ISub, T> mInterfaceMethod;
        private final String mCacheKeyProperty;
        private final T mDefaultValue;

        VoidPropertyInvalidatedCache(
                FunctionalUtils.ThrowingFunction<ISub, T> subscriptionInterfaceMethod,
                String cacheKeyProperty,
                T defaultValue) {
            super(MAX_CACHE_SIZE, cacheKeyProperty);
            mInterfaceMethod = subscriptionInterfaceMethod;
            mCacheKeyProperty = cacheKeyProperty;
            mDefaultValue = defaultValue;
        }

        @Override
            protected Integer recompute(Void query) {
                return getDefaultSubscriptionIdInternal();
            }};
        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;
        }

    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();
            }};
        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
@@ -1199,7 +1295,6 @@ public class SubscriptionManager {
        }

        return subInfo;

    }

    /**
@@ -1769,25 +1864,7 @@ public class SubscriptionManager {
     * subscriptionId doesn't have an associated slot index.
     */
    public static int getSlotIndex(int subscriptionId) {
        if (!isValidSubscriptionId(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;

        return sSlotIndexCache.query(subscriptionId);
    }

    /**
@@ -1826,27 +1903,7 @@ public class SubscriptionManager {
    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    public static int getPhoneId(int subId) {
        if (!isValidSubscriptionId(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;

        return sPhoneIdCache.query(subId);
    }

    private static void logd(String msg) {
@@ -1870,22 +1927,6 @@ public class SubscriptionManager {
        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.
     *
@@ -1972,19 +2013,7 @@ public class SubscriptionManager {
     * @return the default SMS subscription Id.
     */
    public static int getDefaultSmsSubscriptionId() {
        int subId = INVALID_SUBSCRIPTION_ID;

        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;
        return sDefaultSmsSubIdCache.query(null);
    }

    /**
@@ -2039,22 +2068,6 @@ public class SubscriptionManager {
        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
@@ -3285,14 +3298,7 @@ public class SubscriptionManager {
     * SubscriptionManager.INVALID_SUBSCRIPTION_ID if not.
     */
    public static int getActiveDataSubscriptionId() {
        try {
            ISub iSub = TelephonyManager.getSubscriptionService();
            if (iSub != null) {
                return iSub.getActiveDataSubscriptionId();
            }
        } catch (RemoteException ex) {
        }
        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        return sActiveDataSubIdCache.query(null);
    }

    /**
@@ -3320,13 +3326,45 @@ public class SubscriptionManager {
        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
     */
    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() {
        sDefaultSubIdCache.clear();
        sDefaultDataSubIdCache.clear();
        sActiveDataSubIdCache.clear();
        sDefaultSmsSubIdCache.clear();
        sSlotIndexCache.clear();
        sPhoneIdCache.clear();
    }
}