Merge "Mobile data in quick setting still work if default data not set" into qt-dev
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 8cb252e..2bfcc91 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.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 @@
             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 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 @@
             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 @@
             .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 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 @@
     }
 
     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 220463b..a28bb6c 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.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 @@
     @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 @@
         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);
     }
 }