Register BroadcastReceiver for default subId.
Register a receiver of ACTION_DEFAULT_SUBSCRIPTION_CHANGED to update
the cached default subId.
Bug: 273451360
Test: atest FrameworksNetTests
(cherry picked from https://android-review.googlesource.com/q/commit:7b36f2322bf0e7b8f7c916a98914289f9878b676)
Merged-In: I3a38af7615fde2811449585d4e659ffaf29c5670
Change-Id: I3a38af7615fde2811449585d4e659ffaf29c5670
diff --git a/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java b/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java
index f9213d7..d59d526 100644
--- a/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java
+++ b/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java
@@ -19,7 +19,10 @@
import static android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkSpecifier;
@@ -69,9 +72,7 @@
// Mapping of subId to carrierId. Updates are received from OnSubscriptionsChangedListener
private final SparseIntArray mCachedCarrierIdPerSubId = new SparseIntArray();
// The default subscription id obtained from SubscriptionManager.getDefaultSubscriptionId.
- // Updates are done from the OnSubscriptionsChangedListener. Note that there is no callback done
- // to OnSubscriptionsChangedListener when the default sub id changes.
- // TODO: Register a listener for the default subId when it is possible.
+ // Updates are received from the ACTION_DEFAULT_SUBSCRIPTION_CHANGED broadcast.
private int mCachedDefaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
// Class to store network information, lifetime durations and active state of a keepalive.
@@ -269,6 +270,19 @@
Objects.requireNonNull(context.getSystemService(SubscriptionManager.class));
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 looper of the current thread. In the case the current thread does not have a looper,
@@ -286,11 +300,8 @@
// but not necessarily empty, simply ignore it. Another call to the
// listener will be invoked in the future.
if (activeSubInfoList == null) return;
- final int defaultSubId =
- subscriptionManager.getDefaultSubscriptionId();
mConnectivityServiceHandler.post(() -> {
mCachedCarrierIdPerSubId.clear();
- mCachedDefaultSubscriptionId = defaultSubId;
for (final SubscriptionInfo subInfo : activeSubInfoList) {
mCachedCarrierIdPerSubId.put(subInfo.getSubscriptionId(),
diff --git a/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java b/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
index 9472ded..0d2e540 100644
--- a/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/KeepaliveStatsTrackerTest.java
@@ -27,12 +27,15 @@
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
@@ -109,6 +112,18 @@
@Mock private KeepaliveStatsTracker.Dependencies mDependencies;
@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() {
final ArgumentCaptor<OnSubscriptionsChangedListener> listenerCaptor =
ArgumentCaptor.forClass(OnSubscriptionsChangedListener.class);
@@ -1128,4 +1143,53 @@
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
+ });
+ }
}