From a1a7f192f9b07f180e9c639f549b3c5d42db2ac3 Mon Sep 17 00:00:00 2001 From: Malcolm Chen Date: Wed, 8 May 2019 17:16:47 -0700 Subject: [PATCH] Mobile data in quick setting still work if default data not set Even if default data subscription is not set, we'll make "Mobile data" toggle in quick setting work. It will find an active subscription, turn on its mobile data, which implicitly makes it default data sub. Bug: 132063538 Test: robo test and manual Change-Id: I05263ca6e7e0f9171c6d34c7b628553b9ec506ab --- .../settingslib/net/DataUsageController.java | 40 ++++++++---- .../net/DataUsageControllerTest.java | 62 +++++++++++++++++-- 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java index 8cb252ed62833..2bfcc91bbc29e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java +++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java @@ -42,6 +42,8 @@ import android.util.Log; import android.util.Range; import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; import java.time.ZonedDateTime; import java.util.Iterator; @@ -57,7 +59,6 @@ public class DataUsageController { PERIOD_BUILDER, Locale.getDefault()); private final Context mContext; - private final TelephonyManager mTelephonyManager; private final ConnectivityManager mConnectivityManager; private final INetworkStatsService mStatsService; private final NetworkPolicyManager mPolicyManager; @@ -70,7 +71,6 @@ public class DataUsageController { public DataUsageController(Context context) { mContext = context; - mTelephonyManager = TelephonyManager.from(context); mConnectivityManager = ConnectivityManager.from(context); mStatsService = INetworkStatsService.Stub.asInterface( ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); @@ -115,7 +115,8 @@ public class DataUsageController { return warn("no subscriber id"); } NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId); - template = NetworkTemplate.normalize(template, mTelephonyManager.getMergedSubscriberIds()); + template = NetworkTemplate.normalize(template, getTelephonyManager() + .getMergedSubscriberIds()); return getDataUsageInfo(template); } @@ -212,9 +213,29 @@ public class DataUsageController { .append(']').toString(); } + @VisibleForTesting + public TelephonyManager getTelephonyManager() { + int subscriptionId = mSubscriptionId; + + // If mSubscriptionId is invalid, get default data sub. + if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) { + subscriptionId = SubscriptionManager.getDefaultDataSubscriptionId(); + } + + // If data sub is also invalid, get any active sub. + if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) { + int[] activeSubIds = SubscriptionManager.from(mContext).getActiveSubscriptionIdList(); + if (!ArrayUtils.isEmpty(activeSubIds)) { + subscriptionId = activeSubIds[0]; + } + } + + return TelephonyManager.from(mContext).createForSubscriptionId(subscriptionId); + } + public void setMobileDataEnabled(boolean enabled) { Log.d(TAG, "setMobileDataEnabled: enabled=" + enabled); - mTelephonyManager.setDataEnabled(enabled); + getTelephonyManager().setDataEnabled(enabled); if (mCallback != null) { mCallback.onMobileDataEnabled(enabled); } @@ -223,11 +244,11 @@ public class DataUsageController { public boolean isMobileDataSupported() { // require both supported network and ready SIM return mConnectivityManager.isNetworkSupported(TYPE_MOBILE) - && mTelephonyManager.getSimState() == SIM_STATE_READY; + && getTelephonyManager().getSimState() == SIM_STATE_READY; } public boolean isMobileDataEnabled() { - return mTelephonyManager.getDataEnabled(); + return getTelephonyManager().isDataEnabled(); } static int getNetworkType(NetworkTemplate networkTemplate) { @@ -250,12 +271,7 @@ public class DataUsageController { } private String getActiveSubscriberId() { - final TelephonyManager tele = TelephonyManager.from(mContext); - int subscriptionId = mSubscriptionId; - if (subscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { - subscriptionId = SubscriptionManager.getDefaultDataSubscriptionId(); - } - final String actualSubscriberId = tele.getSubscriberId(subscriptionId); + final String actualSubscriberId = getTelephonyManager().getSubscriberId(); return actualSubscriberId; } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java index 220463b1f06cf..a28bb6ce44c56 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java @@ -36,6 +36,7 @@ import android.net.INetworkStatsSession; import android.net.NetworkStatsHistory; import android.net.NetworkTemplate; import android.os.RemoteException; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.format.DateUtils; @@ -57,26 +58,31 @@ public class DataUsageControllerTest { @Mock private TelephonyManager mTelephonyManager; @Mock + private SubscriptionManager mSubscriptionManager; + @Mock private NetworkStatsManager mNetworkStatsManager; @Mock private Context mContext; private DataUsageController mController; private NetworkStatsHistory mNetworkStatsHistory; + private final int mDefaultSubscriptionId = 1234; @Before public void setUp() throws RemoteException { MockitoAnnotations.initMocks(this); + when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)) + .thenReturn(mSubscriptionManager); when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager); mController = new DataUsageController(mContext); mNetworkStatsHistory = spy( new NetworkStatsHistory(DateUtils.DAY_IN_MILLIS /* bucketDuration */)); doReturn(mNetworkStatsHistory) .when(mSession).getHistoryForNetwork(any(NetworkTemplate.class), anyInt()); - final int defaultSubscriptionId = 1234; - ShadowSubscriptionManager.setDefaultDataSubscriptionId(defaultSubscriptionId); - doReturn(SUB_ID).when(mTelephonyManager).getSubscriberId(eq(defaultSubscriptionId)); + ShadowSubscriptionManager.setDefaultDataSubscriptionId(mDefaultSubscriptionId); + doReturn(SUB_ID).when(mTelephonyManager).getSubscriberId(); } @Test @@ -130,19 +136,63 @@ public class DataUsageControllerTest { final NetworkStats.Bucket nonDefaultSubscriberBucket = mock(NetworkStats.Bucket.class); when(nonDefaultSubscriberBucket.getRxBytes()).thenReturn(nonDefaultSubRx); when(nonDefaultSubscriberBucket.getTxBytes()).thenReturn(nonDefaultSubTx); - final int explictSubscriptionId = 55; + final int explicitSubscriptionId = 55; final String subscriberId2 = "Test Subscriber 2"; when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_MOBILE), eq(subscriberId2), eq(0L)/* startTime */, anyLong() /* endTime */)).thenReturn( nonDefaultSubscriberBucket); - doReturn(subscriberId2).when(mTelephonyManager).getSubscriberId(explictSubscriptionId); + doReturn(subscriberId2).when(mTelephonyManager).getSubscriberId(); // Now verify that when we're asking for stats on the non-default subscription, we get // the data back for that subscription and *not* the default one. - mController.setSubscriptionId(explictSubscriptionId); + mController.setSubscriptionId(explicitSubscriptionId); assertThat(mController.getHistoricalUsageLevel( NetworkTemplate.buildTemplateMobileAll(subscriberId2))).isEqualTo( nonDefaultSubRx + nonDefaultSubTx); + + verify(mTelephonyManager).createForSubscriptionId(explicitSubscriptionId); + } + + @Test + public void getTelephonyManager_shouldCreateWithExplicitSubId() throws Exception { + int explicitSubId = 1; + TelephonyManager tmForSub1 = new TelephonyManager(mContext, explicitSubId); + when(mTelephonyManager.createForSubscriptionId(eq(explicitSubId))).thenReturn(tmForSub1); + + // Set a specific subId. + mController.setSubscriptionId(explicitSubId); + + assertThat(mController.getTelephonyManager()).isEqualTo(tmForSub1); + verify(mTelephonyManager).createForSubscriptionId(eq(explicitSubId)); + } + + @Test + public void getTelephonyManager_noExplicitSubId_shouldCreateWithDefaultDataSubId() + throws Exception { + TelephonyManager tmForDefaultSub = new TelephonyManager(mContext, mDefaultSubscriptionId); + when(mTelephonyManager.createForSubscriptionId(mDefaultSubscriptionId)) + .thenReturn(tmForDefaultSub); + + // No subId is set. It should use default data sub. + assertThat(mController.getTelephonyManager()).isEqualTo(tmForDefaultSub); + verify(mTelephonyManager).createForSubscriptionId(mDefaultSubscriptionId); + } + + @Test + public void getTelephonyManager_noExplicitSubIdOrDefaultSub_shouldCreateWithActiveSub() + throws Exception { + int activeSubId = 2; + ShadowSubscriptionManager.setDefaultDataSubscriptionId( + SubscriptionManager.INVALID_SUBSCRIPTION_ID); + when(mSubscriptionManager.getActiveSubscriptionIdList()) + .thenReturn(new int[] {activeSubId}); + TelephonyManager tmForActiveSub = new TelephonyManager(mContext, activeSubId); + when(mTelephonyManager.createForSubscriptionId(activeSubId)) + .thenReturn(tmForActiveSub); + + // No subId is set, default data subId is also not set. So should use the only active subId. + assertThat(mController.getTelephonyManager()).isEqualTo(tmForActiveSub); + verify(mTelephonyManager).createForSubscriptionId(activeSubId); } }