Introduce Telephony2gUpdater to Apply 2g User Restrictions
Listens for the following actions and ensures that 2g is enabled
or disabled based on the state of the `DISALLOW_2G` user
restriction. 2g is enabled or disabled for all active subscriptions
on the device.
* A broadcast for action `android.os.action.USER_RESTRICTIONS_CHANGED`
* A callback from `SubscriptionManager` informing us of a subscription
state change
Test: atest Telephony2gUpdaterTest
Bug: 230669497
Change-Id: I819d412bc14cb98a5874d2a42b50d4e4483b4b02
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index 7edbed9..7c3a842 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -31,6 +31,7 @@
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.Process;
+import android.os.UserManager;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
@@ -58,6 +59,7 @@
@Mock TelephonyManager mMockTelephonyManager;
@Mock SubscriptionManager mMockSubscriptionManager;
@Mock ImsManager mMockImsManager;
+ @Mock UserManager mMockUserManager;
private SparseArray<PersistableBundle> mCarrierConfigs = new SparseArray<>();
@@ -147,6 +149,9 @@
case(Context.TELEPHONY_IMS_SERVICE) : {
return mMockImsManager;
}
+ case(Context.USER_SERVICE) : {
+ return mMockUserManager;
+ }
}
return null;
}
@@ -165,6 +170,9 @@
if (serviceClass == SubscriptionManager.class) {
return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
}
+ if (serviceClass == UserManager.class) {
+ return Context.USER_SERVICE;
+ }
return null;
}
diff --git a/tests/src/com/android/phone/Telephony2gUpdaterTest.java b/tests/src/com/android/phone/Telephony2gUpdaterTest.java
new file mode 100644
index 0000000..3443767
--- /dev/null
+++ b/tests/src/com/android/phone/Telephony2gUpdaterTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.UserManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+@RunWith(AndroidJUnit4.class)
+public class Telephony2gUpdaterTest extends TelephonyTestBase {
+ private Telephony2gUpdater mTelephony2gUpdater;
+ private Executor mExecutor;
+
+ private UserManager mMockUserManager;
+ private TelephonyManager mMockTelephonyManager;
+ private SubscriptionManager mMockSubscriptionManager;
+
+ // 2G Bitmask is 0b10000000_01001011
+ private static final long BASE_NETWORK = 0b11111111_11111111;
+ private static final long EXPECTED_DISABLED = 0b01111111_10110100;
+ private static final long EXPECTED_ENABLED = 0b11111111_11111111;
+
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ mMockTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+ mMockUserManager = mContext.getSystemService(UserManager.class);
+ mMockSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
+
+ mExecutor = Executors.newSingleThreadExecutor();
+ mTelephony2gUpdater = new Telephony2gUpdater(mExecutor,
+ getTestContext(), BASE_NETWORK);
+ }
+
+ @Test
+ public void handleUserRestrictionsChanged_noSubscriptions_noAllowedNetworksChanged() {
+ when(mMockSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ new ArrayList<>());
+ mTelephony2gUpdater.handleUserRestrictionsChanged(getTestContext());
+ verify(mMockTelephonyManager, never()).setAllowedNetworkTypesForReason(anyInt(), anyInt());
+ }
+
+ @Test
+ public void handleUserRestrictionsChanged_nullSubscriptions_noAllowedNetworksChanged() {
+ when(mMockSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(null);
+ mTelephony2gUpdater.handleUserRestrictionsChanged(getTestContext());
+ verify(mMockTelephonyManager, never()).setAllowedNetworkTypesForReason(anyInt(), anyInt());
+ }
+
+ @Test
+ public void handleUserRestrictionsChanged_oneSubscription_allowedNetworksUpdated() {
+ TelephonyManager tmSubscription1 = mock(TelephonyManager.class);
+ when(mMockSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ Collections.singletonList(getSubInfo(1)));
+ when(mMockTelephonyManager.createForSubscriptionId(1)).thenReturn(tmSubscription1);
+ when(mMockUserManager.hasUserRestriction(UserManager.DISALLOW_CELLULAR_2G)).thenReturn(
+ true);
+
+ mTelephony2gUpdater.handleUserRestrictionsChanged(getTestContext());
+
+ System.out.println(TelephonyManager.convertNetworkTypeBitmaskToString(11L));
+ verify(tmSubscription1, times(1)).setAllowedNetworkTypesForReason(
+ TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS, EXPECTED_DISABLED);
+ }
+
+ @Test
+ public void handleUserRestrictionsChanged_manySubscriptionsDisallow2g_allowedNetworkUpdated() {
+
+ // Two subscriptions are available
+ when(mMockSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ Arrays.asList(getSubInfo(1), getSubInfo(2)));
+ TelephonyManager tmSubscription1 = mock(TelephonyManager.class);
+ TelephonyManager tmSubscription2 = mock(TelephonyManager.class);
+ when(mMockTelephonyManager.createForSubscriptionId(1)).thenReturn(tmSubscription1);
+ when(mMockTelephonyManager.createForSubscriptionId(2)).thenReturn(tmSubscription2);
+ // 2g is disallowed
+ when(mMockUserManager.hasUserRestriction(UserManager.DISALLOW_CELLULAR_2G)).thenReturn(
+ true);
+
+ mTelephony2gUpdater.handleUserRestrictionsChanged(getTestContext());
+
+ verify(tmSubscription1, times(1)).setAllowedNetworkTypesForReason(
+ TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS, EXPECTED_DISABLED);
+ verify(tmSubscription1, times(1)).setAllowedNetworkTypesForReason(
+ TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS, EXPECTED_DISABLED);
+ }
+
+ @Test
+ public void handleUserRestrictionsChanged_manySubscriptionsAllow2g_allowedNetworkUpdated() {
+
+ // Two subscriptions are available
+ when(mMockSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
+ Arrays.asList(getSubInfo(1), getSubInfo(2)));
+ TelephonyManager tmSubscription1 = mock(TelephonyManager.class);
+ TelephonyManager tmSubscription2 = mock(TelephonyManager.class);
+ when(mMockTelephonyManager.createForSubscriptionId(1)).thenReturn(tmSubscription1);
+ when(mMockTelephonyManager.createForSubscriptionId(2)).thenReturn(tmSubscription2);
+
+ // 2g is allowed
+ when(mMockUserManager.hasUserRestriction(UserManager.DISALLOW_CELLULAR_2G)).thenReturn(
+ false);
+
+ mTelephony2gUpdater.handleUserRestrictionsChanged(getTestContext());
+
+ verify(tmSubscription1, times(1)).setAllowedNetworkTypesForReason(
+ TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS, EXPECTED_ENABLED);
+ verify(tmSubscription1, times(1)).setAllowedNetworkTypesForReason(
+ TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER_RESTRICTIONS, EXPECTED_ENABLED);
+ }
+
+ private SubscriptionInfo getSubInfo(int id) {
+ return new SubscriptionInfo(id, "890126042XXXXXXXXXXX", 0, "T-mobile", "T-mobile", 0, 255,
+ "12345", 0, null, "310", "260", "156", false, null, null);
+ }
+}