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

Commit 55aebbc1 authored by Collin Fijalkovich's avatar Collin Fijalkovich
Browse files

Setup getDefaultSubscriptionId cache invalidation

Instrument SubscriptionController to trigger
invalidation of getDefaultSubscriptId caches when necessary.
Bug: 151953109
Test: atest SubscriptionControllerTest
Test: atest android.telephony.cts.SubscriptionManagerTest

Merged-In: Ia7fbc39f248ae0d6ed100d3bd0b6e1b73cb808e9
Change-Id: Ia7fbc39f248ae0d6ed100d3bd0b6e1b73cb808e9
parent 9b4cc323
Loading
Loading
Loading
Loading
+170 −34
Original line number Diff line number Diff line
@@ -112,6 +112,9 @@ public class SubscriptionController extends ISub.Stub {
    private static final ParcelUuid INVALID_GROUP_UUID =
            ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING);
    private final LocalLog mLocalLog = new LocalLog(200);
    private static final int SUB_ID_FOUND = 1;
    private static final int NO_ENTRY_FOR_SLOT_INDEX = -1;
    private static final int SUB_ID_NOT_IN_SLOT = -2;

    // Lock that both mCacheActiveSubInfoList and mCacheOpportunisticSubInfoList use.
    private Object mSubInfoListLock = new Object();
