Add new API to set URI on AssistContent.
Also rework how we transfer AssistContent and AssistStructure
to the assistant, so they are delivered as completely separate
objects rather than the kludgy bundling them in the assist
data thing.
Change-Id: Ib40cc3b152bafeb358fd3adec564a7dda3a0dd1d
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 02e0d5b..e4def1e 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2193,7 +2193,9 @@
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
Bundle extras = data.readBundle();
- reportAssistContextExtras(token, extras);
+ AssistStructure structure = AssistStructure.CREATOR.createFromParcel(data);
+ AssistContent content = AssistContent.CREATOR.createFromParcel(data);
+ reportAssistContextExtras(token, extras, structure, content);
reply.writeNoException();
return true;
}
@@ -5359,13 +5361,15 @@
reply.recycle();
}
- public void reportAssistContextExtras(IBinder token, Bundle extras)
- throws RemoteException {
+ public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
+ AssistContent content) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
data.writeBundle(extras);
+ structure.writeToParcel(data, 0);
+ content.writeToParcel(data, 0);
mRemote.transact(REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index cb436b5..2a98b6c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2562,15 +2562,18 @@
public void handleRequestAssistContextExtras(RequestAssistContextExtras cmd) {
Bundle data = new Bundle();
+ AssistStructure structure = null;
+ AssistContent content = new AssistContent();
ActivityClientRecord r = mActivities.get(cmd.activityToken);
if (r != null) {
r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
r.activity.onProvideAssistData(data);
if (cmd.requestType == ActivityManager.ASSIST_CONTEXT_FULL) {
- data.putParcelable(AssistStructure.ASSIST_KEY, new AssistStructure(r.activity));
- AssistContent content = new AssistContent();
+ structure = new AssistStructure(r.activity);
Intent activityIntent = r.activity.getIntent();
- if (activityIntent != null) {
+ if (activityIntent != null && (r.window == null ||
+ (r.window.getAttributes().flags
+ & WindowManager.LayoutParams.FLAG_SECURE) == 0)) {
Intent intent = new Intent(activityIntent);
intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
@@ -2580,15 +2583,14 @@
content.setIntent(new Intent());
}
r.activity.onProvideAssistContent(content);
- data.putParcelable(AssistContent.ASSIST_KEY, content);
}
}
- if (data.isEmpty()) {
- data = null;
+ if (structure == null) {
+ structure = new AssistStructure();
}
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
- mgr.reportAssistContextExtras(cmd.requestToken, data);
+ mgr.reportAssistContextExtras(cmd.requestToken, data, structure, content);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java
index cb1a3f5..f271af1 100644
--- a/core/java/android/app/AssistContent.java
+++ b/core/java/android/app/AssistContent.java
@@ -18,6 +18,7 @@
import android.content.ClipData;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,14 +31,17 @@
public class AssistContent implements Parcelable {
private Intent mIntent;
private ClipData mClipData;
+ private Uri mUri;
/**
+ * @hide
* Key name this data structure is stored in the Bundle generated by
* {@link Activity#onProvideAssistData}.
*/
public static final String ASSIST_KEY = "android:assist_content";
/**
+ * @hide
* Retrieve the framework-generated AssistContent that is stored within
* the Bundle filled in by {@link Activity#onProvideAssistContent}.
*/
@@ -56,6 +60,13 @@
*/
public void setIntent(Intent intent) {
mIntent = intent;
+ setWebUri(null);
+ if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
+ setWebUri(uri);
+ }
+ }
}
/**
@@ -81,6 +92,30 @@
return mClipData;
}
+ /**
+ * Set a web URI associated with the current data being shown to the user.
+ * This URI could be opened in a web browser, or in the app as an
+ * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
+ * being displayed by it. The URI here should be something that is transportable
+ * off the device into other environments to acesss the same data as is currently
+ * being shown in the app; if the app does not have such a representation, it should
+ * leave the null and only report the local intent and clip data.
+ *
+ * <p>This will be automatically populated for you from {@link #setIntent} if that Intent
+ * is an {@link Intent#ACTION_VIEW} of a web (http or https scheme) URI.</p>
+ */
+ public void setWebUri(Uri uri) {
+ mUri = uri;
+ }
+
+ /**
+ * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
+ * there is none.
+ */
+ public Uri getWebUri() {
+ return mUri;
+ }
+
AssistContent(Parcel in) {
if (in.readInt() != 0) {
mIntent = Intent.CREATOR.createFromParcel(in);
@@ -88,6 +123,9 @@
if (in.readInt() != 0) {
mClipData = ClipData.CREATOR.createFromParcel(in);
}
+ if (in.readInt() != 0) {
+ mUri = Uri.CREATOR.createFromParcel(in);
+ }
}
@Override
@@ -109,6 +147,12 @@
} else {
dest.writeInt(0);
}
+ if (mUri != null) {
+ dest.writeInt(1);
+ mUri.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
}
public static final Parcelable.Creator<AssistContent> CREATOR
diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java
index b703b0e..bb9cb3b 100644
--- a/core/java/android/app/AssistStructure.java
+++ b/core/java/android/app/AssistStructure.java
@@ -42,13 +42,13 @@
/**
* Assist data automatically created by the platform's implementation
- * of {@link Activity#onProvideAssistData}. Retrieve it from the assist
- * data with {@link #getAssistStructure(android.os.Bundle)}.
+ * of {@link Activity#onProvideAssistData}.
*/
final public class AssistStructure implements Parcelable {
static final String TAG = "AssistStructure";
/**
+ * @hide
* Key name this data structure is stored in the Bundle generated by
* {@link Activity#onProvideAssistData}.
*/
@@ -741,6 +741,11 @@
}
}
+ AssistStructure() {
+ mHaveData = true;
+ mActivityComponent = null;
+ }
+
AssistStructure(Parcel in) {
mReceiveChannel = in.readStrongBinder();
}
@@ -811,6 +816,7 @@
}
/**
+ * @hide
* Retrieve the framework-generated AssistStructure that is stored within
* the Bundle filled in by {@link Activity#onProvideAssistData}.
*/
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c42719b..0a425ae 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -433,7 +433,8 @@
public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
throws RemoteException;
- public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException;
+ public void reportAssistContextExtras(IBinder token, Bundle extras,
+ AssistStructure structure, AssistContent content) throws RemoteException;
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
throws RemoteException;
diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl
index 7c90261..894edac 100644
--- a/core/java/android/service/voice/IVoiceInteractionSession.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl
@@ -16,6 +16,8 @@
package android.service.voice;
+import android.app.AssistContent;
+import android.app.AssistStructure;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
@@ -28,7 +30,7 @@
oneway interface IVoiceInteractionSession {
void show(in Bundle sessionArgs, int flags, IVoiceInteractionSessionShowCallback showCallback);
void hide();
- void handleAssist(in Bundle assistData);
+ void handleAssist(in Bundle assistData, in AssistStructure structure, in AssistContent content);
void handleScreenshot(in Bitmap screenshot);
void taskStarted(in Intent intent, int taskId);
void taskFinished(in Intent intent, int taskId);
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index f122d10..f09b6a2 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -16,6 +16,7 @@
package android.service.voice;
+import android.app.AssistContent;
import android.app.AssistStructure;
import android.app.Dialog;
import android.app.Instrumentation;
@@ -180,21 +181,16 @@
}
@Override
- public void handleAssist(Bundle assistBundle) {
+ public void handleAssist(Bundle data, AssistStructure structure,
+ AssistContent content) {
// We want to pre-warm the AssistStructure before handing it off to the main
// thread. There is a strong argument to be made that it should be handed
// through as a separate param rather than part of the assistBundle.
- if (assistBundle != null) {
- Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
- if (assistContext != null) {
- AssistStructure as = AssistStructure.getAssistStructure(assistContext);
- if (as != null) {
- as.ensureData();
- }
- }
+ if (structure != null) {
+ structure.ensureData();
}
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_ASSIST,
- assistBundle));
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOOO(MSG_HANDLE_ASSIST,
+ data, structure, content));
}
@Override
@@ -422,8 +418,11 @@
doDestroy();
break;
case MSG_HANDLE_ASSIST:
- if (DEBUG) Log.d(TAG, "onHandleAssist: " + msg.obj);
- onHandleAssist((Bundle) msg.obj);
+ args = (SomeArgs)msg.obj;
+ if (DEBUG) Log.d(TAG, "onHandleAssist: data=" + args.arg1
+ + " structure=" + args.arg2 + " content=" + args.arg3);
+ onHandleAssist((Bundle) args.arg1, (AssistStructure) args.arg2,
+ (AssistContent) args.arg3);
break;
case MSG_HANDLE_SCREENSHOT:
if (DEBUG) Log.d(TAG, "onHandleScreenshot: " + msg.obj);
@@ -817,9 +816,22 @@
}
+ /** @hide */
public void onHandleAssist(Bundle assistBundle) {
}
+ public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
+ if (data != null) {
+ Bundle assistContext = data.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
+ if (assistContext != null) {
+ assistContext.putParcelable(AssistStructure.ASSIST_KEY, structure);
+ assistContext.putParcelable(AssistContent.ASSIST_KEY, content);
+ data.putBundle(Intent.EXTRA_ASSIST_CONTEXT, assistContext);
+ }
+ }
+ onHandleAssist(data);
+ }
+
/** @hide */
public void onHandleScreenshot(Bitmap screenshot) {
}