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

Commit aa0bee6f authored by Jack Yu's avatar Jack Yu Committed by Gerrit Code Review
Browse files

Merge changes from topic "get_all_subs"

* changes:
  Added few more APIs support
  Combine data roaming from user action into one preference
parents 42a600e8 bd19af9c
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -4542,18 +4542,28 @@ public class GsmCdmaPhone extends Phone {
            return;
        }

        SubscriptionInfo info = SubscriptionController.getInstance().getSubInfoForIccId(
        SubscriptionInfo info;
        if (isSubscriptionManagerServiceEnabled()) {
            info = mSubscriptionManagerService
                    .getAllSubInfoList(mContext.getOpPackageName(), mContext.getAttributionTag())
                    .stream()
                    .filter(subInfo -> subInfo.getIccId().equals(IccUtils.stripTrailingFs(iccId)))
                    .findFirst()
                    .orElse(null);
        } else {
            info = SubscriptionController.getInstance().getSubInfoForIccId(
                    IccUtils.stripTrailingFs(iccId));
        }

        // If info is null, it could be a new subscription. By default we enable it.
        boolean expectedValue = info == null ? true : info.areUiccApplicationsEnabled();
        boolean expectedValue = info == null || info.areUiccApplicationsEnabled();

        // If for any reason current state is different from configured state, re-apply the
        // configured state.
        if (expectedValue != mUiccApplicationsEnabled) {
            mCi.enableUiccApplications(expectedValue, Message.obtain(
                    this, EVENT_REAPPLY_UICC_APPS_ENABLEMENT_DONE,
                    new Pair<Boolean, Integer>(expectedValue, retries)));
                    new Pair<>(expectedValue, retries)));
        }
    }

+28 −31
Original line number Diff line number Diff line
@@ -528,42 +528,37 @@ public class DataSettingsManager extends Handler {
     * has not manually set the value. The default value is {@link #isDefaultDataRoamingEnabled()}.
     */
    public void setDefaultDataRoamingEnabled() {
        // For SSSS, this is a per-phone property from DATA_ROAMING_IS_USER_SETTING_KEY.
        // For DSDS, this is a per-sub property from Settings.Global.DATA_ROAMING + subId.
        // If the user has not manually set the value, use the default value.
        boolean useCarrierSpecificDefault = false;
        if (mPhone.getContext().getSystemService(TelephonyManager.class).getSimCount() != 1) {
            String setting = Settings.Global.DATA_ROAMING + mPhone.getSubId();
            try {
                Settings.Global.getInt(mResolver, setting);
            } catch (Settings.SettingNotFoundException ex) {
                // For multi-SIM phones, use the default value if uninitialized.
                useCarrierSpecificDefault = true;
            }
        } else if (!isDataRoamingFromUserAction()) {
            // For single-SIM phones, use the default value if user action is not set.
            useCarrierSpecificDefault = true;
        }
        log("setDefaultDataRoamingEnabled: useCarrierSpecificDefault=" + useCarrierSpecificDefault);
        if (useCarrierSpecificDefault) {
            boolean defaultVal = isDefaultDataRoamingEnabled();
            setDataRoamingEnabledInternal(defaultVal);
        if (!isDataRoamingFromUserAction()) {
            setDataRoamingEnabledInternal(isDefaultDataRoamingEnabled());
        }
    }

    /**
     * Get whether the user has manually enabled or disabled data roaming from settings.
     * @return {@code true} if the user has enabled data roaming and {@code false} if they have not.
     * Get whether the user has manually enabled or disabled data roaming from settings for the
     * current subscription.
     * @return {@code true} if the user has manually enabled data roaming for the current
     *         subscription and {@code false} if they have not.
     */
    private boolean isDataRoamingFromUserAction() {
        final SharedPreferences sp = PreferenceManager
                .getDefaultSharedPreferences(mPhone.getContext());
        // Since we don't want to unset user preferences after a system update, default to true if
        // the preference does not exist and set it to false explicitly from factory reset.
        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) {
            sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
        String key = Phone.DATA_ROAMING_IS_USER_SETTING_KEY + mPhone.getSubId();
        final SharedPreferences sp =
                PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());

        // Set the default roaming from user action value if the preference doesn't exist
        if (!sp.contains(key)) {
            if (sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) {
                log("Reusing previous roaming from user action value for backwards compatibility.");
                sp.edit().putBoolean(key, true).commit();
            } else {
                log("Clearing roaming from user action value for new or upgrading devices.");
                sp.edit().putBoolean(key, false).commit();
            }
        }
        return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);

        boolean isUserSetting = sp.getBoolean(key, true);
        log("isDataRoamingFromUserAction: key=" + key + ", isUserSetting=" + isUserSetting);
        return isUserSetting;
    }

    /**
@@ -572,9 +567,11 @@ public class DataSettingsManager extends Handler {
     * {@link #isDefaultDataRoamingEnabled()} will continue to be used.
     */
    private void setDataRoamingFromUserAction() {
        final SharedPreferences.Editor sp = PreferenceManager
                .getDefaultSharedPreferences(mPhone.getContext()).edit();
        sp.putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true).commit();
        String key = Phone.DATA_ROAMING_IS_USER_SETTING_KEY + mPhone.getSubId();
        log("setDataRoamingFromUserAction: key=" + key);
        final SharedPreferences.Editor sp =
                PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()).edit();
        sp.putBoolean(key, true).commit();
    }

    /** Refresh the enabled mobile data policies from Telephony database */
+178 −21
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.UserHandle;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.SubscriptionManager.PhoneNumberSource;
import android.telephony.SubscriptionManager.SubscriptionType;
import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.TelephonyManager;
@@ -44,6 +45,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.ISub;
import com.android.internal.telephony.MultiSimSettingController;
import com.android.internal.telephony.TelephonyPermissions;
import com.android.internal.telephony.subscription.SubscriptionDatabaseManager.SubscriptionDatabaseManagerCallback;
import com.android.internal.telephony.uicc.IccUtils;
import com.android.telephony.Rlog;
@@ -51,11 +53,13 @@ import com.android.telephony.Rlog;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * The subscription manager service is the backend service of {@link SubscriptionManager}.
@@ -75,6 +79,9 @@ public class SubscriptionManagerService extends ISub.Stub {
    @NonNull
    private final Context mContext;

    /** Telephony manager instance. */
    private final TelephonyManager mTelephonyManager;

    /** The main handler of subscription manager service. */
    @NonNull
    private final Handler mHandler;
@@ -226,6 +233,7 @@ public class SubscriptionManagerService extends ISub.Stub {
    public SubscriptionManagerService(@NonNull Context context, @NonNull Looper looper) {
        sInstance = this;
        mContext = context;
        mTelephonyManager = context.getSystemService(TelephonyManager.class);
        mHandler = new Handler(looper);
        TelephonyServiceManager.ServiceRegisterer subscriptionServiceRegisterer =
                TelephonyFrameworkInitializer
@@ -303,6 +311,98 @@ public class SubscriptionManagerService extends ISub.Stub {
        return sInstance;
    }

    /**
     * Check whether the {@code callingPackage} has access to the phone number on the specified
     * {@code subId} or not.
     *
     * @param subId The subscription id.
     * @param callingPackage The package making the call.
     * @param callingFeatureId The feature in the package.
     * @param message Message to include in the exception or NoteOp.
     *
     * @return {@code true} if the caller has phone number access.
     */
    private boolean hasPhoneNumberAccess(int subId, @NonNull String callingPackage,
            @Nullable String callingFeatureId, @Nullable String message) {
        try {
            return TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(mContext, subId,
                    callingPackage, callingFeatureId, message);
        } catch (SecurityException e) {
            return false;
        }
    }

    /**
     * Check whether the {@code callingPackage} has access to subscriber identifiers on the
     * specified {@code subId} or not.
     *
     * @param subId The subscription id.
     * @param callingPackage The package making the call.
     * @param callingFeatureId The feature in the package.
     * @param message Message to include in the exception or NoteOp.
     * @param reportFailure Indicates if failure should be reported.
     *
     * @return {@code true} if the caller has identifier access.
     */
    private boolean hasSubscriberIdentifierAccess(int subId, String callingPackage,
            String callingFeatureId, String message, boolean reportFailure) {
        try {
            return TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers(mContext, subId,
                    callingPackage, callingFeatureId, message, reportFailure);
        } catch (SecurityException e) {
            // A SecurityException indicates that the calling package is targeting at least the
            // minimum level that enforces identifier access restrictions and the new access
            // requirements are not met.
            return false;
        }
    }

    /**
     * Conditionally removes identifiers from the provided {@link SubscriptionInfo} if the {@code
     * callingPackage} does not meet the access requirements for identifiers and returns the
     * potentially modified object..
     *
     * <p>
     * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission,
     * {@link SubscriptionInfo#getNumber()} will return empty string.
     * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER},
     * {@link SubscriptionInfo#getIccId()} and {@link SubscriptionInfo#getCardString()} will return
     * empty string, and {@link SubscriptionInfo#getGroupUuid()} will return {@code null}.
     *
     * @param subInfo The subscription info.
     * @param callingPackage The package making the call.
     * @param callingFeatureId The feature in the package.
     * @param message Message to include in the exception or NoteOp.
     *
     * @return The modified {@link SubscriptionInfo} depending on caller's permission.
     */
    @NonNull
    private SubscriptionInfo conditionallyRemoveIdentifiers(@NonNull SubscriptionInfo subInfo,
            @NonNull String callingPackage, @Nullable String callingFeatureId,
            @Nullable String message) {
        int subId = subInfo.getSubscriptionId();
        boolean hasIdentifierAccess = hasSubscriberIdentifierAccess(subId, callingPackage,
                callingFeatureId, message, true);
        boolean hasPhoneNumberAccess = hasPhoneNumberAccess(subId, callingPackage,
                callingFeatureId, message);

        if (hasIdentifierAccess && hasPhoneNumberAccess) {
            return subInfo;
        }

        SubscriptionInfo.Builder result = new SubscriptionInfo.Builder(subInfo);
        if (!hasIdentifierAccess) {
            result.setIccId(null);
            result.setCardString(null);
            result.setGroupUuid(null);
        }

        if (!hasPhoneNumberAccess) {
            result.setNumber(null);
        }
        return result.build();
    }

    /**
     * Set the subscription carrier id.
     *
@@ -337,30 +437,70 @@ public class SubscriptionManagerService extends ISub.Stub {
    }

    /**
     * Get all subscription info records from SIMs that are inserted now or were inserted before.
     *
     * <p>
     * If the caller does not have {@link Manifest.permission#READ_PHONE_NUMBERS} permission,
     * {@link SubscriptionInfo#getNumber()} will return empty string.
     * If the caller does not have {@link Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER},
     * {@link SubscriptionInfo#getIccId()} and {@link SubscriptionInfo#getCardString()} will return
     * empty string, and {@link SubscriptionInfo#getGroupUuid()} will return {@code null}.
     *
     * <p>
     * The carrier app will always have full {@link SubscriptionInfo} for the subscriptions
     * that it has carrier privilege.
     *
     * @return List of all {@link SubscriptionInfo} records from SIMs that are inserted or
     * inserted before. Sorted by {@link SubscriptionInfo#getSimSlotIndex()}, then
     * {@link SubscriptionInfo#getSubscriptionId()}.
     *
     * @param callingPackage The package making the call.
     * @param callingFeatureId The feature in the package
     * @return a list of all subscriptions in the database, this includes
     * all subscriptions that have been seen.
     * @param callingFeatureId The feature in the package.
     *
     */
    @Override
    public List<SubscriptionInfo> getAllSubInfoList(@NonNull String callingPackage,
            @NonNull String callingFeatureId) {
        return null;
            @Nullable String callingFeatureId) {
        // Check if the caller has READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or carrier
        // privilege on any active subscription. The carrier app will get full subscription infos
        // on the subs it has carrier privilege.
        if (!TelephonyPermissions.checkReadPhoneStateOnAnyActiveSub(mContext,
                Binder.getCallingPid(), Binder.getCallingUid(), callingPackage, callingFeatureId,
                "getAllSubInfoList")) {
            throw new SecurityException("Need READ_PHONE_STATE, READ_PRIVILEGED_PHONE_STATE, or "
                    + "carrier privilege to call getAllSubInfoList");
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            return mSubscriptionDatabaseManager.getAllSubscriptions().stream()
                    // Remove the identifier if the caller does not have sufficient permission.
                    // carrier apps will get full subscription info on the subscriptions associated
                    // to them.
                    .map(subInfo -> conditionallyRemoveIdentifiers(subInfo.toSubscriptionInfo(),
                            callingPackage, callingFeatureId, "getAllSubInfoList"))
                    .sorted(Comparator.comparing(SubscriptionInfo::getSimSlotIndex)
                            .thenComparing(SubscriptionInfo::getSubscriptionId))
                    .collect(Collectors.toList());

        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
     * Get the active {@link SubscriptionInfo} with the subscription id key.
     *
     * @param subId The unique {@link SubscriptionInfo} key in database
     * @param callingPackage The package making the call
     * @param callingFeatureId The feature in the package
     * @param callingPackage The package making the call.
     * @param callingFeatureId The feature in the package.
     *
     * @return The subscription info.
     */
    @Override
    @Nullable
    public SubscriptionInfo getActiveSubscriptionInfo(int subId, @NonNull String callingPackage,
            @NonNull String callingFeatureId) {
            @Nullable String callingFeatureId) {
        return null;
    }

@@ -376,7 +516,7 @@ public class SubscriptionManagerService extends ISub.Stub {
    @Override
    @Nullable
    public SubscriptionInfo getActiveSubscriptionInfoForIccId(@NonNull String iccId,
            @NonNull String callingPackage, @NonNull String callingFeatureId) {
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        return null;
    }

@@ -391,7 +531,7 @@ public class SubscriptionManagerService extends ISub.Stub {
     */
    @Override
    public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex,
            @NonNull String callingPackage, @NonNull String callingFeatureId) {
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        return null;
    }

@@ -421,7 +561,7 @@ public class SubscriptionManagerService extends ISub.Stub {
     */
    @Override
    public List<SubscriptionInfo> getActiveSubscriptionInfoList(@NonNull String callingPackage,
            @NonNull String callingFeatureId) {
            @Nullable String callingFeatureId) {
        return null;
    }

@@ -434,7 +574,7 @@ public class SubscriptionManagerService extends ISub.Stub {
     */
    @Override
    public int getActiveSubInfoCount(@NonNull String callingPackage,
            @NonNull String callingFeatureId) {
            @Nullable String callingFeatureId) {
        return 0;
    }

@@ -451,7 +591,7 @@ public class SubscriptionManagerService extends ISub.Stub {
     */
    @Override
    public List<SubscriptionInfo> getAvailableSubscriptionInfoList(@NonNull String callingPackage,
            @NonNull String callingFeatureId) {
            @Nullable String callingFeatureId) {
        return null;
    }

@@ -655,7 +795,7 @@ public class SubscriptionManagerService extends ISub.Stub {
    @Override
    @NonNull
    public List<SubscriptionInfo> getOpportunisticSubscriptions(@NonNull String callingPackage,
            @NonNull String callingFeatureId) {
            @Nullable String callingFeatureId) {
        return Collections.emptyList();
    }

@@ -671,7 +811,7 @@ public class SubscriptionManagerService extends ISub.Stub {

    @Override
    public List<SubscriptionInfo> getSubscriptionsInGroup(@NonNull ParcelUuid groupUuid,
            @NonNull String callingPackage, @NonNull String callingFeatureId) {
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        return null;
    }

@@ -761,7 +901,7 @@ public class SubscriptionManagerService extends ISub.Stub {

    @Override
    public String getSubscriptionProperty(int subId, @NonNull String propKey,
            @NonNull String callingPackage, @NonNull String callingFeatureId) {
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        return null;
    }

@@ -787,7 +927,7 @@ public class SubscriptionManagerService extends ISub.Stub {

    @Override
    public boolean isActiveSubId(int subId, @NonNull String callingPackage,
            @NonNull String callingFeatureId) {
            @Nullable String callingFeatureId) {
        return true;
    }

@@ -819,19 +959,36 @@ public class SubscriptionManagerService extends ISub.Stub {

    @Override
    public String getPhoneNumber(int subId, int source,
            @NonNull String callingPackage, @NonNull String callingFeatureId) {
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        return null;
    }

    @Override
    public String getPhoneNumberFromFirstAvailableSource(int subId,
            @NonNull String callingPackage, @NonNull String callingFeatureId) {
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        return null;
    }

    @Override
    public void setPhoneNumber(int subId, int source, @NonNull String number,
            @NonNull String callingPackage, @NonNull String callingFeatureId) {
    public void setPhoneNumber(int subId, @PhoneNumberSource int source, @NonNull String number,
            @NonNull String callingPackage, @Nullable String callingFeatureId) {
        if (source != SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER) {
            throw new IllegalArgumentException("setPhoneNumber doesn't accept source "
                    + SubscriptionManager.phoneNumberSourceToString(source));
        }
        if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) {
            throw new SecurityException("setPhoneNumber for CARRIER needs carrier privilege.");
        }
        if (number == null) {
            throw new NullPointerException("invalid number null");
        }

        final long identity = Binder.clearCallingIdentity();
        try {
            mSubscriptionDatabaseManager.setNumberFromCarrier(subId, number);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
+30 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.internal.telephony.data;
import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
@@ -26,6 +28,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.os.Looper;
import android.os.PersistableBundle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

@@ -44,17 +47,21 @@ import java.util.Set;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class DataSettingsManagerTest extends TelephonyTest {
    private static final String DATA_ROAMING_IS_USER_SETTING = "data_roaming_is_user_setting_key0";

    // Mocked
    DataSettingsManagerCallback mMockedDataSettingsManagerCallback;

    DataSettingsManager mDataSettingsManagerUT;
    PersistableBundle mBundle;

    @Before
    public void setUp() throws Exception {
        logd("DataSettingsManagerTest +Setup!");
        super.setUp(getClass().getSimpleName());
        mMockedDataSettingsManagerCallback = Mockito.mock(DataSettingsManagerCallback.class);
        mBundle = mContextFixture.getCarrierConfigBundle();
        doReturn(true).when(mDataConfigManager).isConfigCarrierSpecific();

        doReturn("").when(mSubscriptionController).getEnabledMobileDataPolicies(anyInt());
        doReturn(true).when(mSubscriptionController).setEnabledMobileDataPolicies(
@@ -102,4 +109,27 @@ public class DataSettingsManagerTest extends TelephonyTest {
                .setEnabledMobileDataPolicies(anyInt(), stringArgumentCaptor.capture());
        assertEquals("1,2", stringArgumentCaptor.getValue());
    }

    @Test
    public void testDefaultDataRoamingEnabled() {
        doReturn(true).when(mDataConfigManager).isDataRoamingEnabledByDefault();
        mDataSettingsManagerUT.setDefaultDataRoamingEnabled();
        assertTrue(mDataSettingsManagerUT.isDataRoamingEnabled());

        mDataSettingsManagerUT.setDataRoamingEnabled(false);
        processAllMessages();
        assertFalse(mDataSettingsManagerUT.isDataRoamingEnabled());

        mDataSettingsManagerUT.setDefaultDataRoamingEnabled();
        assertFalse(mDataSettingsManagerUT.isDataRoamingEnabled());
    }

    @Test
    public void testDefaultDataRoamingEnabledFromUpgrade() {
        doReturn(true).when(mDataConfigManager).isDataRoamingEnabledByDefault();
        mContext.getSharedPreferences("", 0).edit()
                .putBoolean(DATA_ROAMING_IS_USER_SETTING, true).commit();
        mDataSettingsManagerUT.setDefaultDataRoamingEnabled();
        assertFalse(mDataSettingsManagerUT.isDataRoamingEnabled());
    }
}
+143 −1

File changed.

Preview size limit exceeded, changes collapsed.