@@ -146,9 +149,114 @@ public class SubscriptionController extends ISub.Stub {

    private AppOpsManager mAppOps;

    // Allows test mocks to avoid SELinux failures on invalidate calls.
    private static boolean sCachingEnabled = true;

    // Each slot can have multiple subs.
    private static Map<Integer, ArrayList<Integer>> sSlotIndexToSubIds = new ConcurrentHashMap<>();
    protected static int mDefaultFallbackSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private static class WatchedSlotIndexToSubIds {
        private Map<Integer, ArrayList<Integer>> mSlotIndexToSubIds = new ConcurrentHashMap<>();

        WatchedSlotIndexToSubIds() {
        }

        public void clear() {
            mSlotIndexToSubIds.clear();
            invalidateDefaultSubIdCaches();
        }

        public Set<Entry<Integer, ArrayList<Integer>>> entrySet() {
            return mSlotIndexToSubIds.entrySet();
        }

        // Force all updates to data structure through wrapper.
        public ArrayList<Integer> getCopy(int slotIndex) {
            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
            if (subIdList == null) {
                return null;
            }

            return new ArrayList<Integer>(subIdList);
        }

        public void put(int slotIndex, ArrayList<Integer> value) {
            mSlotIndexToSubIds.put(slotIndex, value);
            invalidateDefaultSubIdCaches();
        }

        public void remove(int slotIndex) {
            mSlotIndexToSubIds.remove(slotIndex);
            invalidateDefaultSubIdCaches();
        }

        public int size() {
            return mSlotIndexToSubIds.size();
        }

        @VisibleForTesting
        public Map<Integer, ArrayList<Integer>> getMap() {
            return mSlotIndexToSubIds;
        }

        public int removeFromSubIdList(int slotIndex, int subId) {
            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
            if (subIdList == null) {
                return NO_ENTRY_FOR_SLOT_INDEX;
            } else {
                if (subIdList.contains(subId)) {
                    subIdList.remove(new Integer(subId));
                    if (subIdList.isEmpty()) {
                        mSlotIndexToSubIds.remove(slotIndex);
                    }
                    invalidateDefaultSubIdCaches();
                    return SUB_ID_FOUND;
                } else {
                    return SUB_ID_NOT_IN_SLOT;
                }
            }
        }

        public void addToSubIdList(int slotIndex, Integer value) {
            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
            if (subIdList == null) {
                subIdList = new ArrayList<Integer>();
                subIdList.add(value);
                mSlotIndexToSubIds.put(slotIndex, subIdList);
            } else {
                subIdList.add(value);
            }
            invalidateDefaultSubIdCaches();
        }

        public void clearSubIdList(int slotIndex) {
            ArrayList<Integer> subIdList = mSlotIndexToSubIds.get(slotIndex);
            if (subIdList != null) {
                subIdList.clear();
                invalidateDefaultSubIdCaches();
            }
        }
    }

    protected static class WatchedInt {
        private int mValue;

        public WatchedInt(int initialValue) {
            mValue = initialValue;
        }

        public int get() {
            return mValue;
        }

        public void set(int newValue) {
            mValue = newValue;
            invalidateDefaultSubIdCaches();
        }
    }

    private static WatchedSlotIndexToSubIds sSlotIndexToSubIds = new WatchedSlotIndexToSubIds();
    protected static WatchedInt sDefaultFallbackSubId =
            new WatchedInt(SubscriptionManager.INVALID_SUBSCRIPTION_ID);

    @UnsupportedAppUsage
    private static int mDefaultPhoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;

@@ -222,6 +330,9 @@ public class SubscriptionController extends ISub.Stub {
        // Cache Setting values
        cacheSettingValues();

        // Initial invalidate activates caching.
        invalidateDefaultSubIdCaches();

        if (DBG) logdl("[SubscriptionController] init by Context");
    }

@@ -1327,7 +1438,7 @@ public class SubscriptionController extends ISub.Stub {
        if (!isActiveSubscriptionId(getDefaultSubId())) {
            // current default is not valid anylonger. set a new default
            if (DBG) {
                logdl("[updateDefaultSubIdsIfNeeded] set mDefaultFallbackSubId=" + newDefault);
                logdl("[updateDefaultSubIdsIfNeeded] set sDefaultFallbackSubId=" + newDefault);
            }
            setDefaultFallbackSubId(newDefault, subscriptionType);
        }
@@ -1411,22 +1522,13 @@ public class SubscriptionController extends ISub.Stub {
                return -1;
            }
            refreshCachedActiveSubscriptionInfoList();

            // update sSlotIndexToSubIds struct
            ArrayList<Integer> subIdsList = sSlotIndexToSubIds.get(slotIndex);
            if (subIdsList == null) {
            result = sSlotIndexToSubIds.removeFromSubIdList(slotIndex, subId);
            if (result == NO_ENTRY_FOR_SLOT_INDEX) {
                loge("sSlotIndexToSubIds has no entry for slotIndex = " + slotIndex);
            } else {
                if (subIdsList.contains(subId)) {
                    subIdsList.remove(new Integer(subId));
                    if (subIdsList.isEmpty()) {
                        sSlotIndexToSubIds.remove(slotIndex);
                    }
                } else {
                    loge("sSlotIndexToSubIds has no subid: " + subId
                            + ", in index: " + slotIndex);
                }
            } else if (result == SUB_ID_NOT_IN_SLOT) {
                loge("sSlotIndexToSubIds has no subid: " + subId + ", in index: " + slotIndex);
            }

            // Since a subscription is removed, if this one is set as default for any setting,
            // set some other subid as the default.
            int newDefault = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -2142,7 +2244,7 @@ public class SubscriptionController extends ISub.Stub {
        }

        // Convert ArrayList to array
        ArrayList<Integer> subIds = sSlotIndexToSubIds.get(slotIndex);
        ArrayList<Integer> subIds = sSlotIndexToSubIds.getCopy(slotIndex);
        if (subIds != null && subIds.size() > 0) {
            int[] subIdArr = new int[subIds.size()];
            for (int i = 0; i < subIds.size(); i++) {
@@ -2269,7 +2371,7 @@ public class SubscriptionController extends ISub.Stub {
            if (VDBG) logdl("[getDefaultSubId] NOT VoiceCapable subId=" + subId);
        }
        if (!isActiveSubId(subId)) {
            subId = mDefaultFallbackSubId;
            subId = sDefaultFallbackSubId.get();
            if (VDBG) logdl("[getDefaultSubId] NOT active use fall back subId=" + subId);
        }
        if (VDBG) logv("[getDefaultSubId]- value = " + subId);
@@ -2285,8 +2387,7 @@ public class SubscriptionController extends ISub.Stub {
            throw new RuntimeException("setDefaultSmsSubId called with DEFAULT_SUB_ID");
        }
        if (DBG) logdl("[setDefaultSmsSubId] subId=" + subId);
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION, subId);
        setGlobalSetting(Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION, subId);
        broadcastDefaultSmsSubIdChanged(subId);
    }

@@ -2321,8 +2422,7 @@ public class SubscriptionController extends ISub.Stub {

        int previousDefaultSub = getDefaultSubId();

        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION, subId);
        setGlobalSetting(Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION, subId);
        broadcastDefaultVoiceSubIdChanged(subId);

        PhoneAccountHandle newHandle =
@@ -2422,8 +2522,7 @@ public class SubscriptionController extends ISub.Stub {
            }

            int previousDefaultSub = getDefaultSubId();
            Settings.Global.putInt(mContext.getContentResolver(),
                    Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION, subId);
            setGlobalSetting(Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION, subId);
            MultiSimSettingController.getInstance().notifyDefaultDataSubChanged();
            broadcastDefaultDataSubIdChanged(subId);
            if (previousDefaultSub != getDefaultSubId()) {
@@ -2459,15 +2558,15 @@ public class SubscriptionController extends ISub.Stub {
        }
        int previousDefaultSub = getDefaultSubId();
        if (isSubscriptionForRemoteSim(subscriptionType)) {
            mDefaultFallbackSubId = subId;
            sDefaultFallbackSubId.set(subId);
            return;
        }
        if (SubscriptionManager.isValidSubscriptionId(subId)) {
            int phoneId = getPhoneId(subId);
            if (phoneId >= 0 && (phoneId < mTelephonyManager.getPhoneCount()
                    || mTelephonyManager.getSimCount() == 1)) {
                if (DBG) logdl("[setDefaultFallbackSubId] set mDefaultFallbackSubId=" + subId);
                mDefaultFallbackSubId = subId;
                if (DBG) logdl("[setDefaultFallbackSubId] set sDefaultFallbackSubId=" + subId);
                sDefaultFallbackSubId.set(subId);
                // Update MCC MNC device configuration information
                String defaultMccMnc = mTelephonyManager.getSimOperatorNumericForPhone(phoneId);
                MccTable.updateMccMncConfiguration(mContext, defaultMccMnc);
@@ -3763,7 +3862,7 @@ public class SubscriptionController extends ISub.Stub {
    }

    private synchronized boolean addToSubIdList(int slotIndex, int subId, int subscriptionType) {
        ArrayList<Integer> subIdsList = sSlotIndexToSubIds.get(slotIndex);
        ArrayList<Integer> subIdsList = sSlotIndexToSubIds.getCopy(slotIndex);
        if (subIdsList == null) {
            subIdsList = new ArrayList<>();
            sSlotIndexToSubIds.put(slotIndex, subIdsList);
@@ -3776,11 +3875,11 @@ public class SubscriptionController extends ISub.Stub {
        }
        if (isSubscriptionForRemoteSim(subscriptionType)) {
            // For Remote SIM subscriptions, a slot can have multiple subscriptions.
            subIdsList.add(subId);
            sSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
        } else {
            // for all other types of subscriptions, a slot can have only one subscription at a time
            subIdsList.clear();
            subIdsList.add(subId);
            sSlotIndexToSubIds.clearSubIdList(slotIndex);
            sSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
        }
        if (DBG) logdl("slotIndex, subId combo is added to the map.");
        return true;
@@ -3796,7 +3895,7 @@ public class SubscriptionController extends ISub.Stub {
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public Map<Integer, ArrayList<Integer>> getSlotIndexToSubIdsMap() {
        return sSlotIndexToSubIds;
        return sSlotIndexToSubIds.getMap();
    }

    /**
@@ -3805,7 +3904,7 @@ public class SubscriptionController extends ISub.Stub {
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public void resetStaticMembers() {
        mDefaultFallbackSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        sDefaultFallbackSubId.set(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
        mDefaultPhoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
    }

@@ -3949,4 +4048,41 @@ public class SubscriptionController extends ISub.Stub {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
     * @hide
     */
    private void setGlobalSetting(String name, int value) {
        Settings.Global.putInt(mContext.getContentResolver(), name, value);
        if (name == Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION
                 || name == Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION) {
            invalidateDefaultSubIdCaches();
        }
    }

    /**
     * @hide
     */
    private static void invalidateDefaultSubIdCaches() {
        if (sCachingEnabled) {
            SubscriptionManager.invalidateDefaultSubIdCaches();
        }
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static void disableCaching() {
        sCachingEnabled = false;
    }

    /**
     * @hide
     */
    public static void enableCaching() {
        sCachingEnabled = true;
    }


}
+3 −5
Original line number Diff line number Diff line
@@ -16,15 +16,13 @@

package com.android.internal.telephony.vendor;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.Manifest;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -37,8 +35,8 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.SubscriptionController;

import java.util.Iterator;
import java.util.List;
@@ -244,7 +242,7 @@ public class VendorSubscriptionController extends SubscriptionController {
            logi("set default phoneaccount to  " + subId);
            mTelecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccountHandle);
        }
        if (!isSubProvisioned(mDefaultFallbackSubId)) {
        if (!isSubProvisioned(sDefaultFallbackSubId.get())) {
            setDefaultFallbackSubId(mNextActivatedSub.getSubscriptionId(),
                SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM);
        }
+2 −0
Original line number Diff line number Diff line
@@ -399,6 +399,7 @@ public abstract class TelephonyTest {
        TAG = tag;
        MockitoAnnotations.initMocks(this);
        TelephonyManager.disableServiceHandleCaching();
        SubscriptionController.disableCaching();

        mPhones = new Phone[] {mPhone};
        mImsCallProfile = new ImsCallProfile();
@@ -674,6 +675,7 @@ public abstract class TelephonyTest {

        restoreInstances();
        TelephonyManager.enableServiceHandleCaching();
        SubscriptionController.enableCaching();
    }

    protected static void logd(String s) {