Update AMS to use NetworkManagementInternal.isNetworkRestrictedForUid.
And add global setting WAIT_FOR_NETWORK_TIMEOUT_MS.
Bug: 27803922
Test: runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services
cts-tradefed run singleCommand cts-dev --module CtsHostsideNetworkTests -t com.android.cts.net.HostsideRestrictBackgroundNetworkTests
runtest -c android.provider.SettingsBackupTest frameworks-core
and manual
Change-Id: I6949cd517255670e2ce21ab2de24271082461b11
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 146d2d3..3864706 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9731,6 +9731,15 @@
public static final String RETAIL_DEMO_MODE_CONSTANTS = "retail_demo_mode_constants";
/**
+ * Indicates the maximum time that an app is blocked for the network rules to get updated.
+ *
+ * Type: long
+ *
+ * @hide
+ */
+ public static final String NETWORK_ACCESS_TIMEOUT_MS = "network_access_timeout_ms";
+
+ /**
* The reason for the settings database being downgraded. This is only for
* troubleshooting purposes and its value should not be interpreted in any way.
*
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 0cfdaf5..15fb7fa 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -327,6 +327,7 @@
Settings.Global.USE_GOOGLE_MAIL,
Settings.Global.VT_IMS_ENABLED,
Settings.Global.WAIT_FOR_DEBUGGER,
+ Settings.Global.NETWORK_ACCESS_TIMEOUT_MS,
Settings.Global.WARNING_TEMPERATURE,
Settings.Global.WEBVIEW_DATA_REDUCTION_PROXY_KEY,
Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5956923..98274c4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -54,6 +54,7 @@
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
+import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.provider.Settings.System.FONT_SCALE;
import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
@@ -359,6 +360,7 @@
import com.android.server.IntentResolver;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
+import com.android.server.NetworkManagementInternal;
import com.android.server.RescueParty;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
@@ -574,9 +576,9 @@
static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
/**
- * Indicates the maximum time spent waiting for the network rules to get updated.
+ * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
*/
- private static final long WAIT_FOR_NETWORK_TIMEOUT_MS = 2000; // 2 sec
+ private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 0; // 0 sec
/**
* State indicating that there is no need for any blocking for network.
@@ -751,6 +753,12 @@
final AppErrors mAppErrors;
+ /**
+ * Indicates the maximum time spent waiting for the network rules to get updated.
+ */
+ @VisibleForTesting
+ long mWaitForNetworkTimeoutMs;
+
public boolean canShowErrorDialogs() {
return mShowDialogs && !mSleeping && !mShuttingDown
&& !mKeyguardController.isKeyguardShowing();
@@ -13737,6 +13745,8 @@
final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
final boolean forceResizable = Settings.Global.getInt(
resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
+ final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
+ NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
final boolean supportsLeanbackOnly =
mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
@@ -13792,6 +13802,7 @@
mFullscreenThumbnailScale = res.getFraction(
com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
}
+ mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
}
}
@@ -22456,6 +22467,9 @@
@VisibleForTesting
@GuardedBy("this")
void incrementProcStateSeqAndNotifyAppsLocked() {
+ if (mWaitForNetworkTimeoutMs <= 0) {
+ return;
+ }
// Used for identifying which uids need to block for network.
ArrayList<Integer> blockingUids = null;
for (int i = mActiveUids.size() - 1; i >= 0; --i) {
@@ -23498,10 +23512,14 @@
}
final long startTime = SystemClock.uptimeMillis();
record.waitingForNetwork = true;
- record.lock.wait(WAIT_FOR_NETWORK_TIMEOUT_MS);
+ record.lock.wait(mWaitForNetworkTimeoutMs);
record.waitingForNetwork = false;
final long totalTime = SystemClock.uptimeMillis() - startTime;
- if (DEBUG_NETWORK || totalTime > WAIT_FOR_NETWORK_TIMEOUT_MS / 2) {
+ if (totalTime >= mWaitForNetworkTimeoutMs) {
+ Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
+ + totalTime + ". Uid: " + callingUid + " procStateSeq: "
+ + procStateSeq);
+ } else if (DEBUG_NETWORK || totalTime >= mWaitForNetworkTimeoutMs / 2) {
Slog.d(TAG_NETWORK, "Total time waited for network rules to get updated: "
+ totalTime + ". Uid: " + callingUid + " procStateSeq: "
+ procStateSeq);
@@ -23796,6 +23814,8 @@
@VisibleForTesting
public static class Injector {
+ private NetworkManagementInternal mNmi;
+
public AppOpsService getAppOpsService(File file, Handler handler) {
return new AppOpsService(file, handler);
}
@@ -23805,8 +23825,17 @@
}
public boolean isNetworkRestrictedForUid(int uid) {
- // TODO: add implementation
+ if (ensureHasNetworkManagementInternal()) {
+ return mNmi.isNetworkRestrictedForUid(uid);
+ }
return false;
}
+
+ private boolean ensureHasNetworkManagementInternal() {
+ if (mNmi == null) {
+ mNmi = LocalServices.getService(NetworkManagementInternal.class);
+ }
+ return mNmi != null;
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index cc5764b..b12da34 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -132,6 +132,7 @@
mHandler = new TestHandler(mHandlerThread.getLooper());
mInjector = new TestInjector();
mAms = new ActivityManagerService(mInjector);
+ mAms.mWaitForNetworkTimeoutMs = 100;
}
@After
@@ -217,6 +218,17 @@
44, // exptectedCurProcStateSeq
-1, // expectedBlockState, -1 to verify there are no interactions with main thread.
false); // expectNotify
+
+ // Verify when waitForNetworkTimeout is 0, then procStateSeq is not incremented.
+ mAms.mWaitForNetworkTimeoutMs = 0;
+ mInjector.setNetworkRestrictedForUid(true);
+ verifySeqCounterAndInteractions(uidRec,
+ PROCESS_STATE_TOP, // prevState
+ PROCESS_STATE_IMPORTANT_BACKGROUND, // curState
+ 44, // expectedGlobalCounter
+ 44, // exptectedCurProcStateSeq
+ -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+ false); // expectNotify
}
private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,