2-phase initialization of NetworkPolicyManagerService
Split systemReady() into 2 callbacks:
1) networkScoreAndNetworkManagementServiceReady - called when required
services are ready. NetworkPolicyManagerService starts its initialization
on the worker thread
2) systemReady - wait for phase (1) to finish so that the service is fully
initialized
NetworkPolicyManagerService is now prepared in parallel with
ConnectivityService and NetworkStatsService
Test: device boots without errors
Test: HostsideRestrictBackgroundNetworkTests and NetworkPolicyManagerServiceTest pass
Bug: 32315581
Change-Id: Ic9755ed096900247fa0bbb43f396d8bcb97ae6db
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 533307e..ac3a025 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -139,6 +139,7 @@
import android.os.MessageQueue.IdleHandler;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -197,6 +198,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* Service that maintains low-level network policy rules, using
@@ -565,9 +568,12 @@
}
}
- public void systemReady() {
+ private void initService(CountDownLatch initCompleteSignal) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "systemReady");
+ final int oldPriority = Process.getThreadPriority(Process.myTid());
try {
+ // Boost thread's priority during system server init
+ Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
if (!isBandwidthControlEnabled()) {
Slog.w(TAG, "bandwidth controls disabled, unable to enforce policy");
return;
@@ -672,11 +678,33 @@
mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
+ // tell systemReady() that the service has been initialized
+ initCompleteSignal.countDown();
} finally {
+ // Restore the default priority after init is done
+ Process.setThreadPriority(oldPriority);
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
}
}
+ public CountDownLatch networkScoreAndNetworkManagementServiceReady() {
+ final CountDownLatch initCompleteSignal = new CountDownLatch(1);
+ mHandler.post(() -> initService(initCompleteSignal));
+ return initCompleteSignal;
+ }
+
+ public void systemReady(CountDownLatch initCompleteSignal) {
+ // wait for initService to complete
+ try {
+ if (!initCompleteSignal.await(30, TimeUnit.SECONDS)) {
+ throw new IllegalStateException("Service " + TAG +" init timeout");
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException("Service " + TAG + " init interrupted", e);
+ }
+ }
+
final private IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override public void onUidStateChanged(int uid, int procState) throws RemoteException {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");