• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package android.app.assist;
2 
3 import android.annotation.FlaggedApi;
4 import android.annotation.Nullable;
5 import android.compat.annotation.UnsupportedAppUsage;
6 import android.content.ClipData;
7 import android.content.Intent;
8 import android.net.Uri;
9 import android.os.Build;
10 import android.os.Bundle;
11 import android.os.Parcel;
12 import android.os.Parcelable;
13 
14 /**
15  * Holds information about the content an application is viewing, to hand to an
16  * assistant at the user's request.  This is filled in by
17  * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
18  */
19 public class AssistContent implements Parcelable {
20     /**
21      * Extra for a {@link Bundle} that provides contextual AppFunction's information about the
22      * content currently being viewed in the application.
23      * <p>
24      * This extra can be optionally supplied in the {@link AssistContent#getExtras()} bundle.
25      * <p>
26      * The schema of the {@link Bundle} in this extra is defined in the AppFunction SDK.
27      *
28      * @see android.app.appfunctions.AppFunctionManager
29      */
30     @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
31     public static final String EXTRA_APP_FUNCTION_DATA =
32             "android.app.assist.extra.APP_FUNCTION_DATA";
33 
34     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
35     private boolean mIsAppProvidedIntent = false;
36     private boolean mIsAppProvidedWebUri = false;
37     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
38     private Intent mIntent;
39     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
40     private String mStructuredData;
41     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
42     private ClipData mClipData;
43     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
44     private Uri mUri;
45     private Uri mSessionTransferUri;
46     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
47     private final Bundle mExtras;
48 
AssistContent()49     public AssistContent() {
50         mExtras = new Bundle();
51     }
52 
53     /**
54      * Create an AssistContent with extras initialized.
55      *
56      * @hide
57      */
AssistContent(@ndroid.annotation.NonNull Bundle extras)58     public AssistContent(@android.annotation.NonNull Bundle extras) {
59         mExtras = extras;
60     }
61 
62     /**
63      * Called by {@link android.app.ActivityThread} to set the default Intent based on
64      * {@link android.app.Activity#getIntent Activity.getIntent}.
65      *
66      * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
67      * of a web (http or https scheme) URI.</p>
68      *
69      * @hide
70      */
setDefaultIntent(Intent intent)71     public void setDefaultIntent(Intent intent) {
72         mIntent = intent;
73         mIsAppProvidedIntent = false;
74         mIsAppProvidedWebUri = false;
75         mUri = null;
76         if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
77             Uri uri = intent.getData();
78             if (uri != null) {
79                 if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
80                     mUri = uri;
81                 }
82             }
83         }
84     }
85 
86     /**
87      * Sets the Intent associated with the content, describing the current top-level context of
88      * the activity.  If this contains a reference to a piece of data related to the activity,
89      * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
90      * service can access it.
91      */
setIntent(Intent intent)92     public void setIntent(Intent intent) {
93         mIsAppProvidedIntent = true;
94         mIntent = intent;
95     }
96 
97     /**
98      * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from
99      * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place.
100      */
getIntent()101     public Intent getIntent() {
102         return mIntent;
103     }
104 
105     /**
106      * Returns whether or not the current Intent was explicitly provided in
107      * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
108      * the Intent was automatically set based on
109      * {@link android.app.Activity#getIntent Activity.getIntent}.
110      */
isAppProvidedIntent()111     public boolean isAppProvidedIntent() {
112         return mIsAppProvidedIntent;
113     }
114 
115     /**
116      * Optional additional content items that are involved with
117      * the current UI.  Access to this content will be granted to the assistant as if you
118      * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
119      */
setClipData(ClipData clip)120     public void setClipData(ClipData clip) {
121         mClipData = clip;
122     }
123 
124     /**
125      * Return the current {@link #setClipData}, which you can modify in-place.
126      */
getClipData()127     public ClipData getClipData() {
128         return mClipData;
129     }
130 
131     /**
132      * Sets optional structured data regarding the content being viewed. The provided data
133      * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
134      * <a href="http://schema.org/">schema.org</a> vocabulary.
135      */
setStructuredData(String structuredData)136     public void setStructuredData(String structuredData) {
137         mStructuredData = structuredData;
138     }
139 
140     /**
141      * Returns the current {@link #setStructuredData}.
142      */
getStructuredData()143     public String getStructuredData() {
144         return mStructuredData;
145     }
146 
147     /**
148      * Set a web URI associated with the current data being shown to the user.
149      * This URI could be opened in a web browser, or in the app as an
150      * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
151      * being displayed by it.  The URI here should be something that is transportable
152      * off the device into other environments to acesss the same data as is currently
153      * being shown in the app; if the app does not have such a representation, it should
154      * leave the null and only report the local intent and clip data.
155      */
setWebUri(Uri uri)156     public void setWebUri(Uri uri) {
157         mIsAppProvidedWebUri = true;
158         mUri = uri;
159     }
160 
161     /**
162      * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
163      * there is none.
164      */
getWebUri()165     public Uri getWebUri() {
166         return mUri;
167     }
168 
169     /**
170      * Returns whether or not the current {@link #getWebUri} was explicitly provided in
171      * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
172      * the Intent was automatically set based on
173      * {@link android.app.Activity#getIntent Activity.getIntent}.
174      */
isAppProvidedWebUri()175     public boolean isAppProvidedWebUri() {
176         return mIsAppProvidedWebUri;
177     }
178 
179     /**
180      * This method can be used to provide a {@link Uri} which will be utilized when transitioning a
181      * user's session to another surface.
182      *
183      * <p>If provided, instead of using the URI provided in {@link #setWebUri}, the
184      * "Open in browser" feature will use this URI to transition the current session from one
185      * surface to the other. Apps may choose to encode session or user information into this
186      * URI in order to provide a better session transfer experience. However, while this URI will
187      * only be available to the system and not other applications, developers should not encode
188      * authentication credentials into this URI, because it will be surfaced in the browser URL bar
189      * and may be copied and shared from there.
190      *
191      * <p>When providing this URI, developers should still continue to provide
192      * {@link #setWebUri} for backwards compatibility with features such as
193      * <a href="https://developer.android.com/guide/components/activities/recents#url-sharing">
194      * recents URL sharing</a> which facilitate link sharing with other users and would not benefit
195      * from a session-transfer URI.
196      *
197      * @see android.app.Activity#requestOpenInBrowserEducation()
198      */
199     @FlaggedApi(com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB_EDUCATION)
setSessionTransferUri(@ullable Uri uri)200     public void setSessionTransferUri(@Nullable Uri uri) {
201         mSessionTransferUri = uri;
202     }
203 
204     /**
205      * Return the content's session transfer web URI as per
206      * {@link #setSessionTransferUri(android.net.Uri)}, or null if there is none.
207      */
208     @FlaggedApi(com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB_EDUCATION)
209     @Nullable
getSessionTransferUri()210     public Uri getSessionTransferUri() {
211         return mSessionTransferUri;
212     }
213 
214     /**
215      * Return Bundle for extra vendor-specific data that can be modified and examined.
216      */
getExtras()217     public Bundle getExtras() {
218         return mExtras;
219     }
220 
221     @UnsupportedAppUsage
AssistContent(Parcel in)222     AssistContent(Parcel in) {
223         if (in.readInt() != 0) {
224             mIntent = Intent.CREATOR.createFromParcel(in);
225         }
226         if (in.readInt() != 0) {
227             mClipData = ClipData.CREATOR.createFromParcel(in);
228         }
229         if (in.readInt() != 0) {
230             mUri = Uri.CREATOR.createFromParcel(in);
231         }
232         if (in.readInt() != 0) {
233             mSessionTransferUri = Uri.CREATOR.createFromParcel(in);
234         }
235         if (in.readInt() != 0) {
236             mStructuredData = in.readString();
237         }
238         mIsAppProvidedIntent = in.readInt() == 1;
239         mExtras = in.readBundle();
240         mIsAppProvidedWebUri = in.readInt() == 1;
241     }
242 
243     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
writeToParcelInternal(Parcel dest, int flags)244     void writeToParcelInternal(Parcel dest, int flags) {
245         if (mIntent != null) {
246             dest.writeInt(1);
247             mIntent.writeToParcel(dest, flags);
248         } else {
249             dest.writeInt(0);
250         }
251         if (mClipData != null) {
252             dest.writeInt(1);
253             mClipData.writeToParcel(dest, flags);
254         } else {
255             dest.writeInt(0);
256         }
257         if (mUri != null) {
258             dest.writeInt(1);
259             mUri.writeToParcel(dest, flags);
260         } else {
261             dest.writeInt(0);
262         }
263         if (mSessionTransferUri != null) {
264             dest.writeInt(1);
265             mSessionTransferUri.writeToParcel(dest, flags);
266         } else {
267             dest.writeInt(0);
268         }
269         if (mStructuredData != null) {
270             dest.writeInt(1);
271             dest.writeString(mStructuredData);
272         } else {
273             dest.writeInt(0);
274         }
275         dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
276         dest.writeBundle(mExtras);
277         dest.writeInt(mIsAppProvidedWebUri ? 1 : 0);
278     }
279 
280     @Override
describeContents()281     public int describeContents() {
282         return 0;
283     }
284 
285     @Override
writeToParcel(Parcel dest, int flags)286     public void writeToParcel(Parcel dest, int flags) {
287         writeToParcelInternal(dest, flags);
288     }
289 
290     public static final @android.annotation.NonNull Parcelable.Creator<AssistContent> CREATOR
291             = new Parcelable.Creator<AssistContent>() {
292         public AssistContent createFromParcel(Parcel in) {
293             return new AssistContent(in);
294         }
295 
296         public AssistContent[] newArray(int size) {
297             return new AssistContent[size];
298         }
299     };
300 }
301