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