summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Michal Karpinski <mkarpinski@google.com> 2019-03-13 13:44:02 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-03-13 13:44:02 +0000
commit681db90b5aa76e67e4ebf89b3c5c65aabde4c5f4 (patch)
treec57b13b688f869215ef0ec7ad0147ee3998f0258
parent15694fcceb739485c07534279210853d83df73fb (diff)
parente069b0022f5aa090d00b9266f2760cb2c7a6e97f (diff)
Merge "Add new BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS binding flag and the mechanism to use it"
-rw-r--r--core/java/android/content/Context.java9
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java3
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java93
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java10
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java81
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java4
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java3
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java6
10 files changed, 162 insertions, 52 deletions
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 0c76f3f049a8..5c9931970d5c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -338,6 +338,15 @@ public abstract class Context {
public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100;
/**
+ * Flag for {@link #bindService}: allow background activity starts from the bound service's
+ * process.
+ * This flag is only respected if the caller is holding
+ * {@link android.Manifest.permission#START_ACTIVITIES_FROM_BACKGROUND}.
+ * @hide
+ */
+ public static final int BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS = 0x00100000;
+
+ /**
* @hide Flag for {@link #bindService}: the service being bound to represents a
* protected system component, so must have association restrictions applied to it.
* That is, a system config must have one or more allow-association tags limiting
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b437435902df..a750c7917fc2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11518,6 +11518,7 @@ public final class Settings {
* service_min_restart_time_between (long)
* service_max_inactivity (long)
* service_bg_start_timeout (long)
+ * service_bg_activity_start_timeout (long)
* process_start_async (boolean)
* </pre>
*
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 305fbf2e3e98..b135f7b27c3f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -159,8 +159,8 @@ public class TileLifecycleManager extends BroadcastReceiver implements
mBindTryCount++;
try {
mIsBound = mContext.bindServiceAsUser(mIntent, this,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
- mUser);
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, mUser);
} catch (SecurityException e) {
Log.e(TAG, "Failed to bind to service", e);
mIsBound = false;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index a19a84724d45..3bd6220b4767 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -91,7 +91,8 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect
if (userState == null) return;
final long identity = Binder.clearCallingIdentity();
try {
- int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE;
+ int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS;
if (userState.getBindInstantServiceAllowed()) {
flags |= Context.BIND_ALLOW_INSTANT;
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 85ec2dd55e89..627010606b31 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -131,9 +131,6 @@ public final class ActiveServices {
// calling startForeground() before we ANR + stop it.
static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;
- // For how long after a whitelisted service's start its process can start a background activity
- private static final int SERVICE_BG_ACTIVITY_START_TIMEOUT_MS = 10*1000;
-
final ActivityManagerService mAm;
// Maximum number of services that we allow to start in the background
@@ -333,8 +330,8 @@ public final class ActiveServices {
+ " delayedStop=" + r.delayedStop);
} else {
try {
- startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true,
- false);
+ startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false,
+ true);
} catch (TransactionTooLargeException e) {
// Ignore, nobody upstack cares.
}
@@ -637,26 +634,26 @@ public final class ActiveServices {
}
if (allowBackgroundActivityStarts) {
- ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
- if (proc != null) {
- proc.addAllowBackgroundActivityStartsToken(r);
- // schedule removal of the whitelisting token after the timeout
- removeAllowBackgroundActivityStartsServiceToken(proc, r,
- SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
- }
+ r.hasStartedWhitelistingBgActivityStarts = true;
+ scheduleCleanUpHasStartedWhitelistingBgActivityStartsLocked(r);
}
- ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
- allowBackgroundActivityStarts);
+
+ ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
- private void removeAllowBackgroundActivityStartsServiceToken(ProcessRecord proc,
- ServiceRecord r, int delayMillis) {
- mAm.mHandler.postDelayed(() -> {
- if (proc != null) {
- proc.removeAllowBackgroundActivityStartsToken(r);
- }
- }, delayMillis);
+ private void scheduleCleanUpHasStartedWhitelistingBgActivityStartsLocked(ServiceRecord r) {
+ // if there's a request pending from the past, drop it before scheduling a new one
+ if (r.startedWhitelistingBgActivityStartsCleanUp == null) {
+ r.startedWhitelistingBgActivityStartsCleanUp = () -> {
+ synchronized(mAm) {
+ r.setHasStartedWhitelistingBgActivityStarts(false);
+ }
+ };
+ }
+ mAm.mHandler.removeCallbacks(r.startedWhitelistingBgActivityStartsCleanUp);
+ mAm.mHandler.postDelayed(r.startedWhitelistingBgActivityStartsCleanUp,
+ mAm.mConstants.SERVICE_BG_ACTIVITY_START_TIMEOUT);
}
private boolean requestStartTargetPermissionsReviewIfNeededLocked(ServiceRecord r,
@@ -705,8 +702,7 @@ public final class ActiveServices {
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
- boolean callerFg, boolean addToStarting, boolean allowBackgroundActivityStarts)
- throws TransactionTooLargeException {
+ boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
@@ -717,8 +713,7 @@ public final class ActiveServices {
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
- String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false,
- allowBackgroundActivityStarts);
+ String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
@@ -765,6 +760,12 @@ public final class ActiveServices {
SystemClock.uptimeMillis());
}
service.callStart = false;
+
+ // the service will not necessarily be brought down, so only clear the whitelisting state
+ // for start-based bg activity starts now, and drop any existing future cleanup callback
+ service.setHasStartedWhitelistingBgActivityStarts(false);
+ mAm.mHandler.removeCallbacks(service.startedWhitelistingBgActivityStartsCleanUp);
+
bringDownServiceIfNeededLocked(service, false, false);
}
@@ -788,9 +789,6 @@ public final class ActiveServices {
if (r.record != null) {
final long origId = Binder.clearCallingIdentity();
try {
- // immediately remove bg activity whitelisting token if there was one
- removeAllowBackgroundActivityStartsServiceToken(callerApp, r.record,
- 0 /* delayMillis */);
stopServiceLocked(r.record);
} finally {
Binder.restoreCallingIdentity(origId);
@@ -1614,6 +1612,12 @@ public final class ActiveServices {
+ ") set BIND_ALLOW_INSTANT when binding service " + service);
}
+ if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+ mAm.enforceCallingPermission(
+ android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
+ "BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS");
+ }
+
final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;
@@ -1672,7 +1676,7 @@ public final class ActiveServices {
try {
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(),
- callerFg, false, false, false);
+ callerFg, false, false);
} catch (RemoteException e) {
/* ignore - local call */
}
@@ -1762,6 +1766,9 @@ public final class ActiveServices {
if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
s.whitelistManager = true;
}
+ if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+ s.setHasBindingWhitelistingBgActivityStarts(true);
+ }
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
@@ -1775,7 +1782,7 @@ public final class ActiveServices {
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
- permissionsReviewRequired, false) != null) {
+ permissionsReviewRequired) != null) {
return 0;
}
}
@@ -2445,8 +2452,7 @@ public final class ActiveServices {
return;
}
try {
- bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false,
- false);
+ bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false);
} catch (TransactionTooLargeException e) {
// Ignore, it's been logged and nothing upstack cares.
}
@@ -2491,11 +2497,8 @@ public final class ActiveServices {
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
- boolean whileRestarting, boolean permissionsReviewRequired,
- boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
- //Slog.i(TAG, "Bring up service:");
- //r.dump(" ");
-
+ boolean whileRestarting, boolean permissionsReviewRequired)
+ throws TransactionTooLargeException {
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, execInFg, false);
return null;
@@ -2603,13 +2606,6 @@ public final class ActiveServices {
}
}
- if (app != null && allowBackgroundActivityStarts) {
- app.addAllowBackgroundActivityStartsToken(r);
- // schedule removal of the whitelisting token after the timeout
- removeAllowBackgroundActivityStartsServiceToken(app, r,
- SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
- }
-
if (r.fgRequired) {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.v(TAG, "Whitelisting " + UserHandle.formatUid(r.appInfo.uid)
@@ -2646,6 +2642,11 @@ public final class ActiveServices {
}
}
+ /**
+ * Note the name of this method should not be confused with the started services concept.
+ * The "start" here means bring up the instance in the client, and this method is called
+ * from bindService() as well.
+ */
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
@@ -3085,6 +3086,10 @@ public final class ActiveServices {
updateWhitelistManagerLocked(s.app);
}
}
+ // And do the same for bg activity starts whitelisting.
+ if ((c.flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+ s.updateHasBindingWhitelistingBgActivityStarts();
+ }
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index f9fcef68381e..1751856066fb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -69,6 +69,7 @@ final class ActivityManagerConstants extends ContentObserver {
static final String KEY_SERVICE_MIN_RESTART_TIME_BETWEEN = "service_min_restart_time_between";
static final String KEY_MAX_SERVICE_INACTIVITY = "service_max_inactivity";
static final String KEY_BG_START_TIMEOUT = "service_bg_start_timeout";
+ static final String KEY_SERVICE_BG_ACTIVITY_START_TIMEOUT = "service_bg_activity_start_timeout";
static final String KEY_BOUND_SERVICE_CRASH_RESTART_DURATION = "service_crash_restart_duration";
static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry";
static final String KEY_PROCESS_START_ASYNC = "process_start_async";
@@ -99,6 +100,7 @@ final class ActivityManagerConstants extends ContentObserver {
private static final long DEFAULT_SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
private static final long DEFAULT_MAX_SERVICE_INACTIVITY = 30*60*1000;
private static final long DEFAULT_BG_START_TIMEOUT = 15*1000;
+ private static final long DEFAULT_SERVICE_BG_ACTIVITY_START_TIMEOUT = 10_000;
private static final long DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION = 30*60_000;
private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16;
private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
@@ -212,6 +214,9 @@ final class ActivityManagerConstants extends ContentObserver {
// allowing the next pending start to run.
public long BG_START_TIMEOUT = DEFAULT_BG_START_TIMEOUT;
+ // For how long after a whitelisted service's start its process can start a background activity
+ public long SERVICE_BG_ACTIVITY_START_TIMEOUT = DEFAULT_SERVICE_BG_ACTIVITY_START_TIMEOUT;
+
// Initial backoff delay for retrying bound foreground services
public long BOUND_SERVICE_CRASH_RESTART_DURATION = DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION;
@@ -398,6 +403,9 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_MAX_SERVICE_INACTIVITY);
BG_START_TIMEOUT = mParser.getLong(KEY_BG_START_TIMEOUT,
DEFAULT_BG_START_TIMEOUT);
+ SERVICE_BG_ACTIVITY_START_TIMEOUT = mParser.getLong(
+ KEY_SERVICE_BG_ACTIVITY_START_TIMEOUT,
+ DEFAULT_SERVICE_BG_ACTIVITY_START_TIMEOUT);
BOUND_SERVICE_CRASH_RESTART_DURATION = mParser.getLong(
KEY_BOUND_SERVICE_CRASH_RESTART_DURATION,
DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION);
@@ -518,6 +526,8 @@ final class ActivityManagerConstants extends ContentObserver {
pw.println(MAX_SERVICE_INACTIVITY);
pw.print(" "); pw.print(KEY_BG_START_TIMEOUT); pw.print("=");
pw.println(BG_START_TIMEOUT);
+ pw.print(" "); pw.print(KEY_SERVICE_BG_ACTIVITY_START_TIMEOUT); pw.print("=");
+ pw.println(SERVICE_BG_ACTIVITY_START_TIMEOUT);
pw.print(" "); pw.print(KEY_BOUND_SERVICE_CRASH_RESTART_DURATION); pw.print("=");
pw.println(BOUND_SERVICE_CRASH_RESTART_DURATION);
pw.print(" "); pw.print(KEY_BOUND_SERVICE_CRASH_MAX_RETRY); pw.print("=");
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 0387774bb257..eeaa7de85b5c 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -125,6 +125,14 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
int pendingConnectionGroup; // To be filled in to ProcessRecord once it connects
int pendingConnectionImportance; // To be filled in to ProcessRecord once it connects
+ // any current binding to this service has BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS flag?
+ private boolean hasBindingWhitelistingBgActivityStarts;
+ // is this service currently whitelisted to start activities from background by providing
+ // allowBackgroundActivityStarts=true to startServiceLocked()?
+ boolean hasStartedWhitelistingBgActivityStarts;
+ // used to clean up the state of hasStartedWhitelistingBgActivityStarts after a timeout
+ Runnable startedWhitelistingBgActivityStartsCleanUp;
+
String stringName; // caching of toString
private int lastStartId; // identifier of most recent start request.
@@ -371,6 +379,14 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
if (whitelistManager) {
pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager);
}
+ if (hasBindingWhitelistingBgActivityStarts) {
+ pw.print(prefix); pw.print("hasBindingWhitelistingBgActivityStarts=");
+ pw.println(hasBindingWhitelistingBgActivityStarts);
+ }
+ if (hasStartedWhitelistingBgActivityStarts) {
+ pw.print(prefix); pw.print("hasStartedWhitelistingBgActivityStarts=");
+ pw.println(hasStartedWhitelistingBgActivityStarts);
+ }
if (delayed) {
pw.print(prefix); pw.print("delayed="); pw.println(delayed);
}
@@ -518,6 +534,15 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
}
public void setProcess(ProcessRecord _proc) {
+ if (_proc != null) {
+ if (hasStartedWhitelistingBgActivityStarts || hasBindingWhitelistingBgActivityStarts) {
+ _proc.addAllowBackgroundActivityStartsToken(this);
+ } else {
+ _proc.removeAllowBackgroundActivityStartsToken(this);
+ }
+ } else if (app != null) {
+ app.removeAllowBackgroundActivityStartsToken(this);
+ }
app = _proc;
if (pendingConnectionGroup > 0 && _proc != null) {
_proc.connectionService = this;
@@ -540,6 +565,62 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
}
}
+ void updateHasBindingWhitelistingBgActivityStarts() {
+ boolean hasWhitelistingBinding = false;
+ for (int conni = connections.size() - 1; conni >= 0; conni--) {
+ ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
+ for (int i = 0; i < cr.size(); i++) {
+ if ((cr.get(i).flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) {
+ hasWhitelistingBinding = true;
+ break;
+ }
+ }
+ if (hasWhitelistingBinding) {
+ break;
+ }
+ }
+ if (hasBindingWhitelistingBgActivityStarts != hasWhitelistingBinding) {
+ hasBindingWhitelistingBgActivityStarts = hasWhitelistingBinding;
+ updateParentProcessBgActivityStartsWhitelistingToken();
+ }
+ }
+
+ void setHasBindingWhitelistingBgActivityStarts(boolean newValue) {
+ if (hasBindingWhitelistingBgActivityStarts != newValue) {
+ hasBindingWhitelistingBgActivityStarts = newValue;
+ updateParentProcessBgActivityStartsWhitelistingToken();
+ }
+ }
+
+ void setHasStartedWhitelistingBgActivityStarts(boolean newValue) {
+ if (hasStartedWhitelistingBgActivityStarts != newValue) {
+ hasStartedWhitelistingBgActivityStarts = newValue;
+ updateParentProcessBgActivityStartsWhitelistingToken();
+ }
+ }
+
+ /**
+ * Whether the process this service runs in should be temporarily whitelisted to start
+ * activities from background depends on the current state of both
+ * {@code hasStartedWhitelistingBgActivityStarts} and
+ * {@code hasBindingWhitelistingBgActivityStarts}. If either is true, this ServiceRecord
+ * should be contributing as a token in parent ProcessRecord.
+ *
+ * @see com.android.server.am.ProcessRecord#mAllowBackgroundActivityStartsTokens
+ */
+ private void updateParentProcessBgActivityStartsWhitelistingToken() {
+ if (app == null) {
+ return;
+ }
+ if (hasStartedWhitelistingBgActivityStarts || hasBindingWhitelistingBgActivityStarts) {
+ // if the token is already there it's safe to "re-add it" - we're deadling with
+ // a set of Binder objects
+ app.addAllowBackgroundActivityStartsToken(this);
+ } else {
+ app.removeAllowBackgroundActivityStartsToken(this);
+ }
+ }
+
public AppBindRecord retrieveAppBindingLocked(Intent intent,
ProcessRecord app) {
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
index 66d934541260..2ed25eab50c0 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
@@ -99,8 +99,8 @@ public class AccessibilityServiceConnectionTest {
public void bind_requestsContextToBindService() {
mConnection.bindLocked();
verify(mMockContext).bindServiceAsUser(any(Intent.class), eq(mConnection),
- eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE),
- any(UserHandle.class));
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS), any(UserHandle.class));
}
@Test
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 61d7d6cf45d2..8d2cbca08586 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -357,7 +357,8 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
intent.setComponent(mComponent);
mBound = mContext.bindServiceAsUser(intent, mConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUser));
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser));
if (!mBound) {
Slog.w(TAG, "Failed binding to voice interaction service " + mComponent);
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 1bf07233fc4d..24690f51f9ce 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -159,7 +159,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
mBindIntent.setComponent(mSessionComponentName);
mBound = mContext.bindServiceAsUser(mBindIntent, this,
Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY
- | Context.BIND_ALLOW_OOM_MANAGEMENT, new UserHandle(mUser));
+ | Context.BIND_ALLOW_OOM_MANAGEMENT
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser));
if (mBound) {
try {
mIWindowManager.addWindowToken(mToken, TYPE_VOICE_INTERACTION, DEFAULT_DISPLAY);
@@ -191,7 +192,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
if (!mFullyBound) {
mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY
- | Context.BIND_FOREGROUND_SERVICE,
+ | Context.BIND_FOREGROUND_SERVICE
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS,
new UserHandle(mUser));
}