Register BroadcastReceiver for default subId.

Register a receiver of ACTION_DEFAULT_SUBSCRIPTION_CHANGED to update
the cached default subId.

Bug: 273451360
Test: atest FrameworksNetTests
Change-Id: I3a38af7615fde2811449585d4e659ffaf29c5670
This commit is contained in:
Hansen Kurli
2023-06-08 07:53:26 +00:00
parent 19ea150271
commit 7b36f2322b
2 changed files with 81 additions and 6 deletions

View File

@@ -19,7 +19,10 @@ package com.android.server.connectivity;
import static android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import static android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Network; import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.NetworkSpecifier; import android.net.NetworkSpecifier;
@@ -69,9 +72,7 @@ public class KeepaliveStatsTracker {
// Mapping of subId to carrierId. Updates are received from OnSubscriptionsChangedListener // Mapping of subId to carrierId. Updates are received from OnSubscriptionsChangedListener
private final SparseIntArray mCachedCarrierIdPerSubId = new SparseIntArray(); private final SparseIntArray mCachedCarrierIdPerSubId = new SparseIntArray();
// The default subscription id obtained from SubscriptionManager.getDefaultSubscriptionId. // The default subscription id obtained from SubscriptionManager.getDefaultSubscriptionId.
// Updates are done from the OnSubscriptionsChangedListener. Note that there is no callback done // Updates are received from the ACTION_DEFAULT_SUBSCRIPTION_CHANGED broadcast.
// to OnSubscriptionsChangedListener when the default sub id changes.
// TODO: Register a listener for the default subId when it is possible.
private int mCachedDefaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private int mCachedDefaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
// Class to store network information, lifetime durations and active state of a keepalive. // Class to store network information, lifetime durations and active state of a keepalive.
@@ -269,6 +270,19 @@ public class KeepaliveStatsTracker {
Objects.requireNonNull(context.getSystemService(SubscriptionManager.class)); Objects.requireNonNull(context.getSystemService(SubscriptionManager.class));
mLastUpdateDurationsTimestamp = mDependencies.getElapsedRealtime(); mLastUpdateDurationsTimestamp = mDependencies.getElapsedRealtime();
context.registerReceiver(
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mCachedDefaultSubscriptionId =
intent.getIntExtra(
SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
},
new IntentFilter(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED),
/* broadcastPermission= */ null,
mConnectivityServiceHandler);
// The default constructor for OnSubscriptionsChangedListener will always implicitly grab // The default constructor for OnSubscriptionsChangedListener will always implicitly grab
// the looper of the current thread. In the case the current thread does not have a looper, // the looper of the current thread. In the case the current thread does not have a looper,
@@ -286,11 +300,8 @@ public class KeepaliveStatsTracker {
// but not necessarily empty, simply ignore it. Another call to the // but not necessarily empty, simply ignore it. Another call to the
// listener will be invoked in the future. // listener will be invoked in the future.
if (activeSubInfoList == null) return; if (activeSubInfoList == null) return;
final int defaultSubId =
subscriptionManager.getDefaultSubscriptionId();
mConnectivityServiceHandler.post(() -> { mConnectivityServiceHandler.post(() -> {
mCachedCarrierIdPerSubId.clear(); mCachedCarrierIdPerSubId.clear();
mCachedDefaultSubscriptionId = defaultSubId;
for (final SubscriptionInfo subInfo : activeSubInfoList) { for (final SubscriptionInfo subInfo : activeSubInfoList) {
mCachedCarrierIdPerSubId.put(subInfo.getSubscriptionId(), mCachedCarrierIdPerSubId.put(subInfo.getSubscriptionId(),

View File

@@ -27,12 +27,15 @@ import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Network; import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier; import android.net.TelephonyNetworkSpecifier;
@@ -109,6 +112,18 @@ public class KeepaliveStatsTrackerTest {
@Mock private KeepaliveStatsTracker.Dependencies mDependencies; @Mock private KeepaliveStatsTracker.Dependencies mDependencies;
@Mock private SubscriptionManager mSubscriptionManager; @Mock private SubscriptionManager mSubscriptionManager;
private void triggerBroadcastDefaultSubId(int subId) {
final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
verify(mContext).registerReceiver(receiverCaptor.capture(), /* filter= */ any(),
/* broadcastPermission= */ any(), eq(mTestHandler));
final Intent intent =
new Intent(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);
intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
receiverCaptor.getValue().onReceive(mContext, intent);
}
private OnSubscriptionsChangedListener getOnSubscriptionsChangedListener() { private OnSubscriptionsChangedListener getOnSubscriptionsChangedListener() {
final ArgumentCaptor<OnSubscriptionsChangedListener> listenerCaptor = final ArgumentCaptor<OnSubscriptionsChangedListener> listenerCaptor =
ArgumentCaptor.forClass(OnSubscriptionsChangedListener.class); ArgumentCaptor.forClass(OnSubscriptionsChangedListener.class);
@@ -1128,4 +1143,53 @@ public class KeepaliveStatsTrackerTest {
writeTime * 3 - startTime1 - startTime2 - startTime3) writeTime * 3 - startTime1 - startTime2 - startTime3)
}); });
} }
@Test
public void testUpdateDefaultSubId() {
final int startTime1 = 1000;
final int startTime2 = 3000;
final int writeTime = 5000;
// No TelephonyNetworkSpecifier set with subId to force the use of default subId.
final NetworkCapabilities nc =
new NetworkCapabilities.Builder().addTransportType(TRANSPORT_CELLULAR).build();
onStartKeepalive(startTime1, TEST_SLOT, nc);
// Update default subId
triggerBroadcastDefaultSubId(TEST_SUB_ID_1);
onStartKeepalive(startTime2, TEST_SLOT2, nc);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
buildKeepaliveMetrics(writeTime);
final int[] expectRegisteredDurations =
new int[] {startTime1, startTime2 - startTime1, writeTime - startTime2};
final int[] expectActiveDurations =
new int[] {startTime1, startTime2 - startTime1, writeTime - startTime2};
// Expect the carrier id of the first keepalive to be unknown
final KeepaliveCarrierStats expectKeepaliveCarrierStats1 =
new KeepaliveCarrierStats(
TelephonyManager.UNKNOWN_CARRIER_ID,
/* transportTypes= */ (1 << TRANSPORT_CELLULAR),
TEST_KEEPALIVE_INTERVAL_SEC * 1000,
writeTime - startTime1,
writeTime - startTime1);
// Expect the carrier id of the second keepalive to be TEST_CARRIER_ID_1, from TEST_SUB_ID_1
final KeepaliveCarrierStats expectKeepaliveCarrierStats2 =
new KeepaliveCarrierStats(
TEST_CARRIER_ID_1,
/* transportTypes= */ (1 << TRANSPORT_CELLULAR),
TEST_KEEPALIVE_INTERVAL_SEC * 1000,
writeTime - startTime2,
writeTime - startTime2);
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
/* expectRequestsCount= */ 2,
/* expectAutoRequestsCount= */ 2,
/* expectAppUids= */ new int[] {TEST_UID},
expectRegisteredDurations,
expectActiveDurations,
new KeepaliveCarrierStats[] {
expectKeepaliveCarrierStats1, expectKeepaliveCarrierStats2
});
}
} }