Merge "Allow clients to register for listening to changes in capabilities." into sc-dev

This commit is contained in:
Sudheer Shanka
2021-04-07 20:18:04 +00:00
committed by Android (Google) Code Review
9 changed files with 87 additions and 29 deletions

View File

@@ -794,6 +794,9 @@ public class ActivityManager {
/** @hide Flag for registerUidObserver: report uid cached state has changed. */
public static final int UID_OBSERVER_CACHED = 1<<4;
/** @hide Flag for registerUidObserver: report uid capability has changed. */
public static final int UID_OBSERVER_CAPABILITY = 1<<5;
/** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: normal free-to-run operation. */
public static final int APP_START_MODE_NORMAL = 0;

View File

@@ -33,4 +33,6 @@ enum UidObserverFlag {
UID_OBSERVER_FLAG_ACTIVE = 4;
// report uid cached state has changed, original value is 1 << 4
UID_OBSERVER_FLAG_CACHED = 5;
// report uid capability has changed, original value is 1 << 5
UID_OBSERVER_FLAG_CAPABILITY = 6;
}

View File

@@ -778,6 +778,7 @@ message UidRecordProto {
CHANGE_ACTIVE = 2;
CHANGE_CACHED = 3;
CHANGE_UNCACHED = 4;
CHANGE_CAPABILITY = 5;
}
repeated Change last_reported_changes = 8;
optional int32 num_procs = 9;

View File

@@ -1328,6 +1328,9 @@ public final class OomAdjuster {
|| uidRec.getSetProcState() == PROCESS_STATE_NONEXISTENT) {
uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
}
if (uidRec.getSetCapability() != uidRec.getCurCapability()) {
uidChange |= UidRecord.CHANGE_CAPABILITY;
}
uidRec.setSetProcState(uidRec.getCurProcState());
uidRec.setSetCapability(uidRec.getCurCapability());
uidRec.setSetAllowListed(uidRec.isCurAllowListed());

View File

@@ -147,6 +147,9 @@ public class UidObserverController {
if ((currentChange & UidRecord.CHANGE_GONE) != 0) {
currentChange &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
}
if ((pendingChange & UidRecord.CHANGE_CAPABILITY) != 0) {
currentChange |= UidRecord.CHANGE_CAPABILITY;
}
return currentChange;
}
@@ -285,12 +288,9 @@ public class UidObserverController {
reg.mLastProcStates.delete(item.uid);
}
} else {
boolean doReport = false;
if ((reg.mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
if (DEBUG_UID_OBSERVERS) {
Slog.i(TAG_UID_OBSERVERS, "UID CHANGED uid=" + item.uid
+ ": " + item.procState + ": " + item.capability);
}
boolean doReport = true;
doReport = true;
if (reg.mCutpoint >= ActivityManager.MIN_PROCESS_STATE) {
final int lastState = reg.mLastProcStates.get(item.uid,
ActivityManager.PROCESS_STATE_UNKNOWN);
@@ -302,13 +302,20 @@ public class UidObserverController {
doReport = item.procState != PROCESS_STATE_NONEXISTENT;
}
}
if (doReport) {
if (reg.mLastProcStates != null) {
reg.mLastProcStates.put(item.uid, item.procState);
}
observer.onUidStateChanged(item.uid, item.procState,
item.procStateSeq, item.capability);
}
if ((reg.mWhich & ActivityManager.UID_OBSERVER_CAPABILITY) != 0) {
doReport |= (change & UidRecord.CHANGE_CAPABILITY) != 0;
}
if (doReport) {
if (DEBUG_UID_OBSERVERS) {
Slog.i(TAG_UID_OBSERVERS, "UID CHANGED uid=" + item.uid
+ ": " + item.procState + ": " + item.capability);
}
if (reg.mLastProcStates != null) {
reg.mLastProcStates.put(item.uid, item.procState);
}
observer.onUidStateChanged(item.uid, item.procState,
item.procStateSeq, item.capability);
}
}
final int duration = (int) (SystemClock.uptimeMillis() - start);
@@ -428,12 +435,14 @@ public class UidObserverController {
ActivityManager.UID_OBSERVER_ACTIVE,
ActivityManager.UID_OBSERVER_GONE,
ActivityManager.UID_OBSERVER_PROCSTATE,
ActivityManager.UID_OBSERVER_CAPABILITY,
};
private static final int[] PROTO_ENUMS = new int[]{
ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
ActivityManagerProto.UID_OBSERVER_FLAG_CAPABILITY,
};
UidObserverRegistration(int uid, @NonNull String pkg, int which, int cutpoint) {
@@ -462,6 +471,9 @@ public class UidObserverController {
if ((mWhich & ActivityManager.UID_OBSERVER_GONE) != 0) {
pw.print(" GONE");
}
if ((mWhich & ActivityManager.UID_OBSERVER_CAPABILITY) != 0) {
pw.print(" CAP");
}
if ((mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
pw.print(" STATE");
pw.print(" (cut=");

View File

@@ -122,6 +122,7 @@ public final class UidRecord {
static final int CHANGE_ACTIVE = 1<<2;
static final int CHANGE_CACHED = 1<<3;
static final int CHANGE_UNCACHED = 1<<4;
static final int CHANGE_CAPABILITY = 1<<5;
// Keep the enum lists in sync
private static int[] ORIG_ENUMS = new int[] {
@@ -130,6 +131,7 @@ public final class UidRecord {
CHANGE_ACTIVE,
CHANGE_CACHED,
CHANGE_UNCACHED,
CHANGE_CAPABILITY,
};
private static int[] PROTO_ENUMS = new int[] {
UidRecordProto.CHANGE_GONE,
@@ -137,6 +139,7 @@ public final class UidRecord {
UidRecordProto.CHANGE_ACTIVE,
UidRecordProto.CHANGE_CACHED,
UidRecordProto.CHANGE_UNCACHED,
UidRecordProto.CHANGE_CAPABILITY,
};
// UidObserverController is the only thing that should modify this.

View File

@@ -926,10 +926,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
try {
// TODO: There shouldn't be a need to receive callback for all changes.
mActivityManager.registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
ActivityManager.PROCESS_STATE_UNKNOWN, "android");
final int changes = ActivityManager.UID_OBSERVER_PROCSTATE
| ActivityManager.UID_OBSERVER_GONE
| ActivityManager.UID_OBSERVER_CAPABILITY;
mActivityManager.registerUidObserver(mUidObserver, changes,
NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
// ignored; both services live in system_server

View File

@@ -72,6 +72,7 @@ import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.IntArray;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
@@ -121,7 +122,8 @@ public class ActivityManagerServiceTest {
UidRecord.CHANGE_GONE,
UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE,
UidRecord.CHANGE_IDLE,
UidRecord.CHANGE_ACTIVE
UidRecord.CHANGE_ACTIVE,
UidRecord.CHANGE_CAPABILITY,
};
private static PackageManagerInternal sPackageManagerInternal;
@@ -528,8 +530,10 @@ public class ActivityManagerServiceTest {
ActivityManager.UID_OBSERVER_GONE,
ActivityManager.UID_OBSERVER_IDLE,
ActivityManager.UID_OBSERVER_ACTIVE,
ActivityManager.UID_OBSERVER_CAPABILITY,
ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
| ActivityManager.UID_OBSERVER_ACTIVE | ActivityManager.UID_OBSERVER_IDLE
| ActivityManager.UID_OBSERVER_CAPABILITY
};
final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
for (int i = 0; i < observers.length; ++i) {
@@ -553,7 +557,16 @@ public class ActivityManagerServiceTest {
ActivityManager.PROCESS_STATE_NONEXISTENT,
ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
ActivityManager.PROCESS_STATE_TOP
ActivityManager.PROCESS_STATE_TOP,
ActivityManager.PROCESS_STATE_TOP,
};
final int[] capabilitiesForPendingUidRecords = {
ActivityManager.PROCESS_CAPABILITY_ALL,
ActivityManager.PROCESS_CAPABILITY_NONE,
ActivityManager.PROCESS_CAPABILITY_NONE,
ActivityManager.PROCESS_CAPABILITY_NONE,
ActivityManager.PROCESS_CAPABILITY_NONE,
ActivityManager.PROCESS_CAPABILITY_NETWORK,
};
final Map<Integer, ChangeRecord> changeItems = new HashMap<>();
for (int i = 0; i < changesForPendingUidRecords.length; ++i) {
@@ -562,6 +575,7 @@ public class ActivityManagerServiceTest {
pendingChange.uid = i;
pendingChange.procState = procStatesForPendingUidRecords[i];
pendingChange.procStateSeq = i;
pendingChange.capability = capabilitiesForPendingUidRecords[i];
changeItems.put(changesForPendingUidRecords[i], pendingChange);
addPendingUidChange(pendingChange);
}
@@ -606,20 +620,26 @@ public class ActivityManagerServiceTest {
verify(observer).onUidGone(changeItem.uid, changeItem.ephemeral);
});
}
if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0
|| (changeToObserve & ActivityManager.UID_OBSERVER_CAPABILITY) != 0) {
// Observer listens to uid procState changes, so change items corresponding to
// UidRecord.CHANGE_PROCSTATE or UidRecord.CHANGE_IDLE or UidRecord.CHANGE_ACTIVE
// needs to be delivered to this observer.
final int[] changesToVerify = {
UidRecord.CHANGE_PROCSTATE,
UidRecord.CHANGE_ACTIVE,
UidRecord.CHANGE_IDLE
};
verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
final IntArray changesToVerify = new IntArray();
if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
changesToVerify.add(UidRecord.CHANGE_CAPABILITY);
} else {
changesToVerify.add(UidRecord.CHANGE_PROCSTATE);
changesToVerify.add(UidRecord.CHANGE_ACTIVE);
changesToVerify.add(UidRecord.CHANGE_IDLE);
changesToVerify.add(UidRecord.CHANGE_CAPABILITY);
}
verifyObserverReceivedChanges(observerToTest, changesToVerify.toArray(),
changeItems,
(observer, changeItem) -> {
verify(observer).onUidStateChanged(changeItem.uid,
changeItem.procState, changeItem.procStateSeq,
ActivityManager.PROCESS_CAPABILITY_NONE);
changeItem.capability);
});
}
// Verify there are no other callbacks for this observer.
@@ -725,11 +745,11 @@ public class ActivityManagerServiceTest {
ActivityManager.PROCESS_STATE_CACHED_EMPTY,
ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
ActivityManager.PROCESS_STATE_SERVICE,
ActivityManager.PROCESS_STATE_RECEIVER
ActivityManager.PROCESS_STATE_RECEIVER,
};
final ArrayList<ChangeRecord> pendingItemsForUids =
new ArrayList<>(changesForPendingItems.length);
for (int i = 0; i < changesForPendingItems.length; ++i) {
new ArrayList<>(procStatesForPendingItems.length);
for (int i = 0; i < procStatesForPendingItems.length; ++i) {
final ChangeRecord item = new ChangeRecord();
item.uid = i;
item.change = changesForPendingItems[i];

View File

@@ -18,6 +18,7 @@ package com.android.server.am;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
@@ -109,6 +110,7 @@ public class UidObserverControllerTest {
@Test
public void testMergeWithPendingChange() {
// Map of expectedChange -> {(currentChange, pendingChange)}
final SparseArray<Pair<Integer, Integer>> changesToVerify = new SparseArray<>();
changesToVerify.put(UidRecord.CHANGE_ACTIVE,
@@ -127,6 +129,8 @@ public class UidObserverControllerTest {
Pair.create(UidRecord.CHANGE_GONE, UidRecord.CHANGE_ACTIVE));
changesToVerify.put(UidRecord.CHANGE_GONE,
Pair.create(UidRecord.CHANGE_GONE, UidRecord.CHANGE_CACHED));
changesToVerify.put(UidRecord.CHANGE_PROCSTATE | UidRecord.CHANGE_CAPABILITY,
Pair.create(UidRecord.CHANGE_PROCSTATE, UidRecord.CHANGE_CAPABILITY));
for (int i = 0; i < changesToVerify.size(); ++i) {
final int expectedChange = changesToVerify.keyAt(i);
@@ -149,7 +153,8 @@ public class UidObserverControllerTest {
ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_ACTIVE,
PROCESS_STATE_IMPORTANT_FOREGROUND, TEST_PKG2, TEST_UID2);
final IUidObserver observer2 = mock(IUidObserver.Stub.class);
registerObserver(observer2, ActivityManager.UID_OBSERVER_PROCSTATE,
registerObserver(observer2,
ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_CAPABILITY,
PROCESS_STATE_SERVICE, TEST_PKG3, TEST_UID3);
mUidObserverController.dispatchUidsChanged();
@@ -177,6 +182,14 @@ public class UidObserverControllerTest {
verifyNoMoreInteractions(observer1);
verifyNoMoreInteractions(observer2);
addPendingChange(TEST_UID1, UidRecord.CHANGE_PROCSTATE | UidRecord.CHANGE_CAPABILITY,
PROCESS_STATE_RECEIVER, 111, PROCESS_CAPABILITY_NETWORK, false);
mUidObserverController.dispatchUidsChanged();
verify(observer2).onUidStateChanged(TEST_UID1, PROCESS_STATE_RECEIVER,
111, PROCESS_CAPABILITY_NETWORK);
verifyNoMoreInteractions(observer1);
verifyNoMoreInteractions(observer2);
unregisterObserver(observer1);
addPendingChange(TEST_UID1, UidRecord.CHANGE_PROCSTATE, PROCESS_STATE_TOP,