From 54e0676d19b757e48323bf1ba7ccccbf3080de9c Mon Sep 17 00:00:00 2001 From: Hansen Kurli Date: Thu, 8 Jun 2023 07:53:26 +0000 Subject: [PATCH] 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 --- .../connectivity/KeepaliveStatsTracker.java | 23 +++++-- .../KeepaliveStatsTrackerTest.java | 64 +++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java b/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java index f9213d790a..d59d5263a4 100644 --- a/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java +++ b/service/src/com/android/server/connectivity/KeepaliveStatsTracker.java @@ -19,7 +19,10 @@ package com.android.server.connectivity; 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 @@ public class KeepaliveStatsTracker { // 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 @@ public class KeepaliveStatsTracker { 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 @@ public class KeepaliveStatsTracker { // 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 9472ded79a..0d2e540957 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.assertThrows; 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 @@ public class KeepaliveStatsTrackerTest { @Mock private KeepaliveStatsTracker.Dependencies mDependencies; @Mock private SubscriptionManager mSubscriptionManager; + private void triggerBroadcastDefaultSubId(int subId) { + final ArgumentCaptor 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 listenerCaptor = ArgumentCaptor.forClass(OnSubscriptionsChangedListener.class); @@ -1128,4 +1143,53 @@ public class KeepaliveStatsTrackerTest { 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 + }); + } }