blob: 5217e26a40efb6091c480fa23255e93845e90754 [file] [log] [blame]
markchienb6eb2c22018-07-18 14:29:20 +08001/*
2 * Copyright (C) 2018 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
17package com.android.server.connectivity.tethering;
18
markchien3b519632018-09-07 16:19:12 +080019import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
markchienf2731272019-01-16 17:44:13 +080020import static android.net.ConnectivityManager.TETHERING_USB;
21import static android.net.ConnectivityManager.TETHERING_WIFI;
22import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN;
23import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
24import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
markchien0b595072019-01-08 23:52:21 +080025import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
markchienf2731272019-01-16 17:44:13 +080026
27import static org.junit.Assert.assertEquals;
markchienb6eb2c22018-07-18 14:29:20 +080028import static org.junit.Assert.assertFalse;
29import static org.junit.Assert.assertTrue;
markchienf2731272019-01-16 17:44:13 +080030import static org.junit.Assert.fail;
markchienb6eb2c22018-07-18 14:29:20 +080031import static org.mockito.Matchers.anyBoolean;
markchien3394e142019-04-09 15:53:24 +080032import static org.mockito.Matchers.anyInt;
markchienb6eb2c22018-07-18 14:29:20 +080033import static org.mockito.Matchers.anyString;
34import static org.mockito.Matchers.eq;
markchien29b70142019-03-26 21:41:59 +080035import static org.mockito.Mockito.times;
36import static org.mockito.Mockito.verify;
markchienb6eb2c22018-07-18 14:29:20 +080037import static org.mockito.Mockito.when;
38
39import android.content.ContentResolver;
40import android.content.Context;
41import android.content.res.Resources;
42import android.net.util.SharedLog;
markchienf2731272019-01-16 17:44:13 +080043import android.os.Bundle;
44import android.os.Message;
markchienb6eb2c22018-07-18 14:29:20 +080045import android.os.PersistableBundle;
markchienf2731272019-01-16 17:44:13 +080046import android.os.ResultReceiver;
47import android.os.test.TestLooper;
48import android.provider.Settings;
markchienb6eb2c22018-07-18 14:29:20 +080049import android.telephony.CarrierConfigManager;
markchienf2731272019-01-16 17:44:13 +080050import android.test.mock.MockContentResolver;
markchienb6eb2c22018-07-18 14:29:20 +080051
Brett Chabot1ae2aa62019-03-04 14:14:56 -080052import androidx.test.filters.SmallTest;
53import androidx.test.runner.AndroidJUnit4;
54
markchienb6eb2c22018-07-18 14:29:20 +080055import com.android.internal.R;
markchienf2731272019-01-16 17:44:13 +080056import com.android.internal.util.State;
57import com.android.internal.util.StateMachine;
58import com.android.internal.util.test.BroadcastInterceptingContext;
59import com.android.internal.util.test.FakeSettingsProvider;
markchienb6eb2c22018-07-18 14:29:20 +080060import com.android.server.connectivity.MockableSystemProperties;
61
62import org.junit.After;
63import org.junit.Before;
64import org.junit.Test;
65import org.junit.runner.RunWith;
66import org.mockito.Mock;
67import org.mockito.MockitoAnnotations;
68
markchienf2731272019-01-16 17:44:13 +080069import java.util.ArrayList;
70import java.util.concurrent.CountDownLatch;
71import java.util.concurrent.TimeUnit;
72
markchienb6eb2c22018-07-18 14:29:20 +080073@RunWith(AndroidJUnit4.class)
74@SmallTest
75public final class EntitlementManagerTest {
76
77 private static final int EVENT_EM_UPDATE = 1;
78 private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
markchien3b519632018-09-07 16:19:12 +080079 private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
markchienb6eb2c22018-07-18 14:29:20 +080080
81 @Mock private CarrierConfigManager mCarrierConfigManager;
82 @Mock private Context mContext;
markchienb6eb2c22018-07-18 14:29:20 +080083 @Mock private MockableSystemProperties mSystemProperties;
84 @Mock private Resources mResources;
85 @Mock private SharedLog mLog;
markchien29b70142019-03-26 21:41:59 +080086 @Mock private EntitlementManager.OnUiEntitlementFailedListener mEntitlementFailedListener;
markchienb6eb2c22018-07-18 14:29:20 +080087
88 // Like so many Android system APIs, these cannot be mocked because it is marked final.
89 // We have to use the real versions.
90 private final PersistableBundle mCarrierConfig = new PersistableBundle();
markchienf2731272019-01-16 17:44:13 +080091 private final TestLooper mLooper = new TestLooper();
92 private Context mMockContext;
93 private MockContentResolver mContentResolver;
markchienb6eb2c22018-07-18 14:29:20 +080094
markchienf2731272019-01-16 17:44:13 +080095 private TestStateMachine mSM;
96 private WrappedEntitlementManager mEnMgr;
markchien3394e142019-04-09 15:53:24 +080097 private TetheringConfiguration mConfig;
markchienf2731272019-01-16 17:44:13 +080098
99 private class MockContext extends BroadcastInterceptingContext {
100 MockContext(Context base) {
101 super(base);
102 }
103
104 @Override
105 public Resources getResources() {
106 return mResources;
107 }
108
109 @Override
110 public ContentResolver getContentResolver() {
111 return mContentResolver;
112 }
113 }
114
115 public class WrappedEntitlementManager extends EntitlementManager {
116 public int fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN;
markchien3b519632018-09-07 16:19:12 +0800117 public int uiProvisionCount = 0;
118 public int silentProvisionCount = 0;
markchienf2731272019-01-16 17:44:13 +0800119
120 public WrappedEntitlementManager(Context ctx, StateMachine target,
markchien3b519632018-09-07 16:19:12 +0800121 SharedLog log, int what, MockableSystemProperties systemProperties) {
122 super(ctx, target, log, what, systemProperties);
markchienf2731272019-01-16 17:44:13 +0800123 }
124
markchien29b70142019-03-26 21:41:59 +0800125 public void reset() {
126 fakeEntitlementResult = TETHER_ERROR_ENTITLEMENT_UNKONWN;
127 uiProvisionCount = 0;
128 silentProvisionCount = 0;
markchienf2731272019-01-16 17:44:13 +0800129 }
markchien3b519632018-09-07 16:19:12 +0800130
131 @Override
markchien3394e142019-04-09 15:53:24 +0800132 protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) {
markchien3b519632018-09-07 16:19:12 +0800133 uiProvisionCount++;
markchien29b70142019-03-26 21:41:59 +0800134 receiver.send(fakeEntitlementResult, null);
markchien3b519632018-09-07 16:19:12 +0800135 }
136
137 @Override
markchien3394e142019-04-09 15:53:24 +0800138 protected void runSilentTetherProvisioning(int type, int subId) {
markchien3b519632018-09-07 16:19:12 +0800139 silentProvisionCount++;
markchien29b70142019-03-26 21:41:59 +0800140 addDownstreamMapping(type, fakeEntitlementResult);
markchien3b519632018-09-07 16:19:12 +0800141 }
markchienf2731272019-01-16 17:44:13 +0800142 }
markchienb6eb2c22018-07-18 14:29:20 +0800143
144 @Before
145 public void setUp() {
146 MockitoAnnotations.initMocks(this);
147
markchienb6eb2c22018-07-18 14:29:20 +0800148 when(mResources.getStringArray(R.array.config_tether_dhcp_range))
149 .thenReturn(new String[0]);
150 when(mResources.getStringArray(R.array.config_tether_usb_regexs))
151 .thenReturn(new String[0]);
152 when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
153 .thenReturn(new String[0]);
154 when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
155 .thenReturn(new String[0]);
156 when(mResources.getIntArray(R.array.config_tether_upstream_types))
157 .thenReturn(new int[0]);
158 when(mLog.forSubComponent(anyString())).thenReturn(mLog);
159
markchienf2731272019-01-16 17:44:13 +0800160 mContentResolver = new MockContentResolver();
161 mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
162 mMockContext = new MockContext(mContext);
163 mSM = new TestStateMachine();
markchien3b519632018-09-07 16:19:12 +0800164 mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE,
165 mSystemProperties);
markchien29b70142019-03-26 21:41:59 +0800166 mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener);
markchien3394e142019-04-09 15:53:24 +0800167 mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
168 mEnMgr.setTetheringConfigurationFetcher(() -> {
169 return mConfig;
170 });
markchienb6eb2c22018-07-18 14:29:20 +0800171 }
172
173 @After
markchienf2731272019-01-16 17:44:13 +0800174 public void tearDown() throws Exception {
175 if (mSM != null) {
176 mSM.quit();
177 mSM = null;
178 }
179 }
markchienb6eb2c22018-07-18 14:29:20 +0800180
181 private void setupForRequiredProvisioning() {
182 // Produce some acceptable looking provision app setting if requested.
183 when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
184 .thenReturn(PROVISIONING_APP_NAME);
markchien3b519632018-09-07 16:19:12 +0800185 when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
186 .thenReturn(PROVISIONING_NO_UI_APP_NAME);
187 // Don't disable tethering provisioning unless requested.
markchienb6eb2c22018-07-18 14:29:20 +0800188 when(mSystemProperties.getBoolean(eq(EntitlementManager.DISABLE_PROVISIONING_SYSPROP_KEY),
189 anyBoolean())).thenReturn(false);
190 // Act like the CarrierConfigManager is present and ready unless told otherwise.
191 when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
192 .thenReturn(mCarrierConfigManager);
markchien3394e142019-04-09 15:53:24 +0800193 when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
markchienb6eb2c22018-07-18 14:29:20 +0800194 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
markchien29a650c2019-03-19 20:57:04 +0800195 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
markchien3394e142019-04-09 15:53:24 +0800196 mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
markchienb6eb2c22018-07-18 14:29:20 +0800197 }
198
199 @Test
200 public void canRequireProvisioning() {
201 setupForRequiredProvisioning();
markchien3394e142019-04-09 15:53:24 +0800202 assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
markchienb6eb2c22018-07-18 14:29:20 +0800203 }
204
205 @Test
206 public void toleratesCarrierConfigManagerMissing() {
207 setupForRequiredProvisioning();
208 when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
209 .thenReturn(null);
markchien3394e142019-04-09 15:53:24 +0800210 mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
markchienb6eb2c22018-07-18 14:29:20 +0800211 // Couldn't get the CarrierConfigManager, but still had a declared provisioning app.
212 // Therefore provisioning still be required.
markchien3394e142019-04-09 15:53:24 +0800213 assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
markchienb6eb2c22018-07-18 14:29:20 +0800214 }
215
216 @Test
217 public void toleratesCarrierConfigMissing() {
218 setupForRequiredProvisioning();
219 when(mCarrierConfigManager.getConfig()).thenReturn(null);
markchien3394e142019-04-09 15:53:24 +0800220 mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
markchienb6eb2c22018-07-18 14:29:20 +0800221 // We still have a provisioning app configured, so still require provisioning.
markchien3394e142019-04-09 15:53:24 +0800222 assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
markchienb6eb2c22018-07-18 14:29:20 +0800223 }
224
225 @Test
markchien29a650c2019-03-19 20:57:04 +0800226 public void toleratesCarrierConfigNotLoaded() {
227 setupForRequiredProvisioning();
228 mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
markchien29a650c2019-03-19 20:57:04 +0800229 // We still have a provisioning app configured, so still require provisioning.
markchien3394e142019-04-09 15:53:24 +0800230 assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
markchien29a650c2019-03-19 20:57:04 +0800231 }
232
233 @Test
markchienb6eb2c22018-07-18 14:29:20 +0800234 public void provisioningNotRequiredWhenAppNotFound() {
235 setupForRequiredProvisioning();
236 when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
237 .thenReturn(null);
markchien3394e142019-04-09 15:53:24 +0800238 mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
239 assertFalse(mEnMgr.isTetherProvisioningRequired(mConfig));
markchienb6eb2c22018-07-18 14:29:20 +0800240 when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
241 .thenReturn(new String[] {"malformedApp"});
markchien3394e142019-04-09 15:53:24 +0800242 mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
243 assertFalse(mEnMgr.isTetherProvisioningRequired(mConfig));
markchienb6eb2c22018-07-18 14:29:20 +0800244 }
245
markchienf2731272019-01-16 17:44:13 +0800246 @Test
247 public void testGetLastEntitlementCacheValue() throws Exception {
248 final CountDownLatch mCallbacklatch = new CountDownLatch(1);
249 // 1. Entitlement check is not required.
250 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchienf2731272019-01-16 17:44:13 +0800251 ResultReceiver receiver = new ResultReceiver(null) {
252 @Override
253 protected void onReceiveResult(int resultCode, Bundle resultData) {
254 assertEquals(TETHER_ERROR_NO_ERROR, resultCode);
255 mCallbacklatch.countDown();
256 }
257 };
markchien9554abf2019-03-06 16:25:00 +0800258 mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
markchien3b519632018-09-07 16:19:12 +0800259 mLooper.dispatchAll();
markchienf2731272019-01-16 17:44:13 +0800260 callbackTimeoutHelper(mCallbacklatch);
markchien29b70142019-03-26 21:41:59 +0800261 assertEquals(0, mEnMgr.uiProvisionCount);
262 mEnMgr.reset();
markchienf2731272019-01-16 17:44:13 +0800263
264 setupForRequiredProvisioning();
markchienf2731272019-01-16 17:44:13 +0800265 // 2. No cache value and don't need to run entitlement check.
markchienf2731272019-01-16 17:44:13 +0800266 receiver = new ResultReceiver(null) {
267 @Override
268 protected void onReceiveResult(int resultCode, Bundle resultData) {
269 assertEquals(TETHER_ERROR_ENTITLEMENT_UNKONWN, resultCode);
270 mCallbacklatch.countDown();
271 }
272 };
markchien9554abf2019-03-06 16:25:00 +0800273 mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
markchien3b519632018-09-07 16:19:12 +0800274 mLooper.dispatchAll();
markchienf2731272019-01-16 17:44:13 +0800275 callbackTimeoutHelper(mCallbacklatch);
markchien29b70142019-03-26 21:41:59 +0800276 assertEquals(0, mEnMgr.uiProvisionCount);
277 mEnMgr.reset();
markchienf2731272019-01-16 17:44:13 +0800278 // 3. No cache value and ui entitlement check is needed.
279 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
markchienf2731272019-01-16 17:44:13 +0800280 receiver = new ResultReceiver(null) {
281 @Override
282 protected void onReceiveResult(int resultCode, Bundle resultData) {
283 assertEquals(TETHER_ERROR_PROVISION_FAILED, resultCode);
284 mCallbacklatch.countDown();
285 }
286 };
markchien9554abf2019-03-06 16:25:00 +0800287 mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
markchienf2731272019-01-16 17:44:13 +0800288 mLooper.dispatchAll();
289 callbackTimeoutHelper(mCallbacklatch);
markchien29b70142019-03-26 21:41:59 +0800290 assertEquals(1, mEnMgr.uiProvisionCount);
291 mEnMgr.reset();
markchienf2731272019-01-16 17:44:13 +0800292 // 4. Cache value is TETHER_ERROR_PROVISION_FAILED and don't need to run entitlement check.
293 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchienf2731272019-01-16 17:44:13 +0800294 receiver = new ResultReceiver(null) {
295 @Override
296 protected void onReceiveResult(int resultCode, Bundle resultData) {
297 assertEquals(TETHER_ERROR_PROVISION_FAILED, resultCode);
298 mCallbacklatch.countDown();
299 }
300 };
markchien9554abf2019-03-06 16:25:00 +0800301 mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, false);
markchien3b519632018-09-07 16:19:12 +0800302 mLooper.dispatchAll();
markchienf2731272019-01-16 17:44:13 +0800303 callbackTimeoutHelper(mCallbacklatch);
markchien29b70142019-03-26 21:41:59 +0800304 assertEquals(0, mEnMgr.uiProvisionCount);
305 mEnMgr.reset();
markchienf2731272019-01-16 17:44:13 +0800306 // 5. Cache value is TETHER_ERROR_PROVISION_FAILED and ui entitlement check is needed.
307 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchienf2731272019-01-16 17:44:13 +0800308 receiver = new ResultReceiver(null) {
309 @Override
310 protected void onReceiveResult(int resultCode, Bundle resultData) {
311 assertEquals(TETHER_ERROR_NO_ERROR, resultCode);
312 mCallbacklatch.countDown();
313 }
314 };
markchien9554abf2019-03-06 16:25:00 +0800315 mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
markchienf2731272019-01-16 17:44:13 +0800316 mLooper.dispatchAll();
317 callbackTimeoutHelper(mCallbacklatch);
markchien29b70142019-03-26 21:41:59 +0800318 assertEquals(1, mEnMgr.uiProvisionCount);
319 mEnMgr.reset();
markchienf2731272019-01-16 17:44:13 +0800320 // 6. Cache value is TETHER_ERROR_NO_ERROR.
321 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchienf2731272019-01-16 17:44:13 +0800322 receiver = new ResultReceiver(null) {
323 @Override
324 protected void onReceiveResult(int resultCode, Bundle resultData) {
325 assertEquals(TETHER_ERROR_NO_ERROR, resultCode);
326 mCallbacklatch.countDown();
327 }
328 };
markchien9554abf2019-03-06 16:25:00 +0800329 mEnMgr.getLatestTetheringEntitlementResult(TETHERING_WIFI, receiver, true);
markchien3b519632018-09-07 16:19:12 +0800330 mLooper.dispatchAll();
markchienf2731272019-01-16 17:44:13 +0800331 callbackTimeoutHelper(mCallbacklatch);
markchien29b70142019-03-26 21:41:59 +0800332 assertEquals(0, mEnMgr.uiProvisionCount);
333 mEnMgr.reset();
markchienf2731272019-01-16 17:44:13 +0800334 // 7. Test get value for other downstream type.
markchienf2731272019-01-16 17:44:13 +0800335 receiver = new ResultReceiver(null) {
336 @Override
337 protected void onReceiveResult(int resultCode, Bundle resultData) {
338 assertEquals(TETHER_ERROR_ENTITLEMENT_UNKONWN, resultCode);
339 mCallbacklatch.countDown();
340 }
341 };
markchien9554abf2019-03-06 16:25:00 +0800342 mEnMgr.getLatestTetheringEntitlementResult(TETHERING_USB, receiver, false);
markchien3b519632018-09-07 16:19:12 +0800343 mLooper.dispatchAll();
markchienf2731272019-01-16 17:44:13 +0800344 callbackTimeoutHelper(mCallbacklatch);
markchien29b70142019-03-26 21:41:59 +0800345 assertEquals(0, mEnMgr.uiProvisionCount);
346 mEnMgr.reset();
markchienf2731272019-01-16 17:44:13 +0800347 }
348
349 void callbackTimeoutHelper(final CountDownLatch latch) throws Exception {
350 if (!latch.await(1, TimeUnit.SECONDS)) {
markchien3b519632018-09-07 16:19:12 +0800351 fail("Timout, fail to receive callback");
markchienf2731272019-01-16 17:44:13 +0800352 }
353 }
markchien3b519632018-09-07 16:19:12 +0800354
355 @Test
356 public void verifyPermissionResult() {
357 setupForRequiredProvisioning();
358 mEnMgr.notifyUpstream(true);
markchien29b70142019-03-26 21:41:59 +0800359 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
markchien3b519632018-09-07 16:19:12 +0800360 mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
361 mLooper.dispatchAll();
markchien3b519632018-09-07 16:19:12 +0800362 assertFalse(mEnMgr.isCellularUpstreamPermitted());
363 mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
364 mLooper.dispatchAll();
markchien29b70142019-03-26 21:41:59 +0800365 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchien3b519632018-09-07 16:19:12 +0800366 mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
367 mLooper.dispatchAll();
markchien3b519632018-09-07 16:19:12 +0800368 assertTrue(mEnMgr.isCellularUpstreamPermitted());
369 }
370
371 @Test
372 public void verifyPermissionIfAllNotApproved() {
373 setupForRequiredProvisioning();
374 mEnMgr.notifyUpstream(true);
markchien29b70142019-03-26 21:41:59 +0800375 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
markchien3b519632018-09-07 16:19:12 +0800376 mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
377 mLooper.dispatchAll();
markchien3b519632018-09-07 16:19:12 +0800378 assertFalse(mEnMgr.isCellularUpstreamPermitted());
markchien29b70142019-03-26 21:41:59 +0800379 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
markchien3b519632018-09-07 16:19:12 +0800380 mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
381 mLooper.dispatchAll();
markchien3b519632018-09-07 16:19:12 +0800382 assertFalse(mEnMgr.isCellularUpstreamPermitted());
markchien29b70142019-03-26 21:41:59 +0800383 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
markchien3b519632018-09-07 16:19:12 +0800384 mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
385 mLooper.dispatchAll();
markchien3b519632018-09-07 16:19:12 +0800386 assertFalse(mEnMgr.isCellularUpstreamPermitted());
387 }
388
389 @Test
390 public void verifyPermissionIfAnyApproved() {
391 setupForRequiredProvisioning();
392 mEnMgr.notifyUpstream(true);
markchien29b70142019-03-26 21:41:59 +0800393 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchien3b519632018-09-07 16:19:12 +0800394 mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
395 mLooper.dispatchAll();
markchien3b519632018-09-07 16:19:12 +0800396 assertTrue(mEnMgr.isCellularUpstreamPermitted());
397 mLooper.dispatchAll();
markchien29b70142019-03-26 21:41:59 +0800398 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
markchien3b519632018-09-07 16:19:12 +0800399 mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
400 mLooper.dispatchAll();
markchien3b519632018-09-07 16:19:12 +0800401 assertTrue(mEnMgr.isCellularUpstreamPermitted());
402 mEnMgr.stopProvisioningIfNeeded(TETHERING_WIFI);
403 mLooper.dispatchAll();
404 assertFalse(mEnMgr.isCellularUpstreamPermitted());
405
406 }
407
408 @Test
markchien426311b2019-08-09 21:43:38 +0800409 public void verifyPermissionWhenProvisioningNotStarted() {
410 assertTrue(mEnMgr.isCellularUpstreamPermitted());
411 setupForRequiredProvisioning();
412 assertFalse(mEnMgr.isCellularUpstreamPermitted());
413 }
414
415 @Test
markchien3b519632018-09-07 16:19:12 +0800416 public void testRunTetherProvisioning() {
417 setupForRequiredProvisioning();
markchien3b519632018-09-07 16:19:12 +0800418 // 1. start ui provisioning, upstream is mobile
markchien29b70142019-03-26 21:41:59 +0800419 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchien3b519632018-09-07 16:19:12 +0800420 mEnMgr.notifyUpstream(true);
421 mLooper.dispatchAll();
422 mEnMgr.startProvisioningIfNeeded(TETHERING_USB, true);
423 mLooper.dispatchAll();
markchien29b70142019-03-26 21:41:59 +0800424 assertEquals(1, mEnMgr.uiProvisionCount);
425 assertEquals(0, mEnMgr.silentProvisionCount);
426 assertTrue(mEnMgr.isCellularUpstreamPermitted());
427 mEnMgr.reset();
markchien3b519632018-09-07 16:19:12 +0800428 // 2. start no-ui provisioning
markchien29b70142019-03-26 21:41:59 +0800429 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchien3b519632018-09-07 16:19:12 +0800430 mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, false);
431 mLooper.dispatchAll();
markchien29b70142019-03-26 21:41:59 +0800432 assertEquals(0, mEnMgr.uiProvisionCount);
433 assertEquals(1, mEnMgr.silentProvisionCount);
434 assertTrue(mEnMgr.isCellularUpstreamPermitted());
435 mEnMgr.reset();
markchien3b519632018-09-07 16:19:12 +0800436 // 3. tear down mobile, then start ui provisioning
437 mEnMgr.notifyUpstream(false);
438 mLooper.dispatchAll();
439 mEnMgr.startProvisioningIfNeeded(TETHERING_BLUETOOTH, true);
440 mLooper.dispatchAll();
markchien29b70142019-03-26 21:41:59 +0800441 assertEquals(0, mEnMgr.uiProvisionCount);
442 assertEquals(0, mEnMgr.silentProvisionCount);
443 mEnMgr.reset();
markchien3b519632018-09-07 16:19:12 +0800444 // 4. switch upstream back to mobile
markchien29b70142019-03-26 21:41:59 +0800445 mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
markchien3b519632018-09-07 16:19:12 +0800446 mEnMgr.notifyUpstream(true);
447 mLooper.dispatchAll();
markchien29b70142019-03-26 21:41:59 +0800448 assertEquals(1, mEnMgr.uiProvisionCount);
449 assertEquals(0, mEnMgr.silentProvisionCount);
450 assertTrue(mEnMgr.isCellularUpstreamPermitted());
451 mEnMgr.reset();
markchien3b519632018-09-07 16:19:12 +0800452 // 5. tear down mobile, then switch SIM
453 mEnMgr.notifyUpstream(false);
454 mLooper.dispatchAll();
markchien3394e142019-04-09 15:53:24 +0800455 mEnMgr.reevaluateSimCardProvisioning(mConfig);
markchien29b70142019-03-26 21:41:59 +0800456 assertEquals(0, mEnMgr.uiProvisionCount);
457 assertEquals(0, mEnMgr.silentProvisionCount);
458 mEnMgr.reset();
markchien3b519632018-09-07 16:19:12 +0800459 // 6. switch upstream back to mobile again
markchien29b70142019-03-26 21:41:59 +0800460 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
markchien3b519632018-09-07 16:19:12 +0800461 mEnMgr.notifyUpstream(true);
462 mLooper.dispatchAll();
markchien29b70142019-03-26 21:41:59 +0800463 assertEquals(0, mEnMgr.uiProvisionCount);
464 assertEquals(3, mEnMgr.silentProvisionCount);
465 mEnMgr.reset();
markchien3b519632018-09-07 16:19:12 +0800466 }
467
markchien29b70142019-03-26 21:41:59 +0800468 @Test
469 public void testCallStopTetheringWhenUiProvisioningFail() {
470 setupForRequiredProvisioning();
markchien29b70142019-03-26 21:41:59 +0800471 verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI);
472 mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED;
473 mEnMgr.notifyUpstream(true);
474 mLooper.dispatchAll();
475 mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
476 mLooper.dispatchAll();
477 assertEquals(1, mEnMgr.uiProvisionCount);
478 verify(mEntitlementFailedListener, times(1)).onUiEntitlementFailed(TETHERING_WIFI);
479 }
480
markchienf2731272019-01-16 17:44:13 +0800481 public class TestStateMachine extends StateMachine {
482 public final ArrayList<Message> messages = new ArrayList<>();
markchien3b519632018-09-07 16:19:12 +0800483 private final State
484 mLoggingState = new EntitlementManagerTest.TestStateMachine.LoggingState();
markchienf2731272019-01-16 17:44:13 +0800485
486 class LoggingState extends State {
487 @Override public void enter() {
488 messages.clear();
489 }
490
491 @Override public void exit() {
492 messages.clear();
493 }
494
495 @Override public boolean processMessage(Message msg) {
496 messages.add(msg);
497 return false;
498 }
499 }
500
501 public TestStateMachine() {
502 super("EntitlementManagerTest.TestStateMachine", mLooper.getLooper());
503 addState(mLoggingState);
504 setInitialState(mLoggingState);
505 super.start();
506 }
507 }
markchienb6eb2c22018-07-18 14:29:20 +0800508}