Update TelephonySubscriptionTracker to use CarrierPrivilegesListener
This change adds use for CarrierPrivilegesListener to use the callbacks as triggers to re-check carrier privileges. For simplicity, the carrier privileges returned by the callback are not used, as it requires an additional layer of caching. Instead, a query is performed, which should hit a cache in the CarrierPrivilegesTracker, thus not be performance-sensitive. Bug: 183554244 Test: atest FrameworksVcnTests Change-Id: Ia4529d087ee7f0deca7101c6849183ba7267c067
This commit is contained in:
parent
525fc0dccb
commit
31d56f8298
@ -21,6 +21,7 @@ import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
|
||||
import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@ -38,15 +39,19 @@ import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.TelephonyManager.CarrierPrivilegesListener;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -92,6 +97,10 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
||||
@NonNull private final Map<Integer, Integer> mReadySubIdsBySlotId = new HashMap<>();
|
||||
@NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener;
|
||||
|
||||
@NonNull
|
||||
private final List<CarrierPrivilegesListener> mCarrierPrivilegesChangedListeners =
|
||||
new ArrayList<>();
|
||||
|
||||
@NonNull private TelephonySubscriptionSnapshot mCurrentSnapshot;
|
||||
|
||||
public TelephonySubscriptionTracker(
|
||||
@ -126,22 +135,71 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
||||
};
|
||||
}
|
||||
|
||||
/** Registers the receivers, and starts tracking subscriptions. */
|
||||
/**
|
||||
* Registers the receivers, and starts tracking subscriptions.
|
||||
*
|
||||
* <p>Must always be run on the VcnManagementService thread.
|
||||
*/
|
||||
public void register() {
|
||||
final HandlerExecutor executor = new HandlerExecutor(mHandler);
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
|
||||
filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED);
|
||||
|
||||
mContext.registerReceiver(
|
||||
this, new IntentFilter(ACTION_CARRIER_CONFIG_CHANGED), null, mHandler);
|
||||
mContext.registerReceiver(this, filter, null, mHandler);
|
||||
mSubscriptionManager.addOnSubscriptionsChangedListener(
|
||||
executor, mSubscriptionChangedListener);
|
||||
mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener);
|
||||
|
||||
registerCarrierPrivilegesListeners();
|
||||
}
|
||||
|
||||
/** Unregisters the receivers, and stops tracking subscriptions. */
|
||||
private void registerCarrierPrivilegesListeners() {
|
||||
final HandlerExecutor executor = new HandlerExecutor(mHandler);
|
||||
final int modemCount = mTelephonyManager.getActiveModemCount();
|
||||
try {
|
||||
for (int i = 0; i < modemCount; i++) {
|
||||
CarrierPrivilegesListener carrierPrivilegesListener =
|
||||
new CarrierPrivilegesListener() {
|
||||
@Override
|
||||
public void onCarrierPrivilegesChanged(
|
||||
@NonNull List<String> privilegedPackageNames,
|
||||
@NonNull int[] privilegedUids) {
|
||||
// Re-trigger the synchronous check (which is also very cheap due
|
||||
// to caching in CarrierPrivilegesTracker). This allows consistency
|
||||
// with the onSubscriptionsChangedListener and broadcasts.
|
||||
handleSubscriptionsChanged();
|
||||
}
|
||||
};
|
||||
|
||||
mTelephonyManager.addCarrierPrivilegesListener(
|
||||
i, executor, carrierPrivilegesListener);
|
||||
mCarrierPrivilegesChangedListeners.add(carrierPrivilegesListener);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
Slog.wtf(TAG, "Encounted exception registering carrier privileges listeners", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the receivers, and stops tracking subscriptions.
|
||||
*
|
||||
* <p>Must always be run on the VcnManagementService thread.
|
||||
*/
|
||||
public void unregister() {
|
||||
mContext.unregisterReceiver(this);
|
||||
mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener);
|
||||
mTelephonyManager.unregisterTelephonyCallback(mActiveDataSubIdListener);
|
||||
|
||||
unregisterCarrierPrivilegesListeners();
|
||||
}
|
||||
|
||||
private void unregisterCarrierPrivilegesListeners() {
|
||||
for (CarrierPrivilegesListener carrierPrivilegesListener :
|
||||
mCarrierPrivilegesChangedListeners) {
|
||||
mTelephonyManager.removeCarrierPrivilegesListener(carrierPrivilegesListener);
|
||||
}
|
||||
mCarrierPrivilegesChangedListeners.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,8 +236,6 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
||||
// group.
|
||||
if (subInfo.getSimSlotIndex() != INVALID_SIM_SLOT_INDEX
|
||||
&& mReadySubIdsBySlotId.values().contains(subInfo.getSubscriptionId())) {
|
||||
// TODO (b/172619301): Cache based on callbacks from CarrierPrivilegesTracker
|
||||
|
||||
final TelephonyManager subIdSpecificTelephonyManager =
|
||||
mTelephonyManager.createForSubscriptionId(subInfo.getSubscriptionId());
|
||||
|
||||
@ -214,12 +270,39 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver {
|
||||
*/
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// Accept sticky broadcasts; if CARRIER_CONFIG_CHANGED was previously broadcast and it
|
||||
// already was for an identified carrier, we can stop waiting for initial load to complete
|
||||
if (!ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
|
||||
return;
|
||||
switch (intent.getAction()) {
|
||||
case ACTION_CARRIER_CONFIG_CHANGED:
|
||||
handleActionCarrierConfigChanged(context, intent);
|
||||
break;
|
||||
case ACTION_MULTI_SIM_CONFIG_CHANGED:
|
||||
handleActionMultiSimConfigChanged(context, intent);
|
||||
break;
|
||||
default:
|
||||
Slog.v(TAG, "Unknown intent received with action: " + intent.getAction());
|
||||
}
|
||||
}
|
||||
|
||||
private void handleActionMultiSimConfigChanged(Context context, Intent intent) {
|
||||
unregisterCarrierPrivilegesListeners();
|
||||
|
||||
// Clear invalid slotIds from the mReadySubIdsBySlotId map.
|
||||
final int modemCount = mTelephonyManager.getActiveModemCount();
|
||||
final Iterator<Integer> slotIdIterator = mReadySubIdsBySlotId.keySet().iterator();
|
||||
while (slotIdIterator.hasNext()) {
|
||||
final int slotId = slotIdIterator.next();
|
||||
|
||||
if (slotId >= modemCount) {
|
||||
slotIdIterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
registerCarrierPrivilegesListeners();
|
||||
handleSubscriptionsChanged();
|
||||
}
|
||||
|
||||
private void handleActionCarrierConfigChanged(Context context, Intent intent) {
|
||||
// Accept sticky broadcasts; if CARRIER_CONFIG_CHANGED was previously broadcast and it
|
||||
// already was for an identified carrier, we can stop waiting for initial load to complete
|
||||
final int subId = intent.getIntExtra(EXTRA_SUBSCRIPTION_INDEX, INVALID_SUBSCRIPTION_ID);
|
||||
final int slotId = intent.getIntExtra(EXTRA_SLOT_INDEX, INVALID_SIM_SLOT_INDEX);
|
||||
|
||||
|
@ -22,6 +22,7 @@ import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
import static android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
|
||||
import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
|
||||
|
||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||
import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
|
||||
@ -34,8 +35,10 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
@ -57,6 +60,8 @@ import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.TelephonyManager.CarrierPrivilegesListener;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@ -83,7 +88,7 @@ public class TelephonySubscriptionTrackerTest {
|
||||
private static final String PACKAGE_NAME =
|
||||
TelephonySubscriptionTrackerTest.class.getPackage().getName();
|
||||
private static final ParcelUuid TEST_PARCEL_UUID = new ParcelUuid(UUID.randomUUID());
|
||||
private static final int TEST_SIM_SLOT_INDEX = 1;
|
||||
private static final int TEST_SIM_SLOT_INDEX = 0;
|
||||
private static final int TEST_SUBSCRIPTION_ID_1 = 2;
|
||||
private static final SubscriptionInfo TEST_SUBINFO_1 = mock(SubscriptionInfo.class);
|
||||
private static final int TEST_SUBSCRIPTION_ID_2 = 3;
|
||||
@ -151,6 +156,8 @@ public class TelephonySubscriptionTrackerTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
doReturn(2).when(mTelephonyManager).getActiveModemCount();
|
||||
|
||||
mCallback = mock(TelephonySubscriptionTrackerCallback.class);
|
||||
mTelephonySubscriptionTracker =
|
||||
new TelephonySubscriptionTracker(mContext, mHandler, mCallback, mDeps);
|
||||
@ -180,6 +187,15 @@ public class TelephonySubscriptionTrackerTest {
|
||||
return captor.getValue();
|
||||
}
|
||||
|
||||
private List<CarrierPrivilegesListener> getCarrierPrivilegesListeners() {
|
||||
final ArgumentCaptor<CarrierPrivilegesListener> captor =
|
||||
ArgumentCaptor.forClass(CarrierPrivilegesListener.class);
|
||||
verify(mTelephonyManager, atLeastOnce())
|
||||
.addCarrierPrivilegesListener(anyInt(), any(), captor.capture());
|
||||
|
||||
return captor.getAllValues();
|
||||
}
|
||||
|
||||
private ActiveDataSubscriptionIdListener getActiveDataSubscriptionIdListener() {
|
||||
final ArgumentCaptor<TelephonyCallback> captor =
|
||||
ArgumentCaptor.forClass(TelephonyCallback.class);
|
||||
@ -188,6 +204,11 @@ public class TelephonySubscriptionTrackerTest {
|
||||
return (ActiveDataSubscriptionIdListener) captor.getValue();
|
||||
}
|
||||
|
||||
private Intent buildTestMultiSimConfigBroadcastIntent() {
|
||||
Intent intent = new Intent(ACTION_MULTI_SIM_CONFIG_CHANGED);
|
||||
return intent;
|
||||
}
|
||||
|
||||
private Intent buildTestBroadcastIntent(boolean hasValidSubscription) {
|
||||
Intent intent = new Intent(ACTION_CARRIER_CONFIG_CHANGED);
|
||||
intent.putExtra(EXTRA_SLOT_INDEX, TEST_SIM_SLOT_INDEX);
|
||||
@ -239,12 +260,21 @@ public class TelephonySubscriptionTrackerTest {
|
||||
any(),
|
||||
eq(mHandler));
|
||||
final IntentFilter filter = getIntentFilter();
|
||||
assertEquals(1, filter.countActions());
|
||||
assertEquals(2, filter.countActions());
|
||||
assertTrue(filter.hasAction(ACTION_CARRIER_CONFIG_CHANGED));
|
||||
assertTrue(filter.hasAction(ACTION_MULTI_SIM_CONFIG_CHANGED));
|
||||
|
||||
verify(mSubscriptionManager)
|
||||
.addOnSubscriptionsChangedListener(any(HandlerExecutor.class), any());
|
||||
assertNotNull(getOnSubscriptionsChangedListener());
|
||||
|
||||
verify(mTelephonyManager, times(2))
|
||||
.addCarrierPrivilegesListener(anyInt(), any(HandlerExecutor.class), any());
|
||||
verify(mTelephonyManager)
|
||||
.addCarrierPrivilegesListener(eq(0), any(HandlerExecutor.class), any());
|
||||
verify(mTelephonyManager)
|
||||
.addCarrierPrivilegesListener(eq(1), any(HandlerExecutor.class), any());
|
||||
assertEquals(2, getCarrierPrivilegesListeners().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -255,6 +285,49 @@ public class TelephonySubscriptionTrackerTest {
|
||||
|
||||
final OnSubscriptionsChangedListener listener = getOnSubscriptionsChangedListener();
|
||||
verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(eq(listener));
|
||||
|
||||
for (CarrierPrivilegesListener carrierPrivilegesListener :
|
||||
getCarrierPrivilegesListeners()) {
|
||||
verify(mTelephonyManager)
|
||||
.removeCarrierPrivilegesListener(eq(carrierPrivilegesListener));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiSimConfigChanged() throws Exception {
|
||||
final ArrayMap<Integer, Integer> readySubIdsBySlotId = new ArrayMap<>();
|
||||
readySubIdsBySlotId.put(TEST_SIM_SLOT_INDEX, TEST_SUBSCRIPTION_ID_1);
|
||||
readySubIdsBySlotId.put(TEST_SIM_SLOT_INDEX + 1, TEST_SUBSCRIPTION_ID_1);
|
||||
|
||||
mTelephonySubscriptionTracker.setReadySubIdsBySlotId(readySubIdsBySlotId);
|
||||
doReturn(1).when(mTelephonyManager).getActiveModemCount();
|
||||
|
||||
List<CarrierPrivilegesListener> carrierPrivilegesListeners =
|
||||
getCarrierPrivilegesListeners();
|
||||
|
||||
mTelephonySubscriptionTracker.onReceive(mContext, buildTestMultiSimConfigBroadcastIntent());
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
for (CarrierPrivilegesListener carrierPrivilegesListener : carrierPrivilegesListeners) {
|
||||
verify(mTelephonyManager)
|
||||
.removeCarrierPrivilegesListener(eq(carrierPrivilegesListener));
|
||||
}
|
||||
|
||||
// Expect cache cleared for inactive slots.
|
||||
assertNull(
|
||||
mTelephonySubscriptionTracker
|
||||
.getReadySubIdsBySlotId()
|
||||
.get(TEST_SIM_SLOT_INDEX + 1));
|
||||
|
||||
// Expect a new CarrierPrivilegesListener to have been registered for slot 0, and none other
|
||||
// (2 previously registered during startup, for slots 0 & 1)
|
||||
verify(mTelephonyManager, times(3))
|
||||
.addCarrierPrivilegesListener(anyInt(), any(HandlerExecutor.class), any());
|
||||
verify(mTelephonyManager, times(2))
|
||||
.addCarrierPrivilegesListener(eq(0), any(HandlerExecutor.class), any());
|
||||
|
||||
// Verify that this triggers a re-evaluation
|
||||
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -313,6 +386,17 @@ public class TelephonySubscriptionTrackerTest {
|
||||
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCarrierPrivilegesChanged() throws Exception {
|
||||
setupReadySubIds();
|
||||
|
||||
final CarrierPrivilegesListener listener = getCarrierPrivilegesListeners().get(0);
|
||||
listener.onCarrierPrivilegesChanged(Collections.emptyList(), new int[] {});
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveBroadcast_ConfigReadyWithSubscriptions() throws Exception {
|
||||
mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
|
||||
|
Loading…
x
Reference in New Issue
Block a user