Merge "Block service bound by foreground app to launch background activity by default"
This commit is contained in:
@@ -10071,6 +10071,7 @@ package android.content {
|
||||
field public static final String BATTERY_SERVICE = "batterymanager";
|
||||
field public static final int BIND_ABOVE_CLIENT = 8; // 0x8
|
||||
field public static final int BIND_ADJUST_WITH_ACTIVITY = 128; // 0x80
|
||||
field public static final int BIND_ALLOW_ACTIVITY_STARTS = 512; // 0x200
|
||||
field public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; // 0x10
|
||||
field public static final int BIND_AUTO_CREATE = 1; // 0x1
|
||||
field public static final int BIND_DEBUG_UNBIND = 2; // 0x2
|
||||
|
||||
@@ -278,6 +278,7 @@ public abstract class Context {
|
||||
BIND_IMPORTANT,
|
||||
BIND_ADJUST_WITH_ACTIVITY,
|
||||
BIND_NOT_PERCEPTIBLE,
|
||||
BIND_ALLOW_ACTIVITY_STARTS,
|
||||
BIND_INCLUDE_CAPABILITIES,
|
||||
BIND_SHARED_ISOLATED_PROCESS
|
||||
})
|
||||
@@ -381,6 +382,15 @@ public abstract class Context {
|
||||
*/
|
||||
public static final int BIND_NOT_PERCEPTIBLE = 0x00000100;
|
||||
|
||||
/**
|
||||
* Flag for {@link #bindService}: If binding from an app that is visible, the bound service is
|
||||
* allowed to start an activity from background. This was the default behavior before SDK
|
||||
* version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}. Since then, the default
|
||||
* behavior changed to disallow the bound service to start a background activity even if the app
|
||||
* bound to it is in foreground, unless this flag is specified when binding.
|
||||
*/
|
||||
public static final int BIND_ALLOW_ACTIVITY_STARTS = 0X000000200;
|
||||
|
||||
/**
|
||||
* Flag for {@link #bindService}: If binding from an app that has specific capabilities
|
||||
* due to its foreground state such as an activity or foreground service, then this flag will
|
||||
|
||||
@@ -543,6 +543,7 @@ message ConnectionRecordProto {
|
||||
DEAD = 15;
|
||||
NOT_PERCEPTIBLE = 16;
|
||||
INCLUDE_CAPABILITIES = 17;
|
||||
ALLOW_ACTIVITY_STARTS = 18;
|
||||
}
|
||||
repeated Flag flags = 3;
|
||||
optional string service_name = 4;
|
||||
|
||||
@@ -77,6 +77,7 @@ final class ConnectionRecord {
|
||||
Context.BIND_NOT_VISIBLE,
|
||||
Context.BIND_NOT_PERCEPTIBLE,
|
||||
Context.BIND_INCLUDE_CAPABILITIES,
|
||||
Context.BIND_ALLOW_ACTIVITY_STARTS,
|
||||
};
|
||||
private static final int[] BIND_PROTO_ENUMS = new int[] {
|
||||
ConnectionRecordProto.AUTO_CREATE,
|
||||
@@ -96,6 +97,7 @@ final class ConnectionRecord {
|
||||
ConnectionRecordProto.NOT_VISIBLE,
|
||||
ConnectionRecordProto.NOT_PERCEPTIBLE,
|
||||
ConnectionRecordProto.INCLUDE_CAPABILITIES,
|
||||
ConnectionRecordProto.ALLOW_ACTIVITY_STARTS,
|
||||
};
|
||||
|
||||
void dump(PrintWriter pw, String prefix) {
|
||||
@@ -237,6 +239,9 @@ final class ConnectionRecord {
|
||||
if ((flags & Context.BIND_NOT_PERCEPTIBLE) != 0) {
|
||||
sb.append("!PRCP ");
|
||||
}
|
||||
if ((flags & Context.BIND_ALLOW_ACTIVITY_STARTS) != 0) {
|
||||
sb.append("BALF ");
|
||||
}
|
||||
if ((flags & Context.BIND_INCLUDE_CAPABILITIES) != 0) {
|
||||
sb.append("CAPS ");
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.server.wm.WindowProcessController;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -506,19 +507,21 @@ final class ProcessServiceRecord {
|
||||
return mConnections.size();
|
||||
}
|
||||
|
||||
void addBoundClientUid(int clientUid) {
|
||||
void addBoundClientUid(int clientUid, String clientPackageName, int bindFlags) {
|
||||
mBoundClientUids.add(clientUid);
|
||||
mApp.getWindowProcessController().setBoundClientUids(mBoundClientUids);
|
||||
mApp.getWindowProcessController()
|
||||
.addBoundClientUid(clientUid, clientPackageName, bindFlags);
|
||||
}
|
||||
|
||||
void updateBoundClientUids() {
|
||||
clearBoundClientUids();
|
||||
if (mServices.isEmpty()) {
|
||||
clearBoundClientUids();
|
||||
return;
|
||||
}
|
||||
// grab a set of clientUids of all mConnections of all services
|
||||
final ArraySet<Integer> boundClientUids = new ArraySet<>();
|
||||
final int serviceCount = mServices.size();
|
||||
WindowProcessController controller = mApp.getWindowProcessController();
|
||||
for (int j = 0; j < serviceCount; j++) {
|
||||
final ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns =
|
||||
mServices.valueAt(j).getConnections();
|
||||
@@ -526,12 +529,13 @@ final class ProcessServiceRecord {
|
||||
for (int conni = 0; conni < size; conni++) {
|
||||
ArrayList<ConnectionRecord> c = conns.valueAt(conni);
|
||||
for (int i = 0; i < c.size(); i++) {
|
||||
boundClientUids.add(c.get(i).clientUid);
|
||||
ConnectionRecord cr = c.get(i);
|
||||
boundClientUids.add(cr.clientUid);
|
||||
controller.addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
mBoundClientUids = boundClientUids;
|
||||
mApp.getWindowProcessController().setBoundClientUids(mBoundClientUids);
|
||||
}
|
||||
|
||||
void addBoundClientUidsOfNewService(ServiceRecord sr) {
|
||||
@@ -542,15 +546,18 @@ final class ProcessServiceRecord {
|
||||
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);
|
||||
ConnectionRecord cr = c.get(i);
|
||||
mBoundClientUids.add(cr.clientUid);
|
||||
mApp.getWindowProcessController()
|
||||
.addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.flags);
|
||||
|
||||
}
|
||||
}
|
||||
mApp.getWindowProcessController().setBoundClientUids(mBoundClientUids);
|
||||
}
|
||||
|
||||
void clearBoundClientUids() {
|
||||
mBoundClientUids.clear();
|
||||
mApp.getWindowProcessController().setBoundClientUids(mBoundClientUids);
|
||||
mApp.getWindowProcessController().clearBoundClientUids();
|
||||
}
|
||||
|
||||
@GuardedBy("mService")
|
||||
|
||||
@@ -894,7 +894,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
||||
|
||||
// if we have a process attached, add bound client uid of this connection to it
|
||||
if (app != null) {
|
||||
app.mServices.addBoundClientUid(c.clientUid);
|
||||
app.mServices.addBoundClientUid(c.clientUid, c.clientPackageName, c.flags);
|
||||
app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,17 @@ import static java.util.Objects.requireNonNull;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.BackgroundStartPrivileges;
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.EnabledSince;
|
||||
import android.compat.annotation.Overridable;
|
||||
import android.content.Context;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -58,6 +64,12 @@ class BackgroundLaunchProcessController {
|
||||
private static final String TAG =
|
||||
TAG_WITH_CLASS_NAME ? "BackgroundLaunchProcessController" : TAG_ATM;
|
||||
|
||||
/** If enabled BAL are prevented by default in applications targeting U and later. */
|
||||
@ChangeId
|
||||
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
@Overridable
|
||||
private static final long DEFAULT_RESCIND_BAL_FG_PRIVILEGES_BOUND_SERVICE = 261072174;
|
||||
|
||||
/** It is {@link ActivityTaskManagerService#hasActiveVisibleWindow(int)}. */
|
||||
private final IntPredicate mUidHasActiveVisibleWindowPredicate;
|
||||
|
||||
@@ -71,9 +83,11 @@ class BackgroundLaunchProcessController {
|
||||
@GuardedBy("this")
|
||||
private @Nullable ArrayMap<Binder, BackgroundStartPrivileges> mBackgroundStartPrivileges;
|
||||
|
||||
/** Set of UIDs of clients currently bound to this process. */
|
||||
/** Set of UIDs of clients currently bound to this process and opt in to allow this process to
|
||||
* launch background activity.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private @Nullable IntArray mBoundClientUids;
|
||||
private @Nullable IntArray mBalOptInBoundClientUids;
|
||||
|
||||
BackgroundLaunchProcessController(@NonNull IntPredicate uidHasActiveVisibleWindowPredicate,
|
||||
@Nullable BackgroundActivityStartCallback callback) {
|
||||
@@ -204,9 +218,9 @@ class BackgroundLaunchProcessController {
|
||||
|
||||
private boolean isBoundByForegroundUid() {
|
||||
synchronized (this) {
|
||||
if (mBoundClientUids != null) {
|
||||
for (int i = mBoundClientUids.size() - 1; i >= 0; i--) {
|
||||
if (mUidHasActiveVisibleWindowPredicate.test(mBoundClientUids.get(i))) {
|
||||
if (mBalOptInBoundClientUids != null) {
|
||||
for (int i = mBalOptInBoundClientUids.size() - 1; i >= 0; i--) {
|
||||
if (mUidHasActiveVisibleWindowPredicate.test(mBalOptInBoundClientUids.get(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -215,19 +229,27 @@ class BackgroundLaunchProcessController {
|
||||
return false;
|
||||
}
|
||||
|
||||
void setBoundClientUids(ArraySet<Integer> boundClientUids) {
|
||||
void clearBalOptInBoundClientUids() {
|
||||
synchronized (this) {
|
||||
if (boundClientUids == null || boundClientUids.isEmpty()) {
|
||||
mBoundClientUids = null;
|
||||
return;
|
||||
}
|
||||
if (mBoundClientUids == null) {
|
||||
mBoundClientUids = new IntArray();
|
||||
if (mBalOptInBoundClientUids == null) {
|
||||
mBalOptInBoundClientUids = new IntArray();
|
||||
} else {
|
||||
mBoundClientUids.clear();
|
||||
mBalOptInBoundClientUids.clear();
|
||||
}
|
||||
for (int i = boundClientUids.size() - 1; i >= 0; i--) {
|
||||
mBoundClientUids.add(boundClientUids.valueAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
void addBoundClientUid(int clientUid, String clientPackageName, int bindFlags) {
|
||||
if (!CompatChanges.isChangeEnabled(
|
||||
DEFAULT_RESCIND_BAL_FG_PRIVILEGES_BOUND_SERVICE,
|
||||
clientPackageName,
|
||||
UserHandle.getUserHandleForUid(clientUid))
|
||||
|| (bindFlags & Context.BIND_ALLOW_ACTIVITY_STARTS) != 0) {
|
||||
if (mBalOptInBoundClientUids == null) {
|
||||
mBalOptInBoundClientUids = new IntArray();
|
||||
}
|
||||
if (mBalOptInBoundClientUids.indexOf(clientUid) == -1) {
|
||||
mBalOptInBoundClientUids.add(clientUid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,10 +320,10 @@ class BackgroundLaunchProcessController {
|
||||
pw.println(mBackgroundStartPrivileges.valueAt(i));
|
||||
}
|
||||
}
|
||||
if (mBoundClientUids != null && mBoundClientUids.size() > 0) {
|
||||
if (mBalOptInBoundClientUids != null && mBalOptInBoundClientUids.size() > 0) {
|
||||
pw.print(prefix);
|
||||
pw.print("BoundClientUids:");
|
||||
pw.println(Arrays.toString(mBoundClientUids.toArray()));
|
||||
pw.println(Arrays.toString(mBalOptInBoundClientUids.toArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
@@ -594,8 +593,18 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
|
||||
return mBgLaunchController.canCloseSystemDialogsByToken(mUid);
|
||||
}
|
||||
|
||||
public void setBoundClientUids(ArraySet<Integer> boundClientUids) {
|
||||
mBgLaunchController.setBoundClientUids(boundClientUids);
|
||||
/**
|
||||
* Clear all bound client Uids.
|
||||
*/
|
||||
public void clearBoundClientUids() {
|
||||
mBgLaunchController.clearBalOptInBoundClientUids();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add bound client Uid.
|
||||
*/
|
||||
public void addBoundClientUid(int clientUid, String clientPackageName, int bindFlags) {
|
||||
mBgLaunchController.addBoundClientUid(clientUid, clientPackageName, bindFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user