summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java14
-rw-r--r--core/java/android/app/ActivityManagerNative.java43
-rw-r--r--core/java/android/app/ActivityThread.java38
-rw-r--r--core/java/android/app/Application.java51
-rw-r--r--core/java/android/app/ApplicationThreadNative.java22
-rw-r--r--core/java/android/app/IActivityManager.java6
-rw-r--r--core/java/android/app/IApplicationThread.java3
-rw-r--r--core/java/android/app/SearchManager.java13
-rw-r--r--core/java/android/content/Intent.java21
-rw-r--r--core/java/android/view/SimulatedDpad.java2
10 files changed, 207 insertions, 6 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d6ddeb6..18ccd53 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1346,6 +1346,20 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * This is called when the user is requesting an assist, to build a full
+ * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
+ * application. You can override this method to place into the bundle anything
+ * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
+ * of the assist Intent. The default implementation does nothing.
+ *
+ * <p>This function will be called after any global assist callbacks that had
+ * been registered with {@link Application#registerOnProvideAssistData
+ * Application.registerOnProvideAssistData}.
+ */
+ public void onProvideAssistData(Bundle data) {
+ }
+
+ /**
* Called when you are no longer visible to the user. You will next
* receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 61b2067..bc27a57 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1818,6 +1818,24 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case GET_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int requestType = data.readInt();
+ Bundle res = getTopActivityExtras(requestType);
+ reply.writeNoException();
+ reply.writeBundle(res);
+ return true;
+ }
+
+ case REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ Bundle extras = data.readBundle();
+ reportTopActivityExtras(token, extras);
+ reply.writeNoException();
+ return true;
+ }
+
}
return super.onTransact(code, data, reply, flags);
@@ -4149,5 +4167,30 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public Bundle getTopActivityExtras(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);
+ reply.readException();
+ Bundle res = reply.readBundle();
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
+ public void reportTopActivityExtras(IBinder token, Bundle extras) 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);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1271645..570fb80 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -533,6 +533,12 @@ public final class ActivityThread {
String pkg;
CompatibilityInfo info;
}
+
+ static final class RequestActivityExtras {
+ IBinder activityToken;
+ IBinder requestToken;
+ int requestType;
+ }
private native void dumpGraphicsInfo(FileDescriptor fd);
@@ -1108,6 +1114,16 @@ public final class ActivityThread {
queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
}
+ @Override
+ public void requestActivityExtras(IBinder activityToken, IBinder requestToken,
+ int requestType) {
+ RequestActivityExtras cmd = new RequestActivityExtras();
+ cmd.activityToken = activityToken;
+ cmd.requestToken = requestToken;
+ cmd.requestType = requestType;
+ queueOrSendMessage(H.REQUEST_ACTIVITY_EXTRAS, cmd);
+ }
+
private void printRow(PrintWriter pw, String format, Object...objs) {
pw.println(String.format(format, objs));
}
@@ -1173,6 +1189,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;
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
@@ -1219,6 +1236,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";
}
}
return Integer.toString(code);
@@ -1430,6 +1448,9 @@ public final class ActivityThread {
case UNSTABLE_PROVIDER_DIED:
handleUnstableProviderDied((IBinder)msg.obj, false);
break;
+ case REQUEST_ACTIVITY_EXTRAS:
+ handleRequestActivityExtras((RequestActivityExtras)msg.obj);
+ break;
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
@@ -2322,6 +2343,23 @@ public final class ActivityThread {
performNewIntents(data.token, data.intents);
}
+ public void handleRequestActivityExtras(RequestActivityExtras 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);
+ }
+ if (data.isEmpty()) {
+ data = null;
+ }
+ IActivityManager mgr = ActivityManagerNative.getDefault();
+ try {
+ mgr.reportTopActivityExtras(cmd.requestToken, data);
+ } catch (RemoteException e) {
+ }
+ }
+
private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
/**
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 3a67cec..132388e 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -22,6 +22,7 @@ import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -45,6 +46,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
new ArrayList<ComponentCallbacks>();
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<ActivityLifecycleCallbacks>();
+ private ArrayList<OnProvideAssistData> mAssistCallbacks = null;
/** @hide */
public LoadedApk mLoadedApk;
@@ -59,6 +61,21 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
void onActivityDestroyed(Activity activity);
}
+ /**
+ * Callback interface for use with {@link Application#registerOnProvideAssistData}
+ * and {@link Application#unregisterOnProvideAssistData}.
+ */
+ public interface OnProvideAssistData {
+ /**
+ * This is called when the user is requesting an assist, to build a full
+ * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
+ * application. You can override this method to place into the bundle anything
+ * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
+ * of the assist Intent.
+ */
+ public void onProvideAssistData(Activity activity, Bundle data);
+ }
+
public Application() {
super(null);
}
@@ -137,7 +154,24 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
mActivityLifecycleCallbacks.remove(callback);
}
}
-
+
+ public void registerOnProvideAssistData(OnProvideAssistData callback) {
+ synchronized (this) {
+ if (mAssistCallbacks == null) {
+ mAssistCallbacks = new ArrayList<OnProvideAssistData>();
+ }
+ mAssistCallbacks.add(callback);
+ }
+ }
+
+ public void unregisterOnProvideAssistData(OnProvideAssistData callback) {
+ synchronized (this) {
+ if (mAssistCallbacks != null) {
+ mAssistCallbacks.remove(callback);
+ }
+ }
+ }
+
// ------------------ Internal API ------------------
/**
@@ -232,4 +266,19 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
}
return callbacks;
}
+
+ /* package */ void dispatchOnProvideAssistData(Activity activity, Bundle data) {
+ Object[] callbacks;
+ synchronized (this) {
+ if (mAssistCallbacks == null) {
+ return;
+ }
+ callbacks = mAssistCallbacks.toArray();
+ }
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((OnProvideAssistData)callbacks[i]).onProvideAssistData(activity, data);
+ }
+ }
+ }
}
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 63aa5f9..f0e367c 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -587,6 +587,17 @@ public abstract class ApplicationThreadNative extends Binder
reply.writeNoException();
return true;
}
+
+ case REQUEST_ACTIVITY_EXTRAS_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ IBinder activityToken = data.readStrongBinder();
+ IBinder requestToken = data.readStrongBinder();
+ int requestType = data.readInt();
+ requestActivityExtras(activityToken, requestToken, requestType);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -1185,4 +1196,15 @@ class ApplicationThreadProxy implements IApplicationThread {
mRemote.transact(UNSTABLE_PROVIDER_DIED_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}
+
+ public void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
+ 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.recycle();
+ }
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8af17a4..baac07f 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -368,6 +368,10 @@ public interface IActivityManager extends IInterface {
public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
+ public Bundle getTopActivityExtras(int requestType) throws RemoteException;
+
+ public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -624,4 +628,6 @@ 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;
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 03a26d4..8516694 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -130,6 +130,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;
String descriptor = "android.app.IApplicationThread";
@@ -179,4 +181,5 @@ 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;
}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 6382cee..7dfc589 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -846,8 +846,8 @@ public class SearchManager
*
* @hide
*/
- public Intent getAssistIntent(Context context) {
- return getAssistIntent(context, UserHandle.myUserId());
+ public Intent getAssistIntent(Context context, boolean inclContext) {
+ return getAssistIntent(context, inclContext, UserHandle.myUserId());
}
/**
@@ -856,7 +856,7 @@ public class SearchManager
*
* @hide
*/
- public Intent getAssistIntent(Context context, int userHandle) {
+ public Intent getAssistIntent(Context context, boolean inclContext, int userHandle) {
try {
if (mService == null) {
return null;
@@ -867,6 +867,13 @@ public class SearchManager
}
Intent intent = new Intent(Intent.ACTION_ASSIST);
intent.setComponent(comp);
+ if (inclContext) {
+ IActivityManager am = ActivityManagerNative.getDefault();
+ Bundle extras = am.getTopActivityExtras(0);
+ if (extras != null) {
+ intent.replaceExtras(extras);
+ }
+ }
return intent;
} catch (RemoteException re) {
Log.e(TAG, "getAssistIntent() failed: " + re);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b5349fd..dc367dd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1140,14 +1140,33 @@ public class Intent implements Parcelable, Cloneable {
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
+
/**
* Activity Action: Perform assist action.
* <p>
- * Input: nothing
+ * 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.
* Output: nothing.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_ASSIST = "android.intent.action.ASSIST";
+
+ /**
+ * An optional field on {@link #ACTION_ASSIST} containing the name of the current
+ * foreground application package at the time the assist was invoked.
+ */
+ public static final String EXTRA_ASSIST_PACKAGE
+ = "android.intent.extra.ASSIST_PACKAGE";
+
+ /**
+ * An optional field on {@link #ACTION_ASSIST} containing additional contextual
+ * information supplied by the current foreground app at the time of the assist
+ * request. This is a {@link Bundle} of additional data.
+ */
+ public static final String EXTRA_ASSIST_CONTEXT
+ = "android.intent.extra.ASSIST_CONTEXT";
+
/**
* Activity Action: List all available applications
* <p>Input: Nothing.
diff --git a/core/java/android/view/SimulatedDpad.java b/core/java/android/view/SimulatedDpad.java
index 0a37fdd..1ee416c 100644
--- a/core/java/android/view/SimulatedDpad.java
+++ b/core/java/android/view/SimulatedDpad.java
@@ -182,7 +182,7 @@ class SimulatedDpad {
Intent intent =
((SearchManager)mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT_OR_SELF);
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT_OR_SELF);
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {