[BR06] Support check whether network is blocked by data saver
This change adds a DataSaverStatusTracker, which is a helper class to continuously track data saver status through NPMS public API and intents. ConnectivityManager#isUidNetworkingBlocked would use this cached information along with bpf maps to decide whether networking of an uid is blocked. Test: atest FrameworksNetTests:android.net.connectivity.android.net.BpfNetMapsReaderTest Test: atest ConnectivityCoverageTests:android.net.connectivity.android.net.ConnectivityManagerTest Bug: 297836825 Change-Id: I7e13191759430f3ea1f4dec7facc02f16be7146d
This commit is contained in:
@@ -16,6 +16,13 @@
|
||||
|
||||
package android.net;
|
||||
|
||||
import static android.content.Context.RECEIVER_NOT_EXPORTED;
|
||||
import static android.content.pm.ApplicationInfo.FLAG_PERSISTENT;
|
||||
import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
|
||||
import static android.net.ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED;
|
||||
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
|
||||
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
|
||||
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
|
||||
import static android.net.ConnectivityManager.TYPE_NONE;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
|
||||
@@ -39,6 +46,7 @@ import static android.net.NetworkRequest.Type.TRACK_SYSTEM_DEFAULT;
|
||||
|
||||
import static com.android.testutils.MiscAsserts.assertThrows;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@@ -51,6 +59,7 @@ import static org.mockito.Mockito.CALLS_REAL_METHODS;
|
||||
import static org.mockito.Mockito.after;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
@@ -61,7 +70,10 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.net.ConnectivityManager.DataSaverStatusTracker;
|
||||
import android.net.ConnectivityManager.NetworkCallback;
|
||||
import android.os.Build.VERSION_CODES;
|
||||
import android.os.Bundle;
|
||||
@@ -95,6 +107,7 @@ public class ConnectivityManagerTest {
|
||||
|
||||
@Mock Context mCtx;
|
||||
@Mock IConnectivityManager mService;
|
||||
@Mock NetworkPolicyManager mNpm;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -510,4 +523,54 @@ public class ConnectivityManagerTest {
|
||||
assertNull("ConnectivityManager weak reference still not null after " + attempts
|
||||
+ " attempts", ref.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSaverStatusTracker() {
|
||||
mockService(NetworkPolicyManager.class, Context.NETWORK_POLICY_SERVICE, mNpm);
|
||||
// Mock proper application info.
|
||||
doReturn(mCtx).when(mCtx).getApplicationContext();
|
||||
final ApplicationInfo mockAppInfo = new ApplicationInfo();
|
||||
mockAppInfo.flags = FLAG_PERSISTENT | FLAG_SYSTEM;
|
||||
doReturn(mockAppInfo).when(mCtx).getApplicationInfo();
|
||||
// Enable data saver.
|
||||
doReturn(RESTRICT_BACKGROUND_STATUS_ENABLED).when(mNpm)
|
||||
.getRestrictBackgroundStatus(anyInt());
|
||||
|
||||
final DataSaverStatusTracker tracker = new DataSaverStatusTracker(mCtx);
|
||||
// Verify the data saver status is correct right after initialization.
|
||||
assertTrue(tracker.getDataSaverEnabled());
|
||||
|
||||
// Verify the tracker register receiver with expected intent filter.
|
||||
final ArgumentCaptor<IntentFilter> intentFilterCaptor =
|
||||
ArgumentCaptor.forClass(IntentFilter.class);
|
||||
verify(mCtx).registerReceiver(
|
||||
any(), intentFilterCaptor.capture(), eq(RECEIVER_NOT_EXPORTED));
|
||||
assertEquals(ACTION_RESTRICT_BACKGROUND_CHANGED,
|
||||
intentFilterCaptor.getValue().getAction(0));
|
||||
|
||||
// Mock data saver status changed event and verify the tracker tracks the
|
||||
// status accordingly.
|
||||
doReturn(RESTRICT_BACKGROUND_STATUS_DISABLED).when(mNpm)
|
||||
.getRestrictBackgroundStatus(anyInt());
|
||||
tracker.onReceive(mCtx, new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED));
|
||||
assertFalse(tracker.getDataSaverEnabled());
|
||||
|
||||
doReturn(RESTRICT_BACKGROUND_STATUS_WHITELISTED).when(mNpm)
|
||||
.getRestrictBackgroundStatus(anyInt());
|
||||
tracker.onReceive(mCtx, new Intent(ACTION_RESTRICT_BACKGROUND_CHANGED));
|
||||
assertTrue(tracker.getDataSaverEnabled());
|
||||
}
|
||||
|
||||
private <T> void mockService(Class<T> clazz, String name, T service) {
|
||||
doReturn(service).when(mCtx).getSystemService(name);
|
||||
doReturn(name).when(mCtx).getSystemServiceName(clazz);
|
||||
|
||||
// If the test suite uses the inline mock maker library, such as for coverage tests,
|
||||
// then the final version of getSystemService must also be mocked, as the real
|
||||
// method will not be called by the test and null object is returned since no mock.
|
||||
// Otherwise, mocking a final method will fail the test.
|
||||
if (mCtx.getSystemService(clazz) == null) {
|
||||
doReturn(service).when(mCtx).getSystemService(clazz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user