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

Commit e024878d authored by Xiangyu/Malcolm Chen's avatar Xiangyu/Malcolm Chen Committed by Gerrit Code Review
Browse files

Merge changes I750aa18b,Ic008f6ee,Ib4268fc2

* changes:
  Don't store sPhones in SubscriptionInfoUpdater.
  Upon dual-SIM -> single-SIM switch, auto set default subs.
  Bind or unbind Network and Data service upon multi-SIM config change.
parents 1f8221ea 73f5e92c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_T
import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_DUAL_CDMA;
import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE;
import static android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID;
import static android.telephony.TelephonyManager.MODEM_COUNT_SINGLE_MODEM;

import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -473,7 +474,9 @@ public class MultiSimSettingController extends Handler {
        // Otherwise, if user just inserted their first SIM, or there's one primary and one
        // opportunistic subscription active (activeSubInfos.size() > 1), we automatically
        // set the primary to be default SIM and return.
        if (mPrimarySubList.size() == 1 && change != PRIMARY_SUB_REMOVED) {
        if (mPrimarySubList.size() == 1 && (change != PRIMARY_SUB_REMOVED
                || ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE))
                .getActiveModemCount() == MODEM_COUNT_SINGLE_MODEM)) {
            int subId = mPrimarySubList.get(0);
            if (DBG) log("[updateDefaultValues] to only primary sub " + subId);
            mSubController.setDefaultDataSubId(subId);
+45 −21
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.telephony.INetworkServiceCallback;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkService;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;

import java.util.Hashtable;
@@ -100,6 +101,9 @@ public class NetworkRegistrationManager extends Handler {
        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        phone.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
                intentFilter, null, null);
        PhoneConfigurationManager.registerForMultiSimConfigChange(
                this, EVENT_BIND_NETWORK_SERVICE, null);

        sendEmptyMessage(EVENT_BIND_NETWORK_SERVICE);
    }

