Allow processes that are bound to by a currently foreground app to
start activities from background
Maintain a set of all client UIDs currently bound to a process, by
updating it accordingly when a service is added/removed to a
process, or the connection is added/removed to the process' service.
Test: atest WmTests:ActivityStarterTests
Bug: 128467234
Bug: 123333161 (daydream case)
Bug: 123500216 (google lens case)
Bug: 129000609 (dialer-duo case)
Change-Id: Ied3ffd8357292d2ad25560c87cd69dc100c9e565
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index a90e994..ce13cd8 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -259,6 +259,8 @@
// A set of tokens that currently contribute to this process being temporarily whitelisted
// to start activities even if it's not in the foreground
final ArraySet<Binder> mAllowBackgroundActivityStartsTokens = new ArraySet<>();
+ // a set of UIDs of all bound clients
+ private ArraySet<Integer> mBoundClientUids = new ArraySet<>();
String isolatedEntryPoint; // Class to run on start if this is a special isolated process.
String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main().
@@ -1193,6 +1195,53 @@
!mAllowBackgroundActivityStartsTokens.isEmpty());
}
+ void addBoundClientUids(ArraySet<Integer> clientUids) {
+ mBoundClientUids.addAll(clientUids);
+ mWindowProcessController.setBoundClientUids(mBoundClientUids);
+ }
+
+ void updateBoundClientUids() {
+ if (services.isEmpty()) {
+ clearBoundClientUids();
+ return;
+ }
+ // grab a set of clientUids of all connections of all services
+ ArraySet<Integer> boundClientUids = new ArraySet<>();
+ final int K = services.size();
+ for (int j = 0; j < K; j++) {
+ ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns =
+ services.valueAt(j).getConnections();
+ final int N = conns.size();
+ for (int conni = 0; conni < N; conni++) {
+ ArrayList<ConnectionRecord> c = conns.valueAt(conni);
+ for (int i = 0; i < c.size(); i++) {
+ boundClientUids.add(c.get(i).clientUid);
+ }
+ }
+ }
+ mBoundClientUids = boundClientUids;
+ mWindowProcessController.setBoundClientUids(mBoundClientUids);
+ }
+
+ void addBoundClientUidsOfNewService(ServiceRecord sr) {
+ if (sr == null) {
+ return;
+ }
+ ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = sr.getConnections();
+ for (int conni = conns.size() - 1; conni >= 0; conni--) {
+ ArrayList<ConnectionRecord> c = conns.valueAt(conni);
+ for (int i = 0; i < c.size(); i++) {
+ mBoundClientUids.add(c.get(i).clientUid);
+ }
+ }
+ mWindowProcessController.setBoundClientUids(mBoundClientUids);
+ }
+
+ void clearBoundClientUids() {
+ mBoundClientUids.clear();
+ mWindowProcessController.setBoundClientUids(mBoundClientUids);
+ }
+
void setActiveInstrumentation(ActiveInstrumentation instr) {
mInstr = instr;
boolean isInstrumenting = instr != null;