Ignore older UID state change callbacks in NPMS. am: efa4f74236

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2065618

Change-Id: I4ca5a51080facb1bb42aacd0074649e881589c88
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Sudheer Shanka
2022-04-15 18:17:51 +00:00
committed by Automerger Merge Worker
9 changed files with 94 additions and 219 deletions

View File

@@ -817,11 +817,13 @@ public class NetworkPolicyManager {
public static final class UidState {
public int uid;
public int procState;
public long procStateSeq;
public int capability;
public UidState(int uid, int procState, int capability) {
public UidState(int uid, int procState, long procStateSeq, int capability) {
this.uid = uid;
this.procState = procState;
this.procStateSeq = procStateSeq;
this.capability = capability;
}
@@ -830,6 +832,8 @@ public class NetworkPolicyManager {
final StringBuilder sb = new StringBuilder();
sb.append("{procState=");
sb.append(procStateToString(procState));
sb.append(",seq=");
sb.append(procStateSeq);
sb.append(",cap=");
ActivityManager.printCapabilitiesSummary(sb, capability);
sb.append("}");

View File

@@ -14472,7 +14472,6 @@ public class ActivityManagerService extends IActivityManager.Stub
uid, change, procState, procStateSeq, capability, ephemeral);
if (uidRec != null) {
uidRec.setLastReportedChange(enqueuedChange);
uidRec.updateLastDispatchedProcStateSeq(enqueuedChange);
}
// Directly update the power manager, since we sit on top of it and it is critical
@@ -15610,18 +15609,13 @@ public class ActivityManagerService extends IActivityManager.Stub
return;
}
record.lastNetworkUpdatedProcStateSeq = procStateSeq;
if (record.curProcStateSeq > procStateSeq) {
if (DEBUG_NETWORK) {
Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
+ ", curProcstateSeq: " + record.curProcStateSeq
+ ", procStateSeq: " + procStateSeq);
}
return;
}
if (record.waitingForNetwork) {
if (record.procStateSeqWaitingForNetwork != 0
&& procStateSeq >= record.procStateSeqWaitingForNetwork) {
if (DEBUG_NETWORK) {
Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
+ ", procStateSeq: " + procStateSeq);
+ ", procStateSeq: " + procStateSeq
+ ", procStateSeqWaitingForNetwork: "
+ record.procStateSeqWaitingForNetwork);
}
record.networkStateLock.notifyAll();
}
@@ -16336,7 +16330,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (mNetworkPolicyUidObserver != null) {
try {
mNetworkPolicyUidObserver.onUidStateChanged(uid, PROCESS_STATE_TOP,
mProcessList.getProcStateSeqCounter(), PROCESS_CAPABILITY_ALL);
mProcessList.getNextProcStateSeq(), PROCESS_CAPABILITY_ALL);
} catch (RemoteException e) {
// Should not happen; call is within the same process
}
@@ -16574,23 +16568,6 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
synchronized (record.networkStateLock) {
if (record.lastDispatchedProcStateSeq < procStateSeq) {
if (DEBUG_NETWORK) {
Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
+ "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
+ " lastProcStateSeqDispatchedToObservers: "
+ record.lastDispatchedProcStateSeq);
}
return;
}
if (record.curProcStateSeq > procStateSeq) {
if (DEBUG_NETWORK) {
Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
+ callingUid + ", curProcStateSeq: " + record.curProcStateSeq
+ ", procStateSeq: " + procStateSeq);
}
return;
}
if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
if (DEBUG_NETWORK) {
Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
@@ -16606,9 +16583,9 @@ public class ActivityManagerService extends IActivityManager.Stub
+ " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
}
final long startTime = SystemClock.uptimeMillis();
record.waitingForNetwork = true;
record.procStateSeqWaitingForNetwork = procStateSeq;
record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
record.waitingForNetwork = false;
record.procStateSeqWaitingForNetwork = 0;
final long totalTime = SystemClock.uptimeMillis() - startTime;
if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
Slog.w(TAG_NETWORK, "Total time waited for network rules to get updated: "

View File

@@ -4877,13 +4877,17 @@ public final class ProcessList {
}
/**
* Checks if any uid is coming from background to foreground or vice versa and if so, increments
* the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
* {@link ProcessList#mProcStateSeqCounter} and notifies the app if it needs to block.
* Increments the {@link UidRecord#curProcStateSeq} for all uids using global seq counter
* {@link ProcessList#mProcStateSeqCounter} and checks if any uid is coming
* from background to foreground or vice versa and if so, notifies the app if it needs to block.
*/
@VisibleForTesting
@GuardedBy(anyOf = {"mService", "mProcLock"})
void incrementProcStateSeqAndNotifyAppsLOSP(ActiveUids activeUids) {
for (int i = activeUids.size() - 1; i >= 0; --i) {
final UidRecord uidRec = activeUids.valueAt(i);
uidRec.curProcStateSeq = getNextProcStateSeq();
}
if (mService.mWaitForNetworkTimeoutMs <= 0) {
return;
}
@@ -4910,7 +4914,6 @@ public final class ProcessList {
continue;
}
synchronized (uidRec.networkStateLock) {
uidRec.curProcStateSeq = ++mProcStateSeqCounter; // TODO: use method
if (blockState == NETWORK_STATE_BLOCK) {
if (blockingUids == null) {
blockingUids = new ArrayList<>();
@@ -4921,7 +4924,7 @@ public final class ProcessList {
Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
+ " threads for uid: " + uidRec);
}
if (uidRec.waitingForNetwork) {
if (uidRec.procStateSeqWaitingForNetwork != 0) {
uidRec.networkStateLock.notifyAll();
}
}
@@ -4955,8 +4958,8 @@ public final class ProcessList {
}
}
long getProcStateSeqCounter() {
return mProcStateSeqCounter;
long getNextProcStateSeq() {
return ++mProcStateSeqCounter;
}
/**

View File

@@ -219,7 +219,6 @@ public class UidObserverController {
validateUid.setCurProcState(item.procState);
validateUid.setSetCapability(item.capability);
validateUid.setCurCapability(item.capability);
validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
}
}
}

View File

@@ -95,16 +95,9 @@ public final class UidRecord {
long lastNetworkUpdatedProcStateSeq;
/**
* Last seq number for which AcitivityManagerService dispatched uid state change to
* NetworkPolicyManagerService.
* Indicates if any thread is waiting for network rules to get updated for {@link #mUid}.
*/
@GuardedBy("networkStateUpdate")
long lastDispatchedProcStateSeq;
/**
* Indicates if any thread is waiting for network rules to get updated for {@link #uid}.
*/
volatile boolean waitingForNetwork;
volatile long procStateSeqWaitingForNetwork;
/**
* Indicates whether this uid has internet permission or not.
@@ -309,18 +302,6 @@ public final class UidRecord {
mUid) == PackageManager.PERMISSION_GRANTED;
}
/**
* If the change being dispatched is not CHANGE_GONE (not interested in
* these changes), then update the {@link #lastDispatchedProcStateSeq} with
* {@link #curProcStateSeq}.
*/
public void updateLastDispatchedProcStateSeq(int changeToDispatch) {
if ((changeToDispatch & CHANGE_GONE) == 0) {
lastDispatchedProcStateSeq = curProcStateSeq;
}
}
void dumpDebug(ProtoOutputStream proto, long fieldId) {
long token = proto.start(fieldId);
proto.write(UidRecordProto.UID, mUid);
@@ -341,7 +322,6 @@ public final class UidRecord {
proto.write(UidRecordProto.ProcStateSequence.CURURENT, curProcStateSeq);
proto.write(UidRecordProto.ProcStateSequence.LAST_NETWORK_UPDATED,
lastNetworkUpdatedProcStateSeq);
proto.write(UidRecordProto.ProcStateSequence.LAST_DISPATCHED, lastDispatchedProcStateSeq);
proto.end(seqToken);
proto.end(token);
@@ -412,8 +392,6 @@ public final class UidRecord {
sb.append(curProcStateSeq);
sb.append(",");
sb.append(lastNetworkUpdatedProcStateSeq);
sb.append(",");
sb.append(lastDispatchedProcStateSeq);
sb.append(")}");
return sb.toString();
}

View File

@@ -28,6 +28,7 @@ import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
import static android.app.ActivityManager.PROCESS_STATE_UNKNOWN;
import static android.app.ActivityManager.isProcStateConsideredInteraction;
import static android.app.ActivityManager.procStateToString;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
@@ -1123,7 +1124,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
callbackInfo = new UidStateCallbackInfo();
mUidStateCallbackInfos.put(uid, callbackInfo);
}
callbackInfo.update(uid, procState, procStateSeq, capability);
if (callbackInfo.procStateSeq == -1 || procStateSeq > callbackInfo.procStateSeq) {
callbackInfo.update(uid, procState, procStateSeq, capability);
}
if (!callbackInfo.isPending) {
mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED, callbackInfo)
.sendToTarget();
@@ -1147,8 +1150,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private static final class UidStateCallbackInfo {
public int uid;
public int procState;
public long procStateSeq;
public int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
public long procStateSeq = -1;
@ProcessCapability
public int capability;
public boolean isPending;
@@ -4058,13 +4061,22 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* {@link #updateRulesForPowerRestrictionsUL(int)}. Returns true if the state was updated.
*/
@GuardedBy("mUidRulesFirstLock")
private boolean updateUidStateUL(int uid, int procState, @ProcessCapability int capability) {
private boolean updateUidStateUL(int uid, int procState, long procStateSeq,
@ProcessCapability int capability) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateUidStateUL");
try {
final UidState oldUidState = mUidState.get(uid);
if (oldUidState != null && procStateSeq < oldUidState.procStateSeq) {
if (LOGV) {
Slog.v(TAG, "Ignoring older uid state updates; uid=" + uid
+ ",procState=" + procStateToString(procState) + ",seq=" + procStateSeq
+ ",cap=" + capability + ",oldUidState=" + oldUidState);
}
return false;
}
if (oldUidState == null || oldUidState.procState != procState
|| oldUidState.capability != capability) {
final UidState newUidState = new UidState(uid, procState, capability);
final UidState newUidState = new UidState(uid, procState, procStateSeq, capability);
// state changed, push updated rules
mUidState.put(uid, newUidState);
updateRestrictBackgroundRulesOnUidStatusChangedUL(uid, oldUidState, newUidState);
@@ -4811,6 +4823,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
synchronized (mUidBlockedState) {
mUidBlockedState.delete(uid);
}
mUidState.delete(uid);
mUidPolicy.delete(uid);
mUidFirewallStandbyRules.delete(uid);
mUidFirewallDozableRules.delete(uid);
@@ -5452,21 +5465,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
public boolean handleMessage(Message msg) {
switch (msg.what) {
case UID_MSG_STATE_CHANGED: {
final UidStateCallbackInfo uidStateCallbackInfo =
(UidStateCallbackInfo) msg.obj;
final int uid;
final int procState;
final long procStateSeq;
final int capability;
synchronized (mUidStateCallbackInfos) {
uid = uidStateCallbackInfo.uid;
procState = uidStateCallbackInfo.procState;
procStateSeq = uidStateCallbackInfo.procStateSeq;
capability = uidStateCallbackInfo.capability;
uidStateCallbackInfo.isPending = false;
}
handleUidChanged(uid, procState, procStateSeq, capability);
handleUidChanged((UidStateCallbackInfo) msg.obj);
return true;
}
case UID_MSG_GONE: {
@@ -5481,17 +5480,28 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
};
void handleUidChanged(int uid, int procState, long procStateSeq,
@ProcessCapability int capability) {
void handleUidChanged(@NonNull UidStateCallbackInfo uidStateCallbackInfo) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidStateChanged");
try {
boolean updated;
final int uid;
final int procState;
final long procStateSeq;
final int capability;
synchronized (mUidRulesFirstLock) {
synchronized (mUidStateCallbackInfos) {
uid = uidStateCallbackInfo.uid;
procState = uidStateCallbackInfo.procState;
procStateSeq = uidStateCallbackInfo.procStateSeq;
capability = uidStateCallbackInfo.capability;
uidStateCallbackInfo.isPending = false;
}
// We received a uid state change callback, add it to the history so that it
// will be useful for debugging.
mLogger.uidStateChanged(uid, procState, procStateSeq, capability);
// Now update the network policy rules as per the updated uid state.
updated = updateUidStateUL(uid, procState, capability);
updated = updateUidStateUL(uid, procState, procStateSeq, capability);
// Updating the network rules is done, so notify AMS about this.
mActivityManagerInternal.notifyNetworkPolicyRulesUpdated(uid, procStateSeq);
}

View File

@@ -129,7 +129,7 @@ public class ActivityManagerInternalTest {
thread2.assertWaiting("Unexpected state for " + record2);
thread2.interrupt();
mAms.mProcessList.mActiveUids.clear();
clearActiveUids();
}
private UidRecord addActiveUidRecord(int uid, long curProcStateSeq,
@@ -137,11 +137,21 @@ public class ActivityManagerInternalTest {
final UidRecord record = new UidRecord(uid, mAms);
record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
record.curProcStateSeq = curProcStateSeq;
record.waitingForNetwork = true;
mAms.mProcessList.mActiveUids.put(uid, record);
record.procStateSeqWaitingForNetwork = 1;
addActiveUidRecord(uid, record);
return record;
}
@SuppressWarnings("GuardedBy")
private void addActiveUidRecord(int uid, UidRecord record) {
mAms.mProcessList.mActiveUids.put(uid, record);
}
@SuppressWarnings("GuardedBy")
private void clearActiveUids() {
mAms.mProcessList.mActiveUids.clear();
}
static class CustomThread extends Thread {
private static final long WAIT_TIMEOUT_MS = 1000;
private static final long WAIT_INTERVAL_MS = 100;

View File

@@ -191,8 +191,6 @@ public class ActivityManagerServiceTest {
verifySeqCounterAndInteractions(uidRec,
PROCESS_STATE_TOP, // prevState
PROCESS_STATE_TOP, // curState
0, // expectedGlobalCounter
0, // exptectedCurProcStateSeq
NETWORK_STATE_NO_CHANGE, // expectedBlockState
false); // expectNotify
@@ -200,8 +198,6 @@ public class ActivityManagerServiceTest {
verifySeqCounterAndInteractions(uidRec,
PROCESS_STATE_FOREGROUND_SERVICE, // prevState
PROCESS_STATE_SERVICE, // curState
1, // expectedGlobalCounter
1, // exptectedCurProcStateSeq
NETWORK_STATE_UNBLOCK, // expectedBlockState
true); // expectNotify
@@ -213,8 +209,6 @@ public class ActivityManagerServiceTest {
verifySeqCounterAndInteractions(uidRec,
PROCESS_STATE_TRANSIENT_BACKGROUND, // prevState
PROCESS_STATE_IMPORTANT_BACKGROUND, // curState
42, // expectedGlobalCounter
1, // exptectedCurProcStateSeq
NETWORK_STATE_NO_CHANGE, // expectedBlockState
false); // expectNotify
@@ -222,73 +216,22 @@ public class ActivityManagerServiceTest {
verifySeqCounterAndInteractions(uidRec,
PROCESS_STATE_LAST_ACTIVITY, // prevState
PROCESS_STATE_TOP, // curState
43, // expectedGlobalCounter
43, // exptectedCurProcStateSeq
NETWORK_STATE_BLOCK, // expectedBlockState
false); // expectNotify
// verify waiting threads are not notified.
uidRec.waitingForNetwork = false;
uidRec.procStateSeqWaitingForNetwork = 0;
// Uid state is moving from foreground to background.
verifySeqCounterAndInteractions(uidRec,
PROCESS_STATE_FOREGROUND_SERVICE, // prevState
PROCESS_STATE_SERVICE, // curState
44, // expectedGlobalCounter
44, // exptectedCurProcStateSeq
NETWORK_STATE_UNBLOCK, // expectedBlockState
false); // expectNotify
// Verify when uid is not restricted, procStateSeq is not incremented.
uidRec.waitingForNetwork = true;
mInjector.setNetworkRestrictedForUid(false);
verifySeqCounterAndInteractions(uidRec,
PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
PROCESS_STATE_TOP, // curState
44, // expectedGlobalCounter
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
// Verify when the uid doesn't have internet permission, then procStateSeq is not
// incremented.
uidRec.hasInternetPermission = false;
mAms.mWaitForNetworkTimeoutMs = 111;
mInjector.setNetworkRestrictedForUid(true);
verifySeqCounterAndInteractions(uidRec,
PROCESS_STATE_CACHED_ACTIVITY, // prevState
PROCESS_STATE_FOREGROUND_SERVICE, // curState
44, // expectedGlobalCounter
44, // exptectedCurProcStateSeq
-1, // expectedBlockState, -1 to verify there are no interactions with main thread.
false); // expectNotify
// Verify procStateSeq is not incremented when the uid is not an application, regardless
// of the process state.
final int notAppUid = 111;
final UidRecord uidRec2 = addUidRecord(notAppUid);
verifySeqCounterAndInteractions(uidRec2,
PROCESS_STATE_CACHED_EMPTY, // prevState
PROCESS_STATE_TOP, // curState
44, // expectedGlobalCounter
0, // exptectedCurProcStateSeq
-1, // expectedBlockState, -1 to verify there are no interactions with main thread.
false); // expectNotify
}
private UidRecord addUidRecord(int uid) {
final UidRecord uidRec = new UidRecord(uid, mAms);
uidRec.waitingForNetwork = true;
uidRec.procStateSeqWaitingForNetwork = 1;
uidRec.hasInternetPermission = true;
mAms.mProcessList.mActiveUids.put(uid, uidRec);
@@ -305,18 +248,26 @@ public class ActivityManagerServiceTest {
@SuppressWarnings("GuardedBy")
private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,
int expectedGlobalCounter, int expectedCurProcStateSeq, int expectedBlockState,
boolean expectNotify) throws Exception {
int expectedBlockState, boolean expectNotify) throws Exception {
CustomThread thread = new CustomThread(uidRec.networkStateLock);
thread.startAndWait("Unexpected state for " + uidRec);
uidRec.setSetProcState(prevState);
uidRec.setCurProcState(curState);
final long beforeProcStateSeq = mAms.mProcessList.mProcStateSeqCounter;
mAms.mProcessList.incrementProcStateSeqAndNotifyAppsLOSP(mAms.mProcessList.mActiveUids);
// @SuppressWarnings("GuardedBy")
assertEquals(expectedGlobalCounter, mAms.mProcessList.mProcStateSeqCounter);
assertEquals(expectedCurProcStateSeq, uidRec.curProcStateSeq);
final long afterProcStateSeq = beforeProcStateSeq
+ mAms.mProcessList.mActiveUids.size();
assertEquals("beforeProcStateSeq=" + beforeProcStateSeq
+ ",activeUids.size=" + mAms.mProcessList.mActiveUids.size(),
afterProcStateSeq, mAms.mProcessList.mProcStateSeqCounter);
assertTrue("beforeProcStateSeq=" + beforeProcStateSeq
+ ",afterProcStateSeq=" + afterProcStateSeq
+ ",uidCurProcStateSeq=" + uidRec.curProcStateSeq,
uidRec.curProcStateSeq > beforeProcStateSeq
&& uidRec.curProcStateSeq <= afterProcStateSeq);
for (int i = mAms.mProcessList.getLruSizeLOSP() - 1; i >= 0; --i) {
final ProcessRecord app = mAms.mProcessList.getLruProcessesLOSP().get(i);
@@ -814,49 +765,12 @@ public class ActivityManagerServiceTest {
0, mAms.mUidObserverController.getValidateUidsForTest().size());
}
@Test
public void testEnqueueUidChangeLocked_procStateSeqUpdated() {
final UidRecord uidRecord = new UidRecord(TEST_UID, mAms);
uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
// Verify with no pending changes for TEST_UID.
verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ1);
// Add a pending change for TEST_UID and verify enqueueUidChangeLocked still works as
// expected.
uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2;
verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2);
}
@Test
public void testEnqueueUidChangeLocked_nullUidRecord() {
// Use "null" uidRecord to make sure there is no crash.
mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
}
private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) {
// Test enqueueUidChangeLocked with every UidRecord.CHANGE_*
for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
final int changeToDispatch = UID_RECORD_CHANGES[i];
// Reset lastProcStateSeqDispatchToObservers after every test.
uidRecord.lastDispatchedProcStateSeq = 0;
mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
// Verify there is no effect on curProcStateSeq.
assertEquals(curProcstateSeq, uidRecord.curProcStateSeq);
if ((changeToDispatch & UidRecord.CHANGE_GONE) != 0) {
// Since the change is CHANGE_GONE or CHANGE_GONE_IDLE, verify that
// lastProcStateSeqDispatchedToObservers is not updated.
assertNotEquals(uidRecord.curProcStateSeq,
uidRecord.lastDispatchedProcStateSeq);
} else {
// Since the change is neither CHANGE_GONE nor CHANGE_GONE_IDLE, verify that
// lastProcStateSeqDispatchedToObservers has been updated to curProcStateSeq.
assertEquals(uidRecord.curProcStateSeq,
uidRecord.lastDispatchedProcStateSeq);
}
}
}
@MediumTest
@Test
public void testEnqueueUidChangeLocked_dispatchUidsChanged() {
@@ -893,29 +807,10 @@ public class ActivityManagerServiceTest {
// Check there is no crash when there is no UidRecord for myUid
mAms.waitForNetworkStateUpdate(TEST_PROC_STATE_SEQ1);
// Verify there is no waiting when UidRecord.curProcStateSeq is greater than
// the procStateSeq in the request to wait.
verifyWaitingForNetworkStateUpdate(
TEST_PROC_STATE_SEQ1, // curProcStateSeq
TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
TEST_PROC_STATE_SEQ1 - 4, // lastNetworkUpdatedProcStateSeq
TEST_PROC_STATE_SEQ1 - 2, // procStateSeqToWait
false); // expectWait
// Verify there is no waiting when the procStateSeq in the request to wait is
// not dispatched to NPMS.
verifyWaitingForNetworkStateUpdate(
TEST_PROC_STATE_SEQ1, // curProcStateSeq
TEST_PROC_STATE_SEQ1 - 1, // lastDsipatchedProcStateSeq
TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
TEST_PROC_STATE_SEQ1, // procStateSeqToWait
false); // expectWait
// Verify there is not waiting when the procStateSeq in the request already has
// an updated network state.
verifyWaitingForNetworkStateUpdate(
TEST_PROC_STATE_SEQ1, // curProcStateSeq
TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
TEST_PROC_STATE_SEQ1, // lastNetworkUpdatedProcStateSeq
TEST_PROC_STATE_SEQ1, // procStateSeqToWait
false); // expectWait
@@ -923,18 +818,16 @@ public class ActivityManagerServiceTest {
// Verify waiting for network works
verifyWaitingForNetworkStateUpdate(
TEST_PROC_STATE_SEQ1, // curProcStateSeq
TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
TEST_PROC_STATE_SEQ1, // procStateSeqToWait
true); // expectWait
}
private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
long lastDispatchedProcStateSeq, long lastNetworkUpdatedProcStateSeq,
long lastNetworkUpdatedProcStateSeq,
final long procStateSeqToWait, boolean expectWait) throws Exception {
final UidRecord record = new UidRecord(Process.myUid(), mAms);
record.curProcStateSeq = curProcStateSeq;
record.lastDispatchedProcStateSeq = lastDispatchedProcStateSeq;
record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
mAms.mProcessList.mActiveUids.put(Process.myUid(), record);
@@ -953,7 +846,7 @@ public class ActivityManagerServiceTest {
}
thread.assertTerminated(errMsg);
assertTrue(thread.mNotified);
assertFalse(record.waitingForNetwork);
assertEquals(0, record.procStateSeqWaitingForNetwork);
} else {
thread.start();
thread.assertTerminated(errMsg);

View File

@@ -991,19 +991,20 @@ public class NetworkPolicyManagerServiceTest {
@Test
public void testUidForeground() throws Exception {
// push all uids into background
callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, 0);
long procStateSeq = 0;
callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq++);
callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq++);
assertFalse(mService.isUidForeground(UID_A));
assertFalse(mService.isUidForeground(UID_B));
// push one of the uids into foreground
callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, 0);
callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_TOP, procStateSeq++);
assertTrue(mService.isUidForeground(UID_A));
assertFalse(mService.isUidForeground(UID_B));
// and swap another uid into foreground
callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, 0);
callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, 0);
callOnUidStateChanged(UID_A, ActivityManager.PROCESS_STATE_SERVICE, procStateSeq++);
callOnUidStateChanged(UID_B, ActivityManager.PROCESS_STATE_TOP, procStateSeq++);
assertFalse(mService.isUidForeground(UID_A));
assertTrue(mService.isUidForeground(UID_B));
}