Register OnSubscriptionsChangedListener and cache results.
Register a listener to get notified of SubscriptionInfo changes and store all carrierIds of active subscriptions in a cache. The executor for the listener callback runs on a different thread to the connectivity thread but posts the SubscriptionInfo list to the connectivity thread for caching. Bug: 273451360 Test: atest FrameworksNetTests Change-Id: I889d4da725ccda713367309c257622a0bf9939f3
This commit is contained in:
@@ -311,7 +311,7 @@ public class AutomaticOnOffKeepaliveTracker {
|
||||
mContext, mConnectivityServiceHandler);
|
||||
|
||||
mAlarmManager = mDependencies.getAlarmManager(context);
|
||||
mKeepaliveStatsTracker = new KeepaliveStatsTracker(handler);
|
||||
mKeepaliveStatsTracker = new KeepaliveStatsTracker(context, handler);
|
||||
}
|
||||
|
||||
private void startTcpPollingAlarm(@NonNull AutomaticOnOffKeepalive ki) {
|
||||
|
||||
@@ -16,14 +16,24 @@
|
||||
|
||||
package com.android.server.connectivity;
|
||||
|
||||
import static android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkSpecifier;
|
||||
import android.net.TelephonyNetworkSpecifier;
|
||||
import android.net.TransportInfo;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.metrics.DailykeepaliveInfoReported;
|
||||
@@ -31,6 +41,7 @@ import com.android.metrics.DurationForNumOfKeepalive;
|
||||
import com.android.metrics.DurationPerNumOfKeepalive;
|
||||
import com.android.metrics.KeepaliveLifetimeForCarrier;
|
||||
import com.android.metrics.KeepaliveLifetimePerCarrier;
|
||||
import com.android.modules.utils.BackgroundThread;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -52,6 +63,14 @@ public class KeepaliveStatsTracker {
|
||||
@NonNull private final Handler mConnectivityServiceHandler;
|
||||
@NonNull private final Dependencies mDependencies;
|
||||
|
||||
// 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.
|
||||
private int mCachedDefaultSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
// Class to store network information, lifetime durations and active state of a keepalive.
|
||||
private static final class KeepaliveStats {
|
||||
// The carrier ID for a keepalive, or TelephonyManager.UNKNOWN_CARRIER_ID(-1) if not set.
|
||||
@@ -214,16 +233,53 @@ public class KeepaliveStatsTracker {
|
||||
}
|
||||
}
|
||||
|
||||
public KeepaliveStatsTracker(@NonNull Handler handler) {
|
||||
this(handler, new Dependencies());
|
||||
public KeepaliveStatsTracker(@NonNull Context context, @NonNull Handler handler) {
|
||||
this(context, handler, new Dependencies());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public KeepaliveStatsTracker(@NonNull Handler handler, @NonNull Dependencies dependencies) {
|
||||
public KeepaliveStatsTracker(
|
||||
@NonNull Context context,
|
||||
@NonNull Handler handler,
|
||||
@NonNull Dependencies dependencies) {
|
||||
Objects.requireNonNull(context);
|
||||
mDependencies = Objects.requireNonNull(dependencies);
|
||||
mConnectivityServiceHandler = Objects.requireNonNull(handler);
|
||||
|
||||
final SubscriptionManager subscriptionManager =
|
||||
Objects.requireNonNull(context.getSystemService(SubscriptionManager.class));
|
||||
|
||||
mLastUpdateDurationsTimestamp = mDependencies.getUptimeMillis();
|
||||
|
||||
// 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,
|
||||
// this will throw. Therefore, post a runnable that creates it there.
|
||||
// When the callback is called on the BackgroundThread, post a message on the CS handler
|
||||
// thread to update the caches, which can only be touched there.
|
||||
BackgroundThread.getHandler().post(() ->
|
||||
subscriptionManager.addOnSubscriptionsChangedListener(
|
||||
r -> r.run(), new OnSubscriptionsChangedListener() {
|
||||
@Override
|
||||
public void onSubscriptionsChanged() {
|
||||
final List<SubscriptionInfo> activeSubInfoList =
|
||||
subscriptionManager.getActiveSubscriptionInfoList();
|
||||
// A null subInfo list here indicates the current state is unknown
|
||||
// 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(),
|
||||
subInfo.getCarrierId());
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/** Ensures the list of duration metrics is large enough for number of registered keepalives. */
|
||||
@@ -279,11 +335,33 @@ public class KeepaliveStatsTracker {
|
||||
mLastUpdateDurationsTimestamp = timeNow;
|
||||
}
|
||||
|
||||
// TODO(b/273451360): Make use of SubscriptionManager.OnSubscriptionsChangedListener since
|
||||
// TelephonyManager.getSimCarrierId will be a cross-process call.
|
||||
private int getCarrierId() {
|
||||
// No implementation yet.
|
||||
return TelephonyManager.UNKNOWN_CARRIER_ID;
|
||||
// TODO: Move this function to frameworks/libs/net/.../NetworkCapabilitiesUtils.java
|
||||
private static int getSubId(@NonNull NetworkCapabilities nc, int defaultSubId) {
|
||||
if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
|
||||
final NetworkSpecifier networkSpecifier = nc.getNetworkSpecifier();
|
||||
if (networkSpecifier instanceof TelephonyNetworkSpecifier) {
|
||||
return ((TelephonyNetworkSpecifier) networkSpecifier).getSubscriptionId();
|
||||
}
|
||||
// Use the default subscriptionId.
|
||||
return defaultSubId;
|
||||
}
|
||||
if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
|
||||
final TransportInfo info = nc.getTransportInfo();
|
||||
if (info instanceof WifiInfo) {
|
||||
return ((WifiInfo) info).getSubscriptionId();
|
||||
}
|
||||
}
|
||||
|
||||
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
}
|
||||
|
||||
private int getCarrierId(@NonNull NetworkCapabilities networkCapabilities) {
|
||||
// Try to get the correct subscription id.
|
||||
final int subId = getSubId(networkCapabilities, mCachedDefaultSubscriptionId);
|
||||
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
return TelephonyManager.UNKNOWN_CARRIER_ID;
|
||||
}
|
||||
return mCachedCarrierIdPerSubId.get(subId, TelephonyManager.UNKNOWN_CARRIER_ID);
|
||||
}
|
||||
|
||||
private int getTransportTypes(@NonNull NetworkCapabilities networkCapabilities) {
|
||||
@@ -313,7 +391,7 @@ public class KeepaliveStatsTracker {
|
||||
|
||||
final KeepaliveStats newKeepaliveStats =
|
||||
new KeepaliveStats(
|
||||
getCarrierId(), getTransportTypes(nc), intervalSeconds, timeNow);
|
||||
getCarrierId(nc), getTransportTypes(nc), intervalSeconds, timeNow);
|
||||
|
||||
mKeepaliveStatsPerId.put(keepaliveId, newKeepaliveStats);
|
||||
}
|
||||
|
||||
@@ -355,6 +355,7 @@ import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.security.Credentials;
|
||||
import android.system.Os;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.data.EpsBearerQosSessionAttributes;
|
||||
import android.telephony.data.NrQosSessionAttributes;
|
||||
@@ -616,6 +617,7 @@ public class ConnectivityServiceTest {
|
||||
@Mock BroadcastOptionsShim mBroadcastOptionsShim;
|
||||
@Mock ActivityManager mActivityManager;
|
||||
@Mock DestroySocketsWrapper mDestroySocketsWrapper;
|
||||
@Mock SubscriptionManager mSubscriptionManager;
|
||||
|
||||
// BatteryStatsManager is final and cannot be mocked with regular mockito, so just mock the
|
||||
// underlying binder calls.
|
||||
@@ -740,6 +742,7 @@ public class ConnectivityServiceTest {
|
||||
if (Context.PAC_PROXY_SERVICE.equals(name)) return mPacProxyManager;
|
||||
if (Context.TETHERING_SERVICE.equals(name)) return mTetheringManager;
|
||||
if (Context.ACTIVITY_SERVICE.equals(name)) return mActivityManager;
|
||||
if (Context.TELEPHONY_SUBSCRIPTION_SERVICE.equals(name)) return mSubscriptionManager;
|
||||
return super.getSystemService(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.longThat;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.ignoreStubs;
|
||||
@@ -67,6 +68,7 @@ import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -121,6 +123,7 @@ public class AutomaticOnOffKeepaliveTrackerTest {
|
||||
@Mock Context mCtx;
|
||||
@Mock AlarmManager mAlarmManager;
|
||||
@Mock NetworkAgentInfo mNai;
|
||||
@Mock SubscriptionManager mSubscriptionManager;
|
||||
|
||||
TestKeepaliveTracker mKeepaliveTracker;
|
||||
AOOTestHandler mTestHandler;
|
||||
@@ -298,10 +301,22 @@ public class AutomaticOnOffKeepaliveTrackerTest {
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void mockService(String serviceName, Class<T> serviceClass, T service) {
|
||||
doReturn(serviceName).when(mCtx).getSystemServiceName(serviceClass);
|
||||
doReturn(service).when(mCtx).getSystemService(serviceName);
|
||||
if (mCtx.getSystemService(serviceClass) == null) {
|
||||
// Test is using mockito-extended
|
||||
doCallRealMethod().when(mCtx).getSystemService(serviceClass);
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mockService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class,
|
||||
mSubscriptionManager);
|
||||
|
||||
mNai.networkCapabilities =
|
||||
new NetworkCapabilities.Builder().addTransportType(TRANSPORT_CELLULAR).build();
|
||||
mNai.networkInfo = new NetworkInfo(TYPE_MOBILE, 0 /* subtype */, "LTE", "LTE");
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.connectivity;
|
||||
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
|
||||
import static com.android.testutils.HandlerUtils.visibleOnHandlerThread;
|
||||
|
||||
@@ -25,13 +26,24 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
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.Context;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.TelephonyNetworkSpecifier;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
@@ -41,39 +53,68 @@ import com.android.metrics.DurationForNumOfKeepalive;
|
||||
import com.android.metrics.DurationPerNumOfKeepalive;
|
||||
import com.android.metrics.KeepaliveLifetimeForCarrier;
|
||||
import com.android.metrics.KeepaliveLifetimePerCarrier;
|
||||
import com.android.modules.utils.BackgroundThread;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRunner;
|
||||
import com.android.testutils.HandlerUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(DevSdkIgnoreRunner.class)
|
||||
@SmallTest
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
|
||||
public class KeepaliveStatsTrackerTest {
|
||||
private static final int TIMEOUT_MS = 30_000;
|
||||
|
||||
private static final int TEST_SLOT = 1;
|
||||
private static final int TEST_SLOT2 = 2;
|
||||
private static final int TEST_KEEPALIVE_INTERVAL_SEC = 10;
|
||||
private static final int TEST_KEEPALIVE_INTERVAL2_SEC = 20;
|
||||
// Carrier id not yet implemented, assume it returns unknown for now.
|
||||
private static final int TEST_CARRIER_ID = TelephonyManager.UNKNOWN_CARRIER_ID;
|
||||
private static final int TEST_SUB_ID_1 = 1;
|
||||
private static final int TEST_SUB_ID_2 = 2;
|
||||
private static final int TEST_CARRIER_ID_1 = 135;
|
||||
private static final int TEST_CARRIER_ID_2 = 246;
|
||||
private static final Network TEST_NETWORK = new Network(123);
|
||||
private static final NetworkCapabilities TEST_NETWORK_CAPABILITIES =
|
||||
new NetworkCapabilities.Builder().addTransportType(TRANSPORT_CELLULAR).build();
|
||||
buildCellNetworkCapabilitiesWithSubId(TEST_SUB_ID_1);
|
||||
private static final NetworkCapabilities TEST_NETWORK_CAPABILITIES_2 =
|
||||
buildCellNetworkCapabilitiesWithSubId(TEST_SUB_ID_2);
|
||||
|
||||
private static NetworkCapabilities buildCellNetworkCapabilitiesWithSubId(int subId) {
|
||||
final TelephonyNetworkSpecifier telephonyNetworkSpecifier =
|
||||
new TelephonyNetworkSpecifier.Builder().setSubscriptionId(subId).build();
|
||||
return new NetworkCapabilities.Builder()
|
||||
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
||||
.setNetworkSpecifier(telephonyNetworkSpecifier)
|
||||
.build();
|
||||
}
|
||||
|
||||
private HandlerThread mHandlerThread;
|
||||
private Handler mTestHandler;
|
||||
|
||||
private KeepaliveStatsTracker mKeepaliveStatsTracker;
|
||||
|
||||
@Mock private Context mContext;
|
||||
@Mock private KeepaliveStatsTracker.Dependencies mDependencies;
|
||||
@Mock private SubscriptionManager mSubscriptionManager;
|
||||
|
||||
private OnSubscriptionsChangedListener getOnSubscriptionsChangedListener() {
|
||||
final ArgumentCaptor<OnSubscriptionsChangedListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(OnSubscriptionsChangedListener.class);
|
||||
verify(mSubscriptionManager)
|
||||
.addOnSubscriptionsChangedListener(any(), listenerCaptor.capture());
|
||||
return listenerCaptor.getValue();
|
||||
}
|
||||
|
||||
private static final class KeepaliveCarrierStats {
|
||||
public final int carrierId;
|
||||
@@ -116,23 +157,53 @@ public class KeepaliveStatsTrackerTest {
|
||||
// Use the default test carrier id, transportType and keepalive interval.
|
||||
private KeepaliveCarrierStats getDefaultCarrierStats(int lifetimeMs, int activeLifetimeMs) {
|
||||
return new KeepaliveCarrierStats(
|
||||
TEST_CARRIER_ID,
|
||||
TEST_CARRIER_ID_1,
|
||||
/* transportTypes= */ (1 << TRANSPORT_CELLULAR),
|
||||
TEST_KEEPALIVE_INTERVAL_SEC * 1000,
|
||||
lifetimeMs,
|
||||
activeLifetimeMs);
|
||||
}
|
||||
|
||||
private <T> void mockService(String serviceName, Class<T> serviceClass, T service) {
|
||||
doReturn(serviceName).when(mContext).getSystemServiceName(serviceClass);
|
||||
doReturn(service).when(mContext).getSystemService(serviceName);
|
||||
if (mContext.getSystemService(serviceClass) == null) {
|
||||
// Test is using mockito-extended
|
||||
doCallRealMethod().when(mContext).getSystemService(serviceClass);
|
||||
}
|
||||
}
|
||||
|
||||
private SubscriptionInfo makeSubInfoMock(int subId, int carrierId) {
|
||||
final SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
|
||||
doReturn(subId).when(subInfo).getSubscriptionId();
|
||||
doReturn(carrierId).when(subInfo).getCarrierId();
|
||||
return subInfo;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mockService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class,
|
||||
mSubscriptionManager);
|
||||
|
||||
final SubscriptionInfo subInfo1 = makeSubInfoMock(TEST_SUB_ID_1, TEST_CARRIER_ID_1);
|
||||
final SubscriptionInfo subInfo2 = makeSubInfoMock(TEST_SUB_ID_2, TEST_CARRIER_ID_2);
|
||||
|
||||
doReturn(List.of(subInfo1, subInfo2))
|
||||
.when(mSubscriptionManager)
|
||||
.getActiveSubscriptionInfoList();
|
||||
|
||||
mHandlerThread = new HandlerThread("KeepaliveStatsTrackerTest");
|
||||
mHandlerThread.start();
|
||||
mTestHandler = new Handler(mHandlerThread.getLooper());
|
||||
|
||||
setUptimeMillis(0);
|
||||
mKeepaliveStatsTracker = new KeepaliveStatsTracker(mTestHandler, mDependencies);
|
||||
mKeepaliveStatsTracker = new KeepaliveStatsTracker(mContext, mTestHandler, mDependencies);
|
||||
HandlerUtils.waitForIdle(BackgroundThread.getHandler(), TIMEOUT_MS);
|
||||
|
||||
// Initial onSubscriptionsChanged.
|
||||
getOnSubscriptionsChangedListener().onSubscriptionsChanged();
|
||||
HandlerUtils.waitForIdle(mTestHandler, TIMEOUT_MS);
|
||||
}
|
||||
|
||||
private void setUptimeMillis(long time) {
|
||||
@@ -158,13 +229,18 @@ public class KeepaliveStatsTrackerTest {
|
||||
}
|
||||
|
||||
private void onStartKeepalive(long time, int slot, int intervalSeconds) {
|
||||
onStartKeepalive(time, slot, TEST_NETWORK_CAPABILITIES, intervalSeconds);
|
||||
}
|
||||
|
||||
private void onStartKeepalive(long time, int slot, NetworkCapabilities nc) {
|
||||
onStartKeepalive(time, slot, nc, TEST_KEEPALIVE_INTERVAL_SEC);
|
||||
}
|
||||
|
||||
private void onStartKeepalive(
|
||||
long time, int slot, NetworkCapabilities nc, int intervalSeconds) {
|
||||
setUptimeMillis(time);
|
||||
visibleOnHandlerThread(mTestHandler, () ->
|
||||
mKeepaliveStatsTracker.onStartKeepalive(
|
||||
TEST_NETWORK,
|
||||
slot,
|
||||
TEST_NETWORK_CAPABILITIES,
|
||||
intervalSeconds));
|
||||
mKeepaliveStatsTracker.onStartKeepalive(TEST_NETWORK, slot, nc, intervalSeconds));
|
||||
}
|
||||
|
||||
private void onPauseKeepalive(long time, int slot) {
|
||||
@@ -732,7 +808,8 @@ public class KeepaliveStatsTrackerTest {
|
||||
|
||||
onStartKeepalive(startTime1, TEST_SLOT);
|
||||
|
||||
onStartKeepalive(startTime2, TEST_SLOT2, TEST_KEEPALIVE_INTERVAL2_SEC);
|
||||
onStartKeepalive(startTime2, TEST_SLOT2, TEST_NETWORK_CAPABILITIES_2,
|
||||
TEST_KEEPALIVE_INTERVAL2_SEC);
|
||||
|
||||
onStopKeepalive(stopTime1, TEST_SLOT);
|
||||
|
||||
@@ -759,7 +836,7 @@ public class KeepaliveStatsTrackerTest {
|
||||
getDefaultCarrierStats(stopTime1 - startTime1, stopTime1 - startTime1);
|
||||
final KeepaliveCarrierStats expectKeepaliveCarrierStats2 =
|
||||
new KeepaliveCarrierStats(
|
||||
TEST_CARRIER_ID,
|
||||
TEST_CARRIER_ID_2,
|
||||
/* transportTypes= */ (1 << TRANSPORT_CELLULAR),
|
||||
TEST_KEEPALIVE_INTERVAL2_SEC * 1000,
|
||||
writeTime - startTime2,
|
||||
@@ -783,7 +860,7 @@ public class KeepaliveStatsTrackerTest {
|
||||
// Only the keepalive with interval of intervalSec2 is present.
|
||||
final KeepaliveCarrierStats expectKeepaliveCarrierStats3 =
|
||||
new KeepaliveCarrierStats(
|
||||
TEST_CARRIER_ID,
|
||||
TEST_CARRIER_ID_2,
|
||||
/* transportTypes= */ (1 << TRANSPORT_CELLULAR),
|
||||
TEST_KEEPALIVE_INTERVAL2_SEC * 1000,
|
||||
writeTime2 - writeTime,
|
||||
@@ -861,4 +938,86 @@ public class KeepaliveStatsTrackerTest {
|
||||
getDefaultCarrierStats(expectRegisteredDurations[1], expectActiveDurations[1])
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierIdChange_changeBeforeStart() {
|
||||
// Update the list to only have sub_id_2 with carrier_id_1.
|
||||
final SubscriptionInfo subInfo = makeSubInfoMock(TEST_SUB_ID_2, TEST_CARRIER_ID_1);
|
||||
doReturn(List.of(subInfo)).when(mSubscriptionManager).getActiveSubscriptionInfoList();
|
||||
|
||||
getOnSubscriptionsChangedListener().onSubscriptionsChanged();
|
||||
HandlerUtils.waitForIdle(mTestHandler, TIMEOUT_MS);
|
||||
|
||||
final int startTime = 1000;
|
||||
final int writeTime = 5000;
|
||||
|
||||
onStartKeepalive(startTime, TEST_SLOT, TEST_NETWORK_CAPABILITIES);
|
||||
onStartKeepalive(startTime, TEST_SLOT2, TEST_NETWORK_CAPABILITIES_2);
|
||||
|
||||
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
|
||||
buildKeepaliveMetrics(writeTime);
|
||||
|
||||
// The network with sub_id_1 has an unknown carrier id.
|
||||
final KeepaliveCarrierStats expectKeepaliveCarrierStats1 =
|
||||
new KeepaliveCarrierStats(
|
||||
TelephonyManager.UNKNOWN_CARRIER_ID,
|
||||
/* transportTypes= */ (1 << TRANSPORT_CELLULAR),
|
||||
TEST_KEEPALIVE_INTERVAL_SEC * 1000,
|
||||
writeTime - startTime,
|
||||
writeTime - startTime);
|
||||
|
||||
// The network with sub_id_2 has carrier_id_1.
|
||||
final KeepaliveCarrierStats expectKeepaliveCarrierStats2 =
|
||||
new KeepaliveCarrierStats(
|
||||
TEST_CARRIER_ID_1,
|
||||
/* transportTypes= */ (1 << TRANSPORT_CELLULAR),
|
||||
TEST_KEEPALIVE_INTERVAL_SEC * 1000,
|
||||
writeTime - startTime,
|
||||
writeTime - startTime);
|
||||
assertDailyKeepaliveInfoReported(
|
||||
dailyKeepaliveInfoReported,
|
||||
/* expectRegisteredDurations= */ new int[] {startTime, 0, writeTime - startTime},
|
||||
/* expectActiveDurations= */ new int[] {startTime, 0, writeTime - startTime},
|
||||
new KeepaliveCarrierStats[] {
|
||||
expectKeepaliveCarrierStats1, expectKeepaliveCarrierStats2
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCarrierIdFromWifiInfo() {
|
||||
final int startTime = 1000;
|
||||
final int writeTime = 5000;
|
||||
|
||||
final WifiInfo wifiInfo = mock(WifiInfo.class);
|
||||
final WifiInfo wifiInfoCopy = mock(WifiInfo.class);
|
||||
|
||||
// Building NetworkCapabilities stores a copy of the WifiInfo with makeCopy.
|
||||
doReturn(wifiInfoCopy).when(wifiInfo).makeCopy(anyLong());
|
||||
doReturn(TEST_SUB_ID_1).when(wifiInfo).getSubscriptionId();
|
||||
doReturn(TEST_SUB_ID_1).when(wifiInfoCopy).getSubscriptionId();
|
||||
final NetworkCapabilities nc =
|
||||
new NetworkCapabilities.Builder()
|
||||
.addTransportType(TRANSPORT_WIFI)
|
||||
.setTransportInfo(wifiInfo)
|
||||
.build();
|
||||
|
||||
onStartKeepalive(startTime, TEST_SLOT, nc);
|
||||
|
||||
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
|
||||
buildKeepaliveMetrics(writeTime);
|
||||
|
||||
final KeepaliveCarrierStats expectKeepaliveCarrierStats =
|
||||
new KeepaliveCarrierStats(
|
||||
TEST_CARRIER_ID_1,
|
||||
/* transportTypes= */ (1 << TRANSPORT_WIFI),
|
||||
TEST_KEEPALIVE_INTERVAL_SEC * 1000,
|
||||
writeTime - startTime,
|
||||
writeTime - startTime);
|
||||
|
||||
assertDailyKeepaliveInfoReported(
|
||||
dailyKeepaliveInfoReported,
|
||||
/* expectRegisteredDurations= */ new int[] {startTime, writeTime - startTime},
|
||||
/* expectActiveDurations= */ new int[] {startTime, writeTime - startTime},
|
||||
new KeepaliveCarrierStats[] {expectKeepaliveCarrierStats});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user