Merge "[SM10] Adopt helper class to monitor RAT type change per sub" into rvc-dev
This commit is contained in:
@@ -46,7 +46,6 @@ import static android.net.NetworkStats.UID_ALL;
|
||||
import static android.net.NetworkStatsHistory.FIELD_ALL;
|
||||
import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
|
||||
import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
|
||||
import static android.net.NetworkTemplate.getCollapsedRatType;
|
||||
import static android.net.TrafficStats.KB_IN_BYTES;
|
||||
import static android.net.TrafficStats.MB_IN_BYTES;
|
||||
import static android.os.Trace.TRACE_TAG_NETWORK;
|
||||
@@ -67,9 +66,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
|
||||
import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
|
||||
import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
|
||||
import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
|
||||
import static android.telephony.PhoneStateListener.LISTEN_NONE;
|
||||
import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE;
|
||||
import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
|
||||
import static android.text.format.DateUtils.DAY_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
@@ -133,9 +129,7 @@ import android.provider.Settings.Global;
|
||||
import android.service.NetworkInterfaceProto;
|
||||
import android.service.NetworkStatsServiceDumpProto;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionPlan;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
@@ -206,7 +200,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
private final NetworkStatsFactory mStatsFactory;
|
||||
private final AlarmManager mAlarmManager;
|
||||
private final Clock mClock;
|
||||
private final TelephonyManager mTeleManager;
|
||||
private final NetworkStatsSettings mSettings;
|
||||
private final NetworkStatsObservers mStatsObservers;
|
||||
|
||||
@@ -352,6 +345,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
@NonNull
|
||||
private final Dependencies mDeps;
|
||||
|
||||
@NonNull
|
||||
private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
|
||||
|
||||
private static @NonNull File getDefaultSystemDir() {
|
||||
return new File(Environment.getDataDirectory(), "system");
|
||||
}
|
||||
@@ -401,8 +397,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
PowerManager.WakeLock wakeLock =
|
||||
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||
|
||||
NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
|
||||
wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
|
||||
final NetworkStatsService service = new NetworkStatsService(context, networkManager,
|
||||
alarmManager, wakeLock, getDefaultClock(),
|
||||
new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
|
||||
new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
|
||||
new Dependencies());
|
||||
@@ -416,16 +412,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
@VisibleForTesting
|
||||
NetworkStatsService(Context context, INetworkManagementService networkManager,
|
||||
AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
|
||||
TelephonyManager teleManager, NetworkStatsSettings settings,
|
||||
NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
|
||||
File baseDir, @NonNull Dependencies deps) {
|
||||
NetworkStatsSettings settings, NetworkStatsFactory factory,
|
||||
NetworkStatsObservers statsObservers, File systemDir, File baseDir,
|
||||
@NonNull Dependencies deps) {
|
||||
mContext = Objects.requireNonNull(context, "missing Context");
|
||||
mNetworkManager = Objects.requireNonNull(networkManager,
|
||||
"missing INetworkManagementService");
|
||||
"missing INetworkManagementService");
|
||||
mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
|
||||
mClock = Objects.requireNonNull(clock, "missing Clock");
|
||||
mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
|
||||
mTeleManager = Objects.requireNonNull(teleManager, "missing TelephonyManager");
|
||||
mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
|
||||
mStatsFactory = Objects.requireNonNull(factory, "missing factory");
|
||||
mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
|
||||
@@ -437,7 +432,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
final HandlerThread handlerThread = mDeps.makeHandlerThread();
|
||||
handlerThread.start();
|
||||
mHandler = new NetworkStatsHandler(handlerThread.getLooper());
|
||||
mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler));
|
||||
mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
|
||||
new HandlerExecutor(mHandler), this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,6 +449,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
public HandlerThread makeHandlerThread() {
|
||||
return new HandlerThread(TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
|
||||
* event in NetworkStatsService.
|
||||
*/
|
||||
@NonNull
|
||||
public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
|
||||
@NonNull Executor executor, @NonNull NetworkStatsService service) {
|
||||
// TODO: Update RatType passively in NSS, instead of querying into the monitor
|
||||
// when forceUpdateIface.
|
||||
return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) ->
|
||||
service.handleOnCollapsedRatTypeChanged());
|
||||
}
|
||||
}
|
||||
|
||||
private void registerLocalService() {
|
||||
@@ -517,11 +526,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
|
||||
mSettings.getPollInterval(), pollIntent);
|
||||
|
||||
// TODO: 1. listen to changes from all subscriptions.
|
||||
// 2. listen to settings changed to support dynamically enable/disable.
|
||||
// TODO: listen to settings changed to support dynamically enable/disable.
|
||||
// watch for networkType changes
|
||||
if (!mSettings.getCombineSubtypeEnabled()) {
|
||||
mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE);
|
||||
mNetworkStatsSubscriptionsMonitor.start();
|
||||
}
|
||||
|
||||
registerGlobalAlert();
|
||||
@@ -544,7 +552,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
mContext.unregisterReceiver(mUserReceiver);
|
||||
mContext.unregisterReceiver(mShutdownReceiver);
|
||||
|
||||
mTeleManager.listen(mPhoneListener, LISTEN_NONE);
|
||||
if (!mSettings.getCombineSubtypeEnabled()) {
|
||||
mNetworkStatsSubscriptionsMonitor.stop();
|
||||
}
|
||||
|
||||
final long currentTime = mClock.millis();
|
||||
|
||||
@@ -1197,35 +1207,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
};
|
||||
|
||||
/**
|
||||
* Receiver that watches for {@link TelephonyManager} changes, such as
|
||||
* transitioning between Radio Access Technology(RAT) types.
|
||||
* Handle collapsed RAT type changed event.
|
||||
*/
|
||||
@NonNull
|
||||
private final NetworkTypeListener mPhoneListener;
|
||||
|
||||
class NetworkTypeListener extends PhoneStateListener {
|
||||
private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN;
|
||||
|
||||
NetworkTypeListener(@NonNull Executor executor) {
|
||||
super(executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(@NonNull ServiceState ss) {
|
||||
final int networkType = ss.getDataNetworkType();
|
||||
final int collapsedRatType = getCollapsedRatType(networkType);
|
||||
if (collapsedRatType == mLastCollapsedRatType) return;
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "subtype changed for mobile: "
|
||||
+ mLastCollapsedRatType + " -> " + collapsedRatType);
|
||||
}
|
||||
// Protect service from frequently updating. Remove pending messages if any.
|
||||
mHandler.removeMessages(MSG_UPDATE_IFACES);
|
||||
mLastCollapsedRatType = collapsedRatType;
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
|
||||
}
|
||||
@VisibleForTesting
|
||||
public void handleOnCollapsedRatTypeChanged() {
|
||||
// Protect service from frequently updating. Remove pending messages if any.
|
||||
mHandler.removeMessages(MSG_UPDATE_IFACES);
|
||||
mHandler.sendMessageDelayed(
|
||||
mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
|
||||
}
|
||||
|
||||
private void updateIfaces(
|
||||
@@ -1352,8 +1341,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: return different subType for different subscriptions.
|
||||
return mPhoneListener.mLastCollapsedRatType;
|
||||
return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId);
|
||||
}
|
||||
|
||||
private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
|
||||
|
||||
@@ -60,14 +60,13 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.usage.NetworkStatsManager;
|
||||
import android.content.Context;
|
||||
@@ -95,8 +94,6 @@ import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SimpleClock;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
@@ -126,6 +123,7 @@ import java.io.File;
|
||||
import java.time.Clock;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Tests for {@link NetworkStatsService}.
|
||||
@@ -168,14 +166,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
private @Mock NetworkStatsSettings mSettings;
|
||||
private @Mock IBinder mBinder;
|
||||
private @Mock AlarmManager mAlarmManager;
|
||||
private @Mock TelephonyManager mTelephonyManager;
|
||||
@Mock
|
||||
private NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
|
||||
private HandlerThread mHandlerThread;
|
||||
|
||||
private NetworkStatsService mService;
|
||||
private INetworkStatsSession mSession;
|
||||
private INetworkManagementEventObserver mNetworkObserver;
|
||||
@Nullable
|
||||
private PhoneStateListener mPhoneStateListener;
|
||||
|
||||
private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
|
||||
@Override
|
||||
@@ -203,8 +200,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
mHandlerThread = new HandlerThread("HandlerThread");
|
||||
final NetworkStatsService.Dependencies deps = makeDependencies();
|
||||
mService = new NetworkStatsService(mServiceContext, mNetManager, mAlarmManager, wakeLock,
|
||||
mClock, mTelephonyManager, mSettings,
|
||||
mStatsFactory, new NetworkStatsObservers(), mStatsDir, getBaseDir(mStatsDir), deps);
|
||||
mClock, mSettings, mStatsFactory, new NetworkStatsObservers(), mStatsDir,
|
||||
getBaseDir(mStatsDir), deps);
|
||||
|
||||
mElapsedRealtime = 0L;
|
||||
|
||||
@@ -224,12 +221,6 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
ArgumentCaptor.forClass(INetworkManagementEventObserver.class);
|
||||
verify(mNetManager).registerObserver(networkObserver.capture());
|
||||
mNetworkObserver = networkObserver.getValue();
|
||||
|
||||
// Capture the phone state listener that created by service.
|
||||
final ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
|
||||
ArgumentCaptor.forClass(PhoneStateListener.class);
|
||||
verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(), anyInt());
|
||||
mPhoneStateListener = phoneStateListenerCaptor.getValue();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -239,6 +230,14 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
public HandlerThread makeHandlerThread() {
|
||||
return mHandlerThread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(
|
||||
@NonNull Context context, @NonNull Executor executor,
|
||||
@NonNull NetworkStatsService service) {
|
||||
|
||||
return mNetworkStatsSubscriptionsMonitor;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -678,10 +677,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
|
||||
|
||||
// TODO: support per IMSI state
|
||||
private void setMobileRatTypeAndWaitForIdle(int ratType) {
|
||||
final ServiceState mockSs = mock(ServiceState.class);
|
||||
when(mockSs.getDataNetworkType()).thenReturn(ratType);
|
||||
mPhoneStateListener.onServiceStateChanged(mockSs);
|
||||
|
||||
when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
|
||||
.thenReturn(ratType);
|
||||
mService.handleOnCollapsedRatTypeChanged();
|
||||
HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user