@@ -112,7 +116,7 @@ public class NetworkRegistrationManager extends Handler {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case EVENT_BIND_NETWORK_SERVICE:
                bindService();
                rebindService();
                break;
            default:
                loge("Unhandled event " + msg.what);
@@ -231,15 +235,38 @@ public class NetworkRegistrationManager extends Handler {
        }
    }

    private void bindService() {
        Intent intent = null;
        String packageName = getPackageName();
        String className = getClassName();
    private void unbindService() {
        if (mINetworkService != null && mINetworkService.asBinder().isBinderAlive()) {
            logd("unbinding service");
            // Remove the network availability updater and then unbind the service.
            try {
                mINetworkService.removeNetworkServiceProvider(mPhone.getPhoneId());
            } catch (RemoteException e) {
                loge("Cannot remove data service provider. " + e);
            }
        }

        if (mServiceConnection != null) {
            mPhone.getContext().unbindService(mServiceConnection);
        }
        mINetworkService = null;
        mServiceConnection = null;
        mTargetBindingPackageName = null;
    }

    private void bindService(String packageName) {
        if (mPhone == null || !SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())) {
            loge("can't bindService with invalid phone or phoneId.");
            return;
        }

        if (TextUtils.isEmpty(packageName)) {
            loge("Can't find the binding package");
            return;
        }

        Intent intent = null;
        String className = getClassName();
        if (TextUtils.isEmpty(className)) {
            intent = new Intent(NetworkService.SERVICE_INTERFACE);
            intent.setPackage(packageName);
@@ -248,22 +275,6 @@ public class NetworkRegistrationManager extends Handler {
            intent = new Intent(NetworkService.SERVICE_INTERFACE).setComponent(cm);
        }

        if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
            logd("Service " + packageName + " already bound or being bound.");
            return;
        }

        if (mINetworkService != null && mINetworkService.asBinder().isBinderAlive()) {
            // Remove the network availability updater and then unbind the service.
            try {
                mINetworkService.removeNetworkServiceProvider(mPhone.getPhoneId());
            } catch (RemoteException e) {
                loge("Cannot remove data service provider. " + e);
            }

            mPhone.getContext().unbindService(mServiceConnection);
        }

        try {
            // We bind this as a foreground service because it is operating directly on the SIM,
            // and we do not want it subjected to power-savings restrictions while doing so.
@@ -281,6 +292,19 @@ public class NetworkRegistrationManager extends Handler {
        }
    }

    private void rebindService() {
        String packageName = getPackageName();
        // Do nothing if no need to rebind.
        if (SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())
                && TextUtils.equals(packageName, mTargetBindingPackageName)) {
            logd("Service " + packageName + " already bound or being bound.");
            return;
        }

        unbindService();
        bindService(packageName);
    }

    private String getPackageName() {
        String packageName;
        int resourceId;
+1 −1
Original line number Diff line number Diff line
@@ -218,7 +218,7 @@ public class PhoneFactory {

                Rlog.i(LOG_TAG, "Creating SubInfoRecordUpdater ");
                sSubInfoRecordUpdater = new SubscriptionInfoUpdater(
                        BackgroundThread.get().getLooper(), context, sPhones, sCommandsInterfaces);
                        BackgroundThread.get().getLooper(), context, sCommandsInterfaces);
                sc.updatePhonesAvailability(sPhones);

                // Only bring up IMS if the device supports having an IMS stack.
+15 −19
Original line number Diff line number Diff line
@@ -103,8 +103,6 @@ public class SubscriptionInfoUpdater extends Handler {
    // Key used to read/write the current IMSI. Updated on SIM_STATE_CHANGED - LOADED.
    public static final String CURR_SUBID = "curr_subid";

    @UnsupportedAppUsage
    private static Phone[] sPhones;
    @UnsupportedAppUsage
    private static Context sContext = null;
    @UnsupportedAppUsage
@@ -140,19 +138,17 @@ public class SubscriptionInfoUpdater extends Handler {
    // 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,
                IPackageManager.Stub.asInterface(ServiceManager.getService("package")));
            Looper looper, Context context, CommandsInterface[] ci) {
        this(looper, context, ci, IPackageManager.Stub.asInterface(
                ServiceManager.getService("package")));
    }

    @VisibleForTesting public SubscriptionInfoUpdater(
            Looper looper, Context context, Phone[] phone,
    @VisibleForTesting public SubscriptionInfoUpdater(Looper looper, Context context,
            CommandsInterface[] ci, IPackageManager packageMgr) {
        logd("Constructor invoked");
        mBackgroundHandler = new Handler(looper);

        sContext = context;
        sPhones = phone;
        mSubscriptionManager = SubscriptionManager.from(sContext);
        mEuiccManager = (EuiccManager) sContext.getSystemService(Context.EUICC_SERVICE);
        mPackageManager = packageMgr;
@@ -256,7 +252,7 @@ public class SubscriptionInfoUpdater extends Handler {
                if (ar.exception == null && ar.result != null) {
                    int[] modes = (int[])ar.result;
                    if (modes[0] == 1) {  // Manual mode.
                        sPhones[slotId].setNetworkSelectionModeAutomatic(null);
                        PhoneFactory.getPhone(slotId).setNetworkSelectionModeAutomatic(null);
                    }
                } else {
                    logd("EVENT_GET_NETWORK_SELECTION_MODE_DONE: error getting network mode.");
@@ -367,7 +363,7 @@ public class SubscriptionInfoUpdater extends Handler {

        String iccId = sIccId[slotId];
        if (iccId == null) {
            IccCard iccCard = sPhones[slotId].getIccCard();
            IccCard iccCard = PhoneFactory.getPhone(slotId).getIccCard();
            if (iccCard == null) {
                logd("handleSimLocked: IccCard null");
                return;
@@ -414,7 +410,7 @@ public class SubscriptionInfoUpdater extends Handler {
    private void handleSimNotReady(int slotId) {
        logd("handleSimNotReady: slotId: " + slotId);

        IccCard iccCard = sPhones[slotId].getIccCard();
        IccCard iccCard = PhoneFactory.getPhone(slotId).getIccCard();
        if (iccCard.isEmptyProfile()) {
            // ICC_NOT_READY is a terminal state for an eSIM on the boot profile. At this
            // phase, the subscription list is accessible. Treating NOT_READY
@@ -436,7 +432,7 @@ public class SubscriptionInfoUpdater extends Handler {
        // removed or a refresh RESET that the IccRecords could be null. The right behavior is to
        // not broadcast the SIM loaded.
        int loadedSlotId = slotId;
        IccCard iccCard = sPhones[slotId].getIccCard();
        IccCard iccCard = PhoneFactory.getPhone(slotId).getIccCard();
        if (iccCard == null) {  // Possibly a race condition.
            logd("handleSimLoaded: IccCard null");
            return;
@@ -506,7 +502,7 @@ public class SubscriptionInfoUpdater extends Handler {

                if (storedSubId != subId) {
                    int networkType = Settings.Global.getInt(
                            sPhones[slotId].getContext().getContentResolver(),
                            PhoneFactory.getPhone(slotId).getContext().getContentResolver(),
                            Settings.Global.PREFERRED_NETWORK_MODE + subId,
                            -1 /* invalid network mode */);

@@ -521,16 +517,16 @@ public class SubscriptionInfoUpdater extends Handler {
                                    + "Settings.Global.PREFERRED_NETWORK_MODE");
                        }
                        Settings.Global.putInt(
                                sPhones[slotId].getContext().getContentResolver(),
                                PhoneFactory.getPhone(slotId).getContext().getContentResolver(),
                                Global.PREFERRED_NETWORK_MODE + subId,
                                networkType);
                    }

                    // Set the modem network mode
                    sPhones[slotId].setPreferredNetworkType(networkType, null);
                    PhoneFactory.getPhone(slotId).setPreferredNetworkType(networkType, null);

                    // Only support automatic selection mode on SIM change.
                    sPhones[slotId].getNetworkSelectionMode(
                    PhoneFactory.getPhone(slotId).getNetworkSelectionMode(
                            obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE,
                                    new Integer(slotId)));

@@ -570,8 +566,8 @@ public class SubscriptionInfoUpdater extends Handler {
    }

    private void updateSubscriptionCarrierId(int slotId, String simState) {
        if (sPhones != null && sPhones[slotId] != null) {
            sPhones[slotId].resolveSubscriptionCarrierId(simState);
        if (PhoneFactory.getPhone(slotId) != null) {
            PhoneFactory.getPhone(slotId).resolveSubscriptionCarrierId(simState);
        }
    }

@@ -1103,7 +1099,7 @@ public class SubscriptionInfoUpdater extends Handler {
        boolean isUnknownToNotReady =
                (sSimApplicationState[phoneId] == TelephonyManager.SIM_STATE_UNKNOWN
                        && state == TelephonyManager.SIM_STATE_NOT_READY);
        IccCard iccCard = sPhones[phoneId].getIccCard();
        IccCard iccCard = PhoneFactory.getPhone(phoneId).getIccCard();
        boolean emptyProfile = iccCard != null && iccCard.isEmptyProfile();
        if (state != sSimApplicationState[phoneId] && (!isUnknownToNotReady || emptyProfile)) {
            sSimApplicationState[phoneId] = state;
+50 −26
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
@@ -53,6 +54,7 @@ import android.telephony.data.IDataServiceCallback;
import android.text.TextUtils;

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConfigurationManager;

import java.util.HashSet;
import java.util.List;
@@ -285,8 +287,10 @@ public class DataServiceManager extends Handler {

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
        phone.getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
                intentFilter, null, null);

        PhoneConfigurationManager.registerForMultiSimConfigChange(
                this, EVENT_BIND_DATA_SERVICE, null);

        sendEmptyMessage(EVENT_BIND_DATA_SERVICE);
    }

@@ -299,7 +303,7 @@ public class DataServiceManager extends Handler {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case EVENT_BIND_DATA_SERVICE:
                bindDataService();
                rebindDataService();
                break;
            case EVENT_WATCHDOG_TIMEOUT:
                handleRequestUnresponded((CellularDataServiceCallback) msg.obj);
@@ -320,41 +324,48 @@ public class DataServiceManager extends Handler {
                message);
    }

    private void bindDataService() {
        Intent intent = null;
        String packageName = getDataServicePackageName();
        String className = getDataServiceClassName();
        if (TextUtils.isEmpty(packageName)) {
            loge("Can't find the binding package");
            return;
        }

        if (TextUtils.isEmpty(className)) {
            intent = new Intent(DataService.SERVICE_INTERFACE);
            intent.setPackage(packageName);
        } else {
            ComponentName cm = new ComponentName(packageName, className);
            intent = new Intent(DataService.SERVICE_INTERFACE).setComponent(cm);
        }

        if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
            if (DBG) log("Service " + packageName + " already bound or being bound.");
            return;
        }

    private void unbindDataService() {
        // Start by cleaning up all packages that *shouldn't* have permissions.
        revokePermissionsFromUnusedDataServices();

        if (mIDataService != null && mIDataService.asBinder().isBinderAlive()) {
            log("unbinding service");
            // Remove the network availability updater and then unbind the service.
            try {
                mIDataService.removeDataServiceProvider(mPhone.getPhoneId());
            } catch (RemoteException e) {
                loge("Cannot remove data service provider. " + e);
            }
        }

        if (mServiceConnection != null) {
            mPhone.getContext().unbindService(mServiceConnection);
        }
        mIDataService = null;
        mServiceConnection = null;
        mTargetBindingPackageName = null;
        mBound = false;
    }

    private void bindDataService(String packageName) {
        if (mPhone == null || !SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())) {
            loge("can't bindDataService with invalid phone or phoneId.");
            return;
        }

        if (TextUtils.isEmpty(packageName)) {
            loge("Can't find the binding package");
            return;
        }

        Intent intent = null;
        String className = getDataServiceClassName();
        if (TextUtils.isEmpty(className)) {
            intent = new Intent(DataService.SERVICE_INTERFACE);
            intent.setPackage(packageName);
        } else {
            ComponentName cm = new ComponentName(packageName, className);
            intent = new Intent(DataService.SERVICE_INTERFACE).setComponent(cm);
        }

        // Then pre-emptively grant the permissions to the package we will bind.
        grantPermissionsToService(packageName);
@@ -372,6 +383,19 @@ public class DataServiceManager extends Handler {
        }
    }

    private void rebindDataService() {
        String packageName = getDataServicePackageName();
        // Do nothing if no need to rebind.
        if (SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())
                && TextUtils.equals(packageName, mTargetBindingPackageName)) {
            if (DBG) log("Service " + packageName + " already bound or being bound.");
            return;
        }

        unbindDataService();
        bindDataService(packageName);
    }

    @NonNull
    private Set<String> getAllDataServicePackageNames() {
        // Cowardly using the public PackageManager interface here.
Loading