summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Casey <mrcasey@google.com>2013-08-08 09:33:07 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-08-08 09:33:08 +0000
commit77ece7b192d45351b313ee23270caab373d3c477 (patch)
treecc2ebf80b6dc0d4489bbeee0eeabda6c344ff551
parent81ba97841089bd23b82c7c6feadd3112ad22966c (diff)
parentdfc7fd7818cda46b914c8a9d69d1ba00443ffe5b (diff)
downloadframeworks_base-77ece7b192d45351b313ee23270caab373d3c477.zip
frameworks_base-77ece7b192d45351b313ee23270caab373d3c477.tar.gz
frameworks_base-77ece7b192d45351b313ee23270caab373d3c477.tar.bz2
Merge "Extend assist context to foreground services"
-rw-r--r--api/current.txt4
-rw-r--r--core/java/android/app/ActivityManagerNative.java19
-rw-r--r--core/java/android/app/ActivityThread.java29
-rw-r--r--core/java/android/app/ApplicationThreadNative.java13
-rw-r--r--core/java/android/app/IActivityManager.java9
-rw-r--r--core/java/android/app/IApplicationThread.java6
-rw-r--r--core/java/android/app/SearchManager.java2
-rw-r--r--core/java/android/app/Service.java13
-rw-r--r--core/java/android/content/Intent.java33
-rw-r--r--core/java/android/content/pm/PackageParser.java5
-rw-r--r--core/java/android/content/pm/ServiceInfo.java8
-rw-r--r--core/res/res/values/attrs_manifest.xml3
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java139
14 files changed, 212 insertions, 75 deletions
diff --git a/api/current.txt b/api/current.txt
index b8795f3..d79a8c0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4228,6 +4228,7 @@ package android.app {
method public void onCreate();
method public void onDestroy();
method public void onLowMemory();
+ method public void onProvideAssistData(android.os.Bundle);
method public void onRebind(android.content.Intent);
method public deprecated void onStart(android.content.Intent, int);
method public int onStartCommand(android.content.Intent, int, int);
@@ -6273,6 +6274,8 @@ package android.content {
field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
+ field public static final java.lang.String EXTRA_ASSIST_SERVICES_CONTEXTS = "android.intent.extra.ASSIST_SERVICES_CONTEXTS";
+ field public static final java.lang.String EXTRA_ASSIST_SERVICES_PACKAGES = "android.intent.extra.ASSIST_SERVICES_PACKAGES";
field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -7337,6 +7340,7 @@ package android.content.pm {
method public void dump(android.util.Printer, java.lang.String);
field public static final android.os.Parcelable.Creator CREATOR;
field public static final int FLAG_ISOLATED_PROCESS = 2; // 0x2
+ field public static final int FLAG_PROVIDE_ASSIST_DATA = 4; // 0x4
field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000
field public static final int FLAG_STOP_WITH_TASK = 1; // 0x1
field public int flags;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 404f6aa..cc964c2 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1921,20 +1921,21 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
- case GET_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+ case GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int requestType = data.readInt();
- Bundle res = getTopActivityExtras(requestType);
+ Bundle res = getAssistContextExtras(requestType);
reply.writeNoException();
reply.writeBundle(res);
return true;
}
- case REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+ case REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
Bundle extras = data.readBundle();
- reportTopActivityExtras(token, extras);
+ int index = data.readInt();
+ reportAssistContextExtras(token, extras, index);
reply.writeNoException();
return true;
}
@@ -4456,12 +4457,12 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
- public Bundle getTopActivityExtras(int requestType) throws RemoteException {
+ public Bundle getAssistContextExtras(int requestType) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(requestType);
- mRemote.transact(GET_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
+ mRemote.transact(GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
reply.readException();
Bundle res = reply.readBundle();
data.recycle();
@@ -4469,13 +4470,15 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
- public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException {
+ public void reportAssistContextExtras(IBinder token, Bundle extras, int index)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
data.writeBundle(extras);
- mRemote.transact(REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
+ data.writeInt(index);
+ mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5300eca..2a28b76 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -529,10 +529,11 @@ public final class ActivityThread {
CompatibilityInfo info;
}
- static final class RequestActivityExtras {
+ static final class RequestAssistContextExtras {
IBinder activityToken;
IBinder requestToken;
int requestType;
+ int index;
}
private native void dumpGraphicsInfo(FileDescriptor fd);
@@ -1197,13 +1198,14 @@ public final class ActivityThread {
}
@Override
- public void requestActivityExtras(IBinder activityToken, IBinder requestToken,
- int requestType) {
- RequestActivityExtras cmd = new RequestActivityExtras();
+ public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
+ int requestType, int index) {
+ RequestAssistContextExtras cmd = new RequestAssistContextExtras();
cmd.activityToken = activityToken;
cmd.requestToken = requestToken;
cmd.requestType = requestType;
- queueOrSendMessage(H.REQUEST_ACTIVITY_EXTRAS, cmd);
+ cmd.index = index;
+ queueOrSendMessage(H.REQUEST_ASSIST_CONTEXT_EXTRAS, cmd);
}
private void printRow(PrintWriter pw, String format, Object...objs) {
@@ -1292,7 +1294,7 @@ public final class ActivityThread {
public static final int TRIM_MEMORY = 140;
public static final int DUMP_PROVIDER = 141;
public static final int UNSTABLE_PROVIDER_DIED = 142;
- public static final int REQUEST_ACTIVITY_EXTRAS = 143;
+ public static final int REQUEST_ASSIST_CONTEXT_EXTRAS = 143;
public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144;
String codeToString(int code) {
if (DEBUG_MESSAGES) {
@@ -1340,7 +1342,7 @@ public final class ActivityThread {
case TRIM_MEMORY: return "TRIM_MEMORY";
case DUMP_PROVIDER: return "DUMP_PROVIDER";
case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
- case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS";
+ case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
}
}
@@ -1553,8 +1555,8 @@ public final class ActivityThread {
case UNSTABLE_PROVIDER_DIED:
handleUnstableProviderDied((IBinder)msg.obj, false);
break;
- case REQUEST_ACTIVITY_EXTRAS:
- handleRequestActivityExtras((RequestActivityExtras)msg.obj);
+ case REQUEST_ASSIST_CONTEXT_EXTRAS:
+ handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
break;
case TRANSLUCENT_CONVERSION_COMPLETE:
handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
@@ -2275,19 +2277,24 @@ public final class ActivityThread {
performNewIntents(data.token, data.intents);
}
- public void handleRequestActivityExtras(RequestActivityExtras cmd) {
+ public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
Bundle data = new Bundle();
ActivityClientRecord r = mActivities.get(cmd.activityToken);
if (r != null) {
r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
r.activity.onProvideAssistData(data);
+ } else {
+ Service service = mServices.get(cmd.activityToken);
+ if (service != null) {
+ service.onProvideAssistData(data);
+ }
}
if (data.isEmpty()) {
data = null;
}
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
- mgr.reportTopActivityExtras(cmd.requestToken, data);
+ mgr.reportAssistContextExtras(cmd.requestToken, data, cmd.index);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 1465de2..c0080be 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -600,13 +600,14 @@ public abstract class ApplicationThreadNative extends Binder
return true;
}
- case REQUEST_ACTIVITY_EXTRAS_TRANSACTION:
+ case REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION:
{
data.enforceInterface(IApplicationThread.descriptor);
IBinder activityToken = data.readStrongBinder();
IBinder requestToken = data.readStrongBinder();
int requestType = data.readInt();
- requestActivityExtras(activityToken, requestToken, requestType);
+ int index = data.readInt();
+ requestAssistContextExtras(activityToken, requestToken, requestType, index);
reply.writeNoException();
return true;
}
@@ -1241,14 +1242,16 @@ class ApplicationThreadProxy implements IApplicationThread {
}
@Override
- public void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
- throws RemoteException {
+ public void requestAssistContextExtras(IBinder activityToken, IBinder requestToken,
+ int requestType, int index) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(activityToken);
data.writeStrongBinder(requestToken);
data.writeInt(requestType);
- mRemote.transact(REQUEST_ACTIVITY_EXTRAS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+ data.writeInt(index);
+ mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, null,
+ IBinder.FLAG_ONEWAY);
data.recycle();
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 3eda58c..3851eb3 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -386,9 +386,10 @@ public interface IActivityManager extends IInterface {
public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
- public Bundle getTopActivityExtras(int requestType) throws RemoteException;
+ public Bundle getAssistContextExtras(int requestType) throws RemoteException;
- public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException;
+ public void reportAssistContextExtras(IBinder token, Bundle extras, int index)
+ throws RemoteException;
public void killUid(int uid, String reason) throws RemoteException;
@@ -662,8 +663,8 @@ public interface IActivityManager extends IInterface {
int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
- int GET_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
- int REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
+ int GET_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
+ int REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
int GET_LAUNCHED_FROM_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+163;
int KILL_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+164;
int SET_USER_IS_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+165;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 61c499a..01a0a91 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -133,8 +133,8 @@ public interface IApplicationThread extends IInterface {
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
void unstableProviderDied(IBinder provider) throws RemoteException;
- void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
- throws RemoteException;
+ void requestAssistContextExtras(IBinder activityToken, IBinder requestToken, int requestType,
+ int index) throws RemoteException;
void scheduleTranslucentConversionComplete(IBinder token, boolean timeout)
throws RemoteException;
void setProcessState(int state) throws RemoteException;
@@ -187,7 +187,7 @@ public interface IApplicationThread extends IInterface {
int DUMP_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
- int REQUEST_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
+ int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48;
int SET_PROCESS_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+49;
}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 7dfc589..f9c245e 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -869,7 +869,7 @@ public class SearchManager
intent.setComponent(comp);
if (inclContext) {
IActivityManager am = ActivityManagerNative.getDefault();
- Bundle extras = am.getTopActivityExtras(0);
+ Bundle extras = am.getAssistContextExtras(0);
if (extras != null) {
intent.replaceExtras(extras);
}
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 3967740..7f8ddfd 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -23,6 +23,7 @@ import android.content.ContextWrapper;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.IBinder;
import android.util.Log;
@@ -307,6 +308,18 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
}
/**
+ * This is called on foreground services when the user is requesting an assist, to build a
+ * full {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
+ * running foreground services. You can override this method to place into the bundle
+ * anything you would like to appear as an item in the
+ * {@link Intent#EXTRA_SERVICES_ASSIST_CONTEXT} part of the assist Intent.
+ * This method will not be called if this service is not in the foreground.
+ * The default implementation does nothing.
+ */
+ public void onProvideAssistData(Bundle data) {
+ }
+
+ /**
* @deprecated Implement {@link #onStartCommand(Intent, int, int)} instead.
*/
@Deprecated
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 205ca6b..ff350b9 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1152,9 +1152,10 @@ public class Intent implements Parcelable, Cloneable {
/**
* Activity Action: Perform assist action.
* <p>
- * Input: {@link #EXTRA_ASSIST_PACKAGE} and {@link #EXTRA_ASSIST_CONTEXT} can provide
- * additional optional contextual information about where the user was when they requested
- * the assist.
+ * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT},
+ * {@link #EXTRA_ASSIST_SERVICES_PACKAGES}, and {@link #EXTRA_ASSIST_SERVICES_CONTEXTS} can
+ * provide additional optional contextual information about where the user was when they
+ * requested the assist.
* Output: nothing.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@@ -1163,9 +1164,10 @@ public class Intent implements Parcelable, Cloneable {
/**
* Activity Action: Perform voice assist action.
* <p>
- * Input: {@link #EXTRA_ASSIST_PACKAGE} and {@link #EXTRA_ASSIST_CONTEXT} can provide
- * additional optional contextual information about where the user was when they requested
- * the voice assist.
+ * Input: {@link #EXTRA_ASSIST_PACKAGE}, {@link #EXTRA_ASSIST_CONTEXT},
+ * {@link #EXTRA_ASSIST_SERVICES_PACKAGES}, and {@link #EXTRA_ASSIST_SERVICES_CONTEXTS} can
+ * provide additional optional contextual information about where the user was when they
+ * requested the voice assist.
* Output: nothing.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@@ -1189,6 +1191,25 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.extra.ASSIST_CONTEXT";
/**
+ * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
+ * containing an the names of the application package of foreground services at the time
+ * of the assist request. This is an array of {@link String}s, with one entry
+ * per service.
+ */
+ public static final String EXTRA_ASSIST_SERVICES_PACKAGES
+ = "android.intent.extra.ASSIST_SERVICES_PACKAGES";
+
+ /**
+ * An optional field on {@link #ACTION_ASSIST} and {@link #ACTION_VOICE_ASSIST}
+ * containing additional contextual information supplied by the current
+ * foreground services at the time of the assist request. This is an array
+ * of {@link Bundle}s of additional data, with one {@link Bundle} per service.
+ */
+ public static final String EXTRA_ASSIST_SERVICES_CONTEXTS
+ = "android.intent.extra.ASSIST_SERVICES_CONTEXTS";
+
+
+ /**
* Activity Action: List all available applications
* <p>Input: Nothing.
* <p>Output: nothing.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index aaa2640..b432164 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3005,6 +3005,11 @@ public class PackageParser {
s.info.flags = 0;
if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestService_provideAssistData,
+ false)) {
+ s.info.flags |= ServiceInfo.FLAG_PROVIDE_ASSIST_DATA;
+ }
+ if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestService_stopWithTask,
false)) {
s.info.flags |= ServiceInfo.FLAG_STOP_WITH_TASK;
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 796c2a4..a57a853 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -49,6 +49,14 @@ public class ServiceInfo extends ComponentInfo
public static final int FLAG_ISOLATED_PROCESS = 0x0002;
/**
+ * Bit in {@link #flags}: If set,
+ * {@link Service#onProvideAssistData(android.os.Bundle)} will be
+ * called on the service when it is running in the foreground. Set from
+ * the {@link android.R.attr#provideAssistData} attribute.
+ */
+ public static final int FLAG_PROVIDE_ASSIST_DATA = 0x0004;
+
+ /**
* Bit in {@link #flags}: If set, a single instance of the service will
* run for all users on the device. Set from the
* {@link android.R.attr#singleUser} attribute.
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 728b1b0..60ed0e5 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1379,6 +1379,9 @@
component specific values). -->
<attr name="enabled" />
<attr name="exported" />
+ <!-- If set to true, onProvideAssistData will be called on this service when this service
+ is running in the foreground. -->
+ <attr name="provideAssistData" format="boolean" />
<!-- If set to true, this service with be automatically stopped
when the user remove a task rooted in an activity owned by
the application. The default is false. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1b5ee68..138debf 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -831,8 +831,8 @@
<string name="permlab_getTopActivityInfo">get current app info</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_getTopActivityInfo">Allows the holder to retrieve private information
- about the current application in the foreground of the screen.</string>
-
+ about the current application and services in the foreground of the screen.</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_runSetActivityWatcher">monitor and control all app launching</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2d2d468..3d8843e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -184,6 +184,7 @@ import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -306,8 +307,13 @@ public final class ActivityManagerService extends ActivityManagerNative
// Maximum number of users we allow to be running at a time.
static final int MAX_RUNNING_USERS = 3;
- // How long to wait in getTopActivityExtras for the activity to respond with the result.
- static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000;
+ // How long to wait in getAssistContextExtras for the activity and foreground services
+ // to respond with the result.
+ static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
+
+ // Index for assist context bundle pertaining to the top activity. Non-negative indices
+ // correspond to assist context bundles from foreground services.
+ static final int TOP_ACTIVITY_ASSIST_EXTRAS_INDEX = -1;
static final int MY_PID = Process.myPid();
@@ -383,25 +389,38 @@ public final class ActivityManagerService extends ActivityManagerNative
*/
private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
- public class PendingActivityExtras extends Binder implements Runnable {
+ public class PendingAssistExtras extends Binder implements Runnable {
public final ActivityRecord activity;
- public boolean haveResult = false;
- public Bundle result = null;
- public PendingActivityExtras(ActivityRecord _activity) {
+ public final List<ServiceRecord> services;
+ public int numPending;
+ public int numRespondedServices = 0;
+ public Bundle activityExtras = null;
+ public Bundle[] servicesExtras;
+ public PendingAssistExtras(ActivityRecord _activity, List<ServiceRecord> _services) {
activity = _activity;
+ services = _services;
+ numPending = services.size() + 1;
}
@Override
public void run() {
- Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity);
+ if (activityExtras == null) {
+ Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
+ }
+ for (int i = 0; i < services.size(); i++) {
+ if (servicesExtras[i] == null) {
+ Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from "
+ + services.get(i));
+ }
+ }
synchronized (this) {
- haveResult = true;
+ numPending = 0;
notifyAll();
}
}
}
- final ArrayList<PendingActivityExtras> mPendingActivityExtras
- = new ArrayList<PendingActivityExtras>();
+ final ArrayList<PendingAssistExtras> mPendingAssistExtras
+ = new ArrayList<PendingAssistExtras>();
/**
* Process management.
@@ -7986,60 +8005,110 @@ public final class ActivityManagerService extends ActivityManagerNative
return true;
}
- public Bundle getTopActivityExtras(int requestType) {
+ public Bundle getAssistContextExtras(int requestType) {
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
- "getTopActivityExtras()");
- PendingActivityExtras pae;
+ "getAssistContextExtras()");
+ PendingAssistExtras pae;
Bundle extras = new Bundle();
+ List<ServiceRecord> foregroundServices;
synchronized (this) {
+ Collection<ServiceRecord> allServices = mServices.mServiceMap.getAllServices(
+ Binder.getCallingUid());
+ foregroundServices = new ArrayList<ServiceRecord>();
+ for (ServiceRecord record : allServices) {
+ if ((record.serviceInfo.flags & ServiceInfo.FLAG_PROVIDE_ASSIST_DATA) > 0 &&
+ record.isForeground) {
+ if (record.app == null || record.app.thread == null) {
+ Slog.w(TAG, "getAssistContextExtras error: no process for " + record);
+ continue;
+ }
+ if (record.app.pid == Binder.getCallingPid()) {
+ Slog.w(TAG, "getAssistContextExtras error: request process same as " +
+ record);
+ continue;
+ }
+ foregroundServices.add(record);
+ }
+ }
+
ActivityRecord activity = getFocusedStack().mResumedActivity;
+ boolean validActivity = true;
if (activity == null) {
- Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
- return null;
+ Slog.w(TAG, "getAssistContextExtras error: no resumed activity");
+ validActivity = false;
}
- extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
if (activity.app == null || activity.app.thread == null) {
- Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity);
- return extras;
+ Slog.w(TAG, "getAssistContextExtras error: no process for " + activity);
+ validActivity = false;
}
if (activity.app.pid == Binder.getCallingPid()) {
- Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity);
- return extras;
+ Slog.w(TAG, "getAssistContextExtras error: request process same as " + activity);
+ validActivity = false;
}
- pae = new PendingActivityExtras(activity);
+
+ pae = new PendingAssistExtras(activity, foregroundServices);
try {
- activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType);
- mPendingActivityExtras.add(pae);
- mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT);
+ if (validActivity) {
+ activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
+ requestType, -1);
+ }
+ for (int i = 0; i < foregroundServices.size(); i++) {
+ ServiceRecord record = foregroundServices.get(i);
+ record.app.thread.requestAssistContextExtras(record, pae, requestType, i);
+ }
+ mPendingAssistExtras.add(pae);
+ mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
} catch (RemoteException e) {
- Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity);
- return extras;
+ Slog.w(TAG, "getAssistContextExtras failed: crash fetching extras.", e);
}
}
synchronized (pae) {
- while (!pae.haveResult) {
+ while (pae.numPending > 0) {
try {
pae.wait();
} catch (InterruptedException e) {
}
}
- if (pae.result != null) {
- extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
+ if (pae.activityExtras != null) {
+ extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.activityExtras);
+ extras.putString(Intent.EXTRA_ASSIST_PACKAGE, pae.activity.packageName);
+ }
+ if (pae.numRespondedServices > 0) {
+ Bundle[] servicesExtras = new Bundle[pae.numRespondedServices];
+ String[] servicesPackages = new String[pae.numRespondedServices];
+ int extrasIndex = 0;
+ for (int i = 0; i < foregroundServices.size(); i++) {
+ if (pae.servicesExtras[i] != null) {
+ servicesExtras[extrasIndex] = pae.servicesExtras[i];
+ ServiceRecord record = foregroundServices.get(i);
+ servicesPackages[extrasIndex] = record.packageName;
+ extrasIndex++;
+ }
+ }
+ extras.putParcelableArray(Intent.EXTRA_ASSIST_SERVICES_CONTEXTS, servicesExtras);
+ extras.putStringArray(Intent.EXTRA_ASSIST_SERVICES_PACKAGES, servicesPackages);
}
}
synchronized (this) {
- mPendingActivityExtras.remove(pae);
+ mPendingAssistExtras.remove(pae);
mHandler.removeCallbacks(pae);
}
return extras;
}
- public void reportTopActivityExtras(IBinder token, Bundle extras) {
- PendingActivityExtras pae = (PendingActivityExtras)token;
+ public void reportAssistContextExtras(IBinder token, Bundle extras, int index) {
+ PendingAssistExtras pae = (PendingAssistExtras)token;
synchronized (pae) {
- pae.result = extras;
- pae.haveResult = true;
- pae.notifyAll();
+ if (index == TOP_ACTIVITY_ASSIST_EXTRAS_INDEX) {
+ pae.activityExtras = extras;
+ } else {
+ pae.servicesExtras[index] = extras;
+ pae.numRespondedServices++;
+ }
+ pae.numPending--;
+ if (pae.numPending == 0) {
+ pae.notifyAll();
+ }
}
}