1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony.data;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.ArgumentMatchers.anyBoolean;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.Mockito.clearInvocations;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.times;
30 import static org.mockito.Mockito.verify;
31 
32 import android.annotation.NonNull;
33 import android.os.Looper;
34 import android.os.Message;
35 import android.os.PersistableBundle;
36 import android.telephony.TelephonyManager;
37 import android.testing.AndroidTestingRunner;
38 import android.testing.TestableLooper;
39 
40 import com.android.internal.telephony.Phone;
41 import com.android.internal.telephony.PhoneFactory;
42 import com.android.internal.telephony.TelephonyTest;
43 import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
44 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
45 
46 import org.junit.After;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 import org.mockito.ArgumentCaptor;
51 import org.mockito.Mockito;
52 
53 import java.util.Set;
54 import java.util.concurrent.CountDownLatch;
55 import java.util.concurrent.TimeUnit;
56 
57 @RunWith(AndroidTestingRunner.class)
58 @TestableLooper.RunWithLooper
59 public class DataSettingsManagerTest extends TelephonyTest {
60     private static final String DATA_ROAMING_IS_USER_SETTING = "data_roaming_is_user_setting_key0";
61 
62     // Mocked
63     DataSettingsManagerCallback mMockedDataSettingsManagerCallback;
64 
65     DataSettingsManager mDataSettingsManagerUT;
66     PersistableBundle mBundle;
67 
68     @Before
setUp()69     public void setUp() throws Exception {
70         logd("DataSettingsManagerTest +Setup!");
71         super.setUp(getClass().getSimpleName());
72         mMockedDataSettingsManagerCallback = Mockito.mock(DataSettingsManagerCallback.class);
73         mBundle = mContextFixture.getCarrierConfigBundle();
74         doReturn(true).when(mDataConfigManager).isConfigCarrierSpecific();
75 
76         doReturn(new SubscriptionInfoInternal.Builder().setId(1).build())
77                 .when(mSubscriptionManagerService).getSubscriptionInfoInternal(anyInt());
78 
79         mDataSettingsManagerUT = new DataSettingsManager(mPhone, mDataNetworkController,
80                 mFeatureFlags, Looper.myLooper(), mMockedDataSettingsManagerCallback);
81         logd("DataSettingsManagerTest -Setup!");
82     }
83 
84     @After
tearDown()85     public void tearDown() throws Exception {
86         logd("tearDown");
87         super.tearDown();
88     }
89 
90     @Test
testMobileDataPolicyParsing()91     public void testMobileDataPolicyParsing() {
92         //Valid new data policy
93         Set<Integer> policies = mDataSettingsManagerUT.getMobileDataPolicyEnabled("1, 2");
94         assertThat(policies.size()).isEqualTo(2);
95         Set<Integer> policies2 = mDataSettingsManagerUT.getMobileDataPolicyEnabled(",2");
96         assertThat(policies2.size()).isEqualTo(1);
97         Set<Integer> policies3 = mDataSettingsManagerUT.getMobileDataPolicyEnabled("");
98         assertThat(policies3.size()).isEqualTo(0);
99 
100         // Invalid
101         Set<Integer> invalid = mDataSettingsManagerUT.getMobileDataPolicyEnabled(
102                 "nonExistent, 1, 2");
103         assertThat(invalid.size()).isEqualTo(2);
104 
105         Set<Integer> invalid2 = mDataSettingsManagerUT.getMobileDataPolicyEnabled(
106                 "nonExistent ,,");
107         assertThat(invalid2.size()).isEqualTo(0);
108     }
109 
110     @Test
testGetPolicies()111     public void testGetPolicies() {
112         mDataSettingsManagerUT.setMobileDataPolicy(1, true);
113         mDataSettingsManagerUT.setMobileDataPolicy(2, true);
114         processAllMessages();
115 
116         ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
117         verify(mSubscriptionManagerService, times(2))
118                 .setEnabledMobileDataPolicies(anyInt(), stringArgumentCaptor.capture());
119         assertEquals("1,2", stringArgumentCaptor.getValue());
120     }
121 
122     @Test
testDefaultDataRoamingEnabled()123     public void testDefaultDataRoamingEnabled() {
124         doReturn(true).when(mDataConfigManager).isDataRoamingEnabledByDefault();
125         mDataSettingsManagerUT.setDefaultDataRoamingEnabled();
126         assertTrue(mDataSettingsManagerUT.isDataRoamingEnabled());
127 
128         mDataSettingsManagerUT.setDataRoamingEnabled(false);
129         processAllMessages();
130         assertFalse(mDataSettingsManagerUT.isDataRoamingEnabled());
131 
132         mDataSettingsManagerUT.setDefaultDataRoamingEnabled();
133         assertFalse(mDataSettingsManagerUT.isDataRoamingEnabled());
134     }
135 
136     @Test
testDefaultDataRoamingEnabledFromUpgrade()137     public void testDefaultDataRoamingEnabledFromUpgrade() {
138         doReturn(true).when(mDataConfigManager).isDataRoamingEnabledByDefault();
139         mContext.getSharedPreferences("", 0).edit()
140                 .putBoolean(DATA_ROAMING_IS_USER_SETTING, true).commit();
141         mDataSettingsManagerUT.setDefaultDataRoamingEnabled();
142         assertFalse(mDataSettingsManagerUT.isDataRoamingEnabled());
143     }
144 
145     @Test
testUpdateDataEnabledAndNotifyOverride()146     public void testUpdateDataEnabledAndNotifyOverride() throws Exception {
147         // Mock another DDS phone.
148         int ddsPhoneId = 1;
149         int ddsSubId = 2;
150         doReturn(ddsSubId).when(mSubscriptionManagerService).getDefaultDataSubId();
151         Phone phone2 = Mockito.mock(Phone.class);
152         doReturn(ddsPhoneId).when(phone2).getPhoneId();
153         doReturn(ddsSubId).when(phone2).getSubId();
154         doReturn(ddsPhoneId).when(mSubscriptionManagerService).getPhoneId(ddsSubId);
155         DataSettingsManager dataSettingsManager2 = Mockito.mock(DataSettingsManager.class);
156         doReturn(dataSettingsManager2).when(phone2).getDataSettingsManager();
157         mPhones = new Phone[] {mPhone, phone2};
158         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
159         ArgumentCaptor<DataSettingsManagerCallback> callbackArgumentCaptor = ArgumentCaptor
160                 .forClass(DataSettingsManagerCallback.class);
161 
162         mDataSettingsManagerUT.sendEmptyMessage(11 /* EVENT_INITIALIZE */);
163         processAllMessages();
164 
165         // Verify listening to user enabled status of other phones.
166         verify(dataSettingsManager2).registerCallback(callbackArgumentCaptor.capture());
167         DataSettingsManagerCallback callback = callbackArgumentCaptor.getValue();
168 
169         // Mock the phone as nonDDS.
170         mDataSettingsManagerUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, false, "");
171         processAllMessages();
172         clearInvocations(mPhone);
173 
174         // Verify the override policy doesn't take effect because the DDS is user disabled.
175         mDataSettingsManagerUT.setMobileDataPolicy(
176                 TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, true);
177         processAllMessages();
178         verify(mPhone, never()).notifyDataEnabled(anyBoolean(), anyInt());
179 
180         // Verify the override takes effect upon DDS user enabled.
181         doReturn(true).when(phone2).isUserDataEnabled();
182         callback.onUserDataEnabledChanged(true, "callingPackage");
183         verify(mPhone).notifyDataEnabled(true, TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
184     }
185 
186     @Test
testNotifyDataEnabledFromNewValidSubId()187     public void testNotifyDataEnabledFromNewValidSubId() throws Exception {
188         final CountDownLatch latch = new CountDownLatch(1);
189         mDataSettingsManagerUT.registerCallback(
190                 new DataSettingsManagerCallback(mDataSettingsManagerUT::post) {
191                     @Override
192                     public void onDataEnabledChanged(boolean enabled,
193                             @TelephonyManager.DataEnabledChangedReason int reason,
194                             @NonNull String callingPackage) {
195                         latch.countDown();
196                     }
197                 });
198 
199         Message.obtain(mDataSettingsManagerUT, 4 /* EVENT_SUBSCRIPTIONS_CHANGED */, -1)
200                 .sendToTarget();
201         Message.obtain(mDataSettingsManagerUT, 4 /* EVENT_SUBSCRIPTIONS_CHANGED */, 2)
202                 .sendToTarget();
203         processAllMessages();
204 
205         assertTrue(latch.await(1000, TimeUnit.MILLISECONDS));
206     }
207 }
208