Update AMS to wait for network state update if requested by the main thread.

Bug: 27803922
Test: runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services
      runtest -c com.android.server.am.ActivityManagerInternalTest frameworks-services
      cts-tradefed run singleCommand cts-dev --module CtsHostsideNetworkTests
      and manual
Change-Id: I7d1052b9941c1fae51ff8ab1c9b89dca3919ccd2
This commit is contained in:
Sudheer Shanka
2017-03-08 18:19:01 -08:00
parent 3b1728642d
commit 84a4895c9c
7 changed files with 656 additions and 88 deletions

View File

@@ -204,6 +204,22 @@ public final class ActivityThread {
// Whether to invoke an activity callback after delivering new configuration.
private static final boolean REPORT_TO_ACTIVITY = true;
/**
* Denotes an invalid sequence number corresponding to a process state change.
*/
public static final long INVALID_PROC_STATE_SEQ = -1;
private final Object mNetworkPolicyLock = new Object();
/**
* Denotes the sequence number of the process state change for which the main thread needs
* to block until the network rules are updated for it.
*
* Value of {@link #INVALID_PROC_STATE_SEQ} indicates there is no need for blocking.
*/
@GuardedBy("mNetworkPolicyLock")
private long mNetworkBlockSeq = INVALID_PROC_STATE_SEQ;
private ContextImpl mSystemContext;
static volatile IPackageManager sPackageManager;
@@ -1324,6 +1340,18 @@ public final class ActivityThread {
}
}
/**
* Updates {@link #mNetworkBlockSeq}. This is used by ActivityManagerService to inform
* the main thread that it needs to wait for the network rules to get updated before
* launching an activity.
*/
@Override
public void setNetworkBlockSeq(long procStateSeq) {
synchronized (mNetworkPolicyLock) {
mNetworkBlockSeq = procStateSeq;
}
}
@Override
public void scheduleInstallProvider(ProviderInfo provider) {
sendMessage(H.INSTALL_PROVIDER, provider);
@@ -2698,6 +2726,7 @@ public final class ActivityThread {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
@@ -2764,6 +2793,22 @@ public final class ActivityThread {
return activity;
}
/**
* Checks if {@link #mNetworkBlockSeq} is {@link #INVALID_PROC_STATE_SEQ} and if so, returns
* immediately. Otherwise, makes a blocking call to ActivityManagerService to wait for the
* network rules to get updated.
*/
private void checkAndBlockForNetworkAccess() {
synchronized (mNetworkPolicyLock) {
if (mNetworkBlockSeq != INVALID_PROC_STATE_SEQ) {
try {
ActivityManager.getService().waitForNetworkStateUpdate(mNetworkBlockSeq);
mNetworkBlockSeq = INVALID_PROC_STATE_SEQ;
} catch (RemoteException ignored) {}
}
}
}
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
final int displayId;
try {

View File

@@ -607,6 +607,8 @@ interface IActivityManager {
void scheduleApplicationInfoChanged(in List<String> packageNames, int userId);
void setPersistentVrThread(int tid);
void waitForNetworkStateUpdate(long procStateSeq);
// WARNING: when these transactions are updated, check if they are any callers on the native
// side. If so, make sure they are using the correct transaction ids and arguments.
// If a transaction which will also be used on the native side is being inserted, add it

View File

@@ -154,4 +154,5 @@ oneway interface IApplicationThread {
void handleTrustStorageUpdate();
void attachAgent(String path);
void scheduleApplicationInfoChanged(in ApplicationInfo ai);
void setNetworkBlockSeq(long procStateSeq);
}