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

Commit 8dc42cb3 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5443223 from c182c2e8 to qt-release

Change-Id: I02849ef132622839f97aa1f18f7969e6a499a317
parents 1c974129 c182c2e8
Loading
Loading
Loading
Loading
+55 −5
Original line number Diff line number Diff line
@@ -237,6 +237,12 @@ public class SubscriptionController extends ISub.Stub {
            mLastISubServiceRegTime = System.currentTimeMillis();
        }

        /**
         * Switching between DSDS and single sim mode needs to clear the slot index of
         * subscription info.
         */
        clearSlotIndexForSubInfoRecords();

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

@@ -263,6 +269,25 @@ public class SubscriptionController extends ISub.Stub {
        return sSlotIndexToSubIds.size() > 0;
    }

    /**
     * Switching between DSDS and single sim mode needs to update the slot index of subscription
     * info into invalid if the slot index is not active.
     */
    private void clearSlotIndexForSubInfoRecords() {
        if (mTelephonyManager == null || mContext == null) {
            logel("[clearSlotIndexForSubInfoRecords] TelephonyManager or mContext is null");
            return;
        }
        int phoneCount = mTelephonyManager.getPhoneCount();

        // Update simInfo db with invalid slot index
        ContentResolver resolver = mContext.getContentResolver();
        ContentValues value = new ContentValues(1);
        value.put(SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX);
        mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI,
                value, SubscriptionManager.SIM_SLOT_INDEX + ">=" + phoneCount, null);
    }

    private SubscriptionController(Phone phone) {
        mContext = phone.getContext();
        mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -273,6 +298,12 @@ public class SubscriptionController extends ISub.Stub {

        migrateImsSettings();

        /**
         * Switching between DSDS and single sim mode needs to clear the slot index of
         * subscription info.
         */
        clearSlotIndexForSubInfoRecords();

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

@@ -514,6 +545,20 @@ public class SubscriptionController extends ISub.Stub {
        return null;
    }

    /**
     * Get a single subscription info record for a given subscription.
     *
     * @param subId the subId to query.
     *
     * @hide
     */
    public SubscriptionInfo getSubscriptionInfo(int subId) {
        List<SubscriptionInfo> subInfoList = getSubInfo(
                SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + subId, null);
        if (subInfoList == null || subInfoList.isEmpty()) return null;
        return subInfoList.get(0);
    }

    /**
     * Get the active SubscriptionInfo associated with the iccId
     * @param iccId the IccId of SIM card
@@ -1060,9 +1105,6 @@ public class SubscriptionController extends ISub.Stub {
                        if (value.size() > 0) {
                            resolver.update(SubscriptionManager.getUriForSubscriptionId(subId),
                                    value, null, null);

                            // Refresh the Cache of Active Subscription Info List
                            refreshCachedActiveSubscriptionInfoList();
                        }

                        if (DBG) logdl("[addSubInfoRecord] Record already exists");
@@ -1145,8 +1187,11 @@ public class SubscriptionController extends ISub.Stub {
                }
            }

            if (isSubscriptionForRemoteSim(subscriptionType)) {
            // Refresh the Cache of Active Subscription Info List. This should be done after
            // updating sSlotIndexToSubIds which is done through addToSubIdList() above.
            refreshCachedActiveSubscriptionInfoList();

            if (isSubscriptionForRemoteSim(subscriptionType)) {
                notifySubscriptionInfoChanged();
            } else {  // Handle Local SIM devices
                // Set Display name after sub id is set above so as to get valid simCarrierName
@@ -2344,7 +2389,12 @@ public class SubscriptionController extends ISub.Stub {
            simState = IccCardConstants.State.UNKNOWN;
            err = "invalid slotIndex";
        } else {
            Phone phone = PhoneFactory.getPhone(slotIndex);
            Phone phone = null;
            try {
                phone = PhoneFactory.getPhone(slotIndex);
            } catch (IllegalStateException e) {
                // ignore
            }
            if (phone == null) {
                simState = IccCardConstants.State.UNKNOWN;
                err = "phone == null";
+112 −2
Original line number Diff line number Diff line
@@ -32,12 +32,15 @@ import android.os.Handler;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.provider.Settings.SettingNotFoundException;
import android.service.carrier.CarrierService;
import android.service.euicc.EuiccProfileInfo;
import android.service.euicc.EuiccService;
import android.service.euicc.GetEuiccProfileInfoListResult;
@@ -90,6 +93,9 @@ public class SubscriptionInfoUpdater extends Handler {

    private static final String ICCID_STRING_FOR_NO_SIM = "";

    private static final ParcelUuid REMOVE_GROUP_UUID =
            ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING);

    // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED.
    public static final String CURR_SUBID = "curr_subid";

@@ -111,6 +117,8 @@ public class SubscriptionInfoUpdater extends Handler {
    private int mCurrentlyActiveUserId;
    private CarrierServiceBindHelper mCarrierServiceBindHelper;

    // TODO: The SubscriptionController instance should be passed in here from PhoneFactory
    // rather than invoking the static getter all over the place.
    public SubscriptionInfoUpdater(
            Looper looper, Context context, Phone[] phone, CommandsInterface[] ci) {
        this(looper, context, phone, ci,
@@ -512,8 +520,8 @@ public class SubscriptionInfoUpdater extends Handler {
    }

    private void updateCarrierServices(int slotId, String simState) {
        CarrierConfigManager configManager = (CarrierConfigManager)
                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
        CarrierConfigManager configManager =
                (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
        configManager.updateConfigForPhoneId(slotId, simState);
        mCarrierServiceBindHelper.updateForPhoneId(slotId, simState);
    }
@@ -753,6 +761,108 @@ public class SubscriptionInfoUpdater extends Handler {
        return hasChanges;
    }

    /**
     * Called by CarrierConfigLoader to update the subscription before sending a broadcast.
     */
    public void updateSubscriptionByCarrierConfigAndNotifyComplete(int phoneId,
            String configPackageName, PersistableBundle config, Message onComplete) {
        post(() -> {
            updateSubscriptionByCarrierConfig(phoneId, configPackageName, config);
            onComplete.sendToTarget();
        });
    }

    private String getDefaultCarrierServicePackageName() {
        CarrierConfigManager configManager =
                (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
        return configManager.getDefaultCarrierServicePackageName();
    }

    private boolean isCarrierServicePackage(int phoneId, String pkgName) {
        if (pkgName.equals(getDefaultCarrierServicePackageName())) return false;

        List<String> carrierPackageNames = TelephonyManager.from(mContext)
                .getCarrierPackageNamesForIntentAndPhone(
                        new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), phoneId);
        if (DBG) logd("Carrier Packages For Subscription = " + carrierPackageNames);
        return carrierPackageNames != null && carrierPackageNames.contains(pkgName);
    }

    /**
     * Update the currently active Subscription based on information from CarrierConfig
     */
    @VisibleForTesting
    public void updateSubscriptionByCarrierConfig(
            int phoneId, String configPackageName, PersistableBundle config) {
        if (!SubscriptionManager.isValidPhoneId(phoneId)
                || TextUtils.isEmpty(configPackageName) || config == null) {
            if (DBG) {
                logd("In updateSubscriptionByCarrierConfig(): phoneId=" + phoneId
                        + " configPackageName=" + configPackageName + " config="
                        + ((config == null) ? "null" : config.hashCode()));
            }
            return;
        }

        SubscriptionController sc = SubscriptionController.getInstance();
        if (sc == null) {
            loge("SubscriptionController was null");
            return;
        }

        int currentSubId = sc.getSubIdUsingPhoneId(phoneId);
        if (!SubscriptionManager.isValidSubscriptionId(currentSubId)
                || currentSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
            if (DBG) logd("No subscription is active for phone being updated");
            return;
        }

        SubscriptionInfo currentSubInfo = sc.getSubscriptionInfo(currentSubId);
        if (currentSubInfo == null) {
            loge("Couldn't retrieve subscription info for current subscription");
            return;
        }

        if (!isCarrierServicePackage(phoneId, configPackageName)) {
            loge("Cannot manage subId=" + currentSubId + ", carrierPackage=" + configPackageName);
            return;
        }

        ContentValues cv = new ContentValues();
        boolean isOpportunistic = config.getBoolean(
                CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, false);
        if (currentSubInfo.isOpportunistic() != isOpportunistic) {
            if (DBG) logd("Set SubId=" + currentSubId + " isOpportunistic=" + isOpportunistic);
            cv.put(SubscriptionManager.IS_OPPORTUNISTIC, isOpportunistic ? "1" : "0");
        }

        String groupUuidString =
                config.getString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, "");
        ParcelUuid groupId = null;
        if (!TextUtils.isEmpty(groupUuidString)) {
            try {
                // Update via a UUID Structure to ensure consistent formatting
                ParcelUuid groupUuid = ParcelUuid.fromString(groupUuidString);
                if (groupUuid.equals(REMOVE_GROUP_UUID)
                            && currentSubInfo.getGroupUuid() != null) {
                    cv.put(SubscriptionManager.GROUP_UUID, (String) null);
                    if (DBG) logd("Group Removed for" + currentSubId);
                } else {
                    // TODO: validate and update group owner information once feasible.
                    cv.put(SubscriptionManager.GROUP_UUID, groupUuid.toString());
                    if (DBG) logd("Group Added for" + currentSubId);
                }
            } catch (IllegalArgumentException e) {
                loge("Invalid Group UUID=" + groupUuidString);
            }
        }
        if (cv.size() > 0 && mContext.getContentResolver().update(SubscriptionManager
                    .getUriForSubscriptionId(currentSubId), cv, null, null) > 0) {
            sc.refreshCachedActiveSubscriptionInfoList();
            sc.notifySubscriptionInfoChanged();
        }
    }

    private static int findSubscriptionInfoForIccid(List<SubscriptionInfo> list, String iccid) {
        for (int i = 0; i < list.size(); i++) {
            if (TextUtils.equals(iccid, list.get(i).getIccId())) {
+11 −0
Original line number Diff line number Diff line
@@ -233,6 +233,11 @@ public class DataConnection extends StateMachine {

    int mTag;
    public int mCid;
    /**
     * Indicate this data connection has been transferred to the other transport type during
     * IWLAN and WWAN handover.
     */
    private boolean mHasTransferred;
    private final Map<ApnContext, ConnectionParams> mApnContexts = new ConcurrentHashMap<>();
    PendingIntent mReconnectIntent = null;

@@ -366,6 +371,10 @@ public class DataConnection extends StateMachine {
        return getCurrentState() == mActivatingState;
    }

    boolean hasBeenTransferred() {
        return mHasTransferred;
    }

    int getCid() {
        return mCid;
    }
@@ -1706,6 +1715,7 @@ public class DataConnection extends StateMachine {
                    mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L,
                    mApnSetting != null
                        ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false);
            mHasTransferred = false;
        }
        @Override
        public boolean processMessage(Message msg) {
@@ -2882,6 +2892,7 @@ public class DataConnection extends StateMachine {
    public DcNetworkAgent transferNetworkAgent(DataConnection dataConnection,
                                               @TransportType int transportType) {
        mNetworkAgent.acquireOwnership(dataConnection, transportType);
        this.mHasTransferred = true;
        return mNetworkAgent;
    }

+11 −3
Original line number Diff line number Diff line
@@ -2919,9 +2919,17 @@ public class DcTracker extends Handler {
    private void onDisconnectDone(ApnContext apnContext) {
        if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
        apnContext.setState(DctConstants.State.IDLE);

        mPhone.notifyDataConnection(apnContext.getApnType());

        final DataConnection dc = apnContext.getDataConnection();
        // when data connection is gone and not for handover, notify all apn types which
        // this data connection can handle. Note, this might not work if one apn type served for
        // multiple data connection.
        if (dc != null && dc.isInactive() && !dc.hasBeenTransferred()) {
            String[] types = ApnSetting.getApnTypesStringFromBitmask(
                    apnContext.getApnSetting().getApnTypeBitmask()).split(",");
            for (String type : types) {
                mPhone.notifyDataConnection(type);
            }
        }
        // if all data connection are gone, check whether Airplane mode request was
        // pending.
        if (isDisconnected()) {
+126 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.any;
@@ -40,6 +41,8 @@ import android.content.pm.IPackageManager;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.HandlerThread;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
import android.service.euicc.EuiccProfileInfo;
import android.service.euicc.EuiccService;
import android.service.euicc.GetEuiccProfileInfoListResult;
@@ -64,6 +67,7 @@ import org.mockito.stubbing.Answer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

@@ -571,4 +575,126 @@ public class SubscriptionInfoUpdaterTest extends TelephonyTest {
                eq(FAKE_SUB_ID_1));
        verify(mSubscriptionController, times(0)).clearSubInfo();
    }

    PersistableBundle getCarrierConfigForSubInfoUpdate(
            boolean isOpportunistic, String groupUuid) {
        PersistableBundle p = new PersistableBundle();
        p.putBoolean(CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, isOpportunistic);
        p.putString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, groupUuid);
        return p;
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigOpportunisticUnchanged() throws Exception {
        final int phoneId = mPhone.getPhoneId();
        String carrierPackageName = "FakeCarrierPackageName";

        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
        ((MockContentResolver) mContext.getContentResolver()).addProvider(
                SubscriptionManager.CONTENT_URI.getAuthority(),
                new FakeSubscriptionContentProvider());

        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
                carrierPackageName, new PersistableBundle());

        verify(mContentProvider, never()).update(any(), any(), any(), any());
        verify(mSubscriptionController, never()).refreshCachedActiveSubscriptionInfoList();
        verify(mSubscriptionController, never()).notifySubscriptionInfoChanged();
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigOpportunisticSetOpportunistic() throws Exception {
        final int phoneId = mPhone.getPhoneId();
        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate(
                true, "");
        String carrierPackageName = "FakeCarrierPackageName";

        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
        doReturn(false).when(mSubInfo).isOpportunistic();
        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
        ((MockContentResolver) mContext.getContentResolver()).addProvider(
                SubscriptionManager.CONTENT_URI.getAuthority(),
                new FakeSubscriptionContentProvider());

        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
                carrierPackageName, carrierConfig);

        ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class);
        verify(mContentProvider, times(1)).update(
                eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)),
                cvCaptor.capture(), eq(null), eq(null));
        assertEquals(1, cvCaptor.getValue().getAsInteger(
                SubscriptionManager.IS_OPPORTUNISTIC).intValue());
        assertEquals(1, cvCaptor.getValue().size());
        verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList();
        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigOpportunisticAddToGroup() throws Exception {
        final int phoneId = mPhone.getPhoneId();
        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate(
                true, "11111111-2222-3333-4444-555555555555");
        String carrierPackageName = "FakeCarrierPackageName";

        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
        ((MockContentResolver) mContext.getContentResolver()).addProvider(
                SubscriptionManager.CONTENT_URI.getAuthority(),
                new FakeSubscriptionContentProvider());

        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
                carrierPackageName, carrierConfig);

        ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class);
        verify(mContentProvider, times(1)).update(
                eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)),
                cvCaptor.capture(), eq(null), eq(null));
        assertEquals(1, cvCaptor.getValue().getAsInteger(
                SubscriptionManager.IS_OPPORTUNISTIC).intValue());
        assertEquals("11111111-2222-3333-4444-555555555555",
                cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID));
        assertEquals(2, cvCaptor.getValue().size());
    }

    @Test
    @SmallTest
    public void testUpdateFromCarrierConfigOpportunisticRemoveFromGroup() throws Exception {
        final int phoneId = mPhone.getPhoneId();
        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate(
                true, "00000000-0000-0000-0000-000000000000");
        String carrierPackageName = "FakeCarrierPackageName";

        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
        doReturn(ParcelUuid.fromString("11111111-2222-3333-4444-555555555555"))
            .when(mSubInfo).getGroupUuid();
        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
        ((MockContentResolver) mContext.getContentResolver()).addProvider(
                SubscriptionManager.CONTENT_URI.getAuthority(),
                new FakeSubscriptionContentProvider());

        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
                carrierPackageName, carrierConfig);

        ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class);
        verify(mContentProvider, times(1)).update(
                eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)),
                cvCaptor.capture(), eq(null), eq(null));
        assertEquals(1, cvCaptor.getValue().getAsInteger(
                SubscriptionManager.IS_OPPORTUNISTIC).intValue());
        assertNull(cvCaptor.getValue().getAsString(SubscriptionManager.GROUP_UUID));
        assertEquals(2, cvCaptor.getValue().size());
    }
}