1 package android.app.assist;
2 
3 import android.compat.annotation.UnsupportedAppUsage;
4 import android.content.ClipData;
5 import android.content.Intent;
6 import android.net.Uri;
7 import android.os.Build;
8 import android.os.Bundle;
9 import android.os.Parcel;
10 import android.os.Parcelable;
11 
12 /**
13  * Holds information about the content an application is viewing, to hand to an
14  * assistant at the user's request.  This is filled in by
15  * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
16  */
17 public class AssistContent implements Parcelable {
18     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
19     private boolean mIsAppProvidedIntent = false;
20     private boolean mIsAppProvidedWebUri = false;
21     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
22     private Intent mIntent;
23     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
24     private String mStructuredData;
25     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
26     private ClipData mClipData;
27     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
28     private Uri mUri;
29     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
30     private final Bundle mExtras;
31 
AssistContent()32     public AssistContent() {
33         mExtras = new Bundle();
34     }
35 
36     /**
37      * @hide
38      * Called by {@link android.app.ActivityThread} to set the default Intent based on
39      * {@link android.app.Activity#getIntent Activity.getIntent}.
40      *
41      * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
42      * of a web (http or https scheme) URI.</p>
43      */
setDefaultIntent(Intent intent)44     public void setDefaultIntent(Intent intent) {
45         mIntent = intent;
46         mIsAppProvidedIntent = false;
47         mIsAppProvidedWebUri = false;
48         mUri = null;
49         if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) {
50             Uri uri = intent.getData();
51             if (uri != null) {
52                 if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) {
53                     mUri = uri;
54                 }
55             }
56         }
57     }
58 
59     /**
60      * Sets the Intent associated with the content, describing the current top-level context of
61      * the activity.  If this contains a reference to a piece of data related to the activity,
62      * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility
63      * service can access it.
64      */
setIntent(Intent intent)65     public void setIntent(Intent intent) {
66         mIsAppProvidedIntent = true;
67         mIntent = intent;
68     }
69 
70     /**
71      * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from
72      * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place.
73      */
getIntent()74     public Intent getIntent() {
75         return mIntent;
76     }
77 
78     /**
79      * Returns whether or not the current Intent was explicitly provided in
80      * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
81      * the Intent was automatically set based on
82      * {@link android.app.Activity#getIntent Activity.getIntent}.
83      */
isAppProvidedIntent()84     public boolean isAppProvidedIntent() {
85         return mIsAppProvidedIntent;
86     }
87 
88     /**
89      * Optional additional content items that are involved with
90      * the current UI.  Access to this content will be granted to the assistant as if you
91      * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}.
92      */
setClipData(ClipData clip)93     public void setClipData(ClipData clip) {
94         mClipData = clip;
95     }
96 
97     /**
98      * Return the current {@link #setClipData}, which you can modify in-place.
99      */
getClipData()100     public ClipData getClipData() {
101         return mClipData;
102     }
103 
104     /**
105      * Sets optional structured data regarding the content being viewed. The provided data
106      * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the
107      * <a href="http://schema.org/">schema.org</a> vocabulary.
108      */
setStructuredData(String structuredData)109     public void setStructuredData(String structuredData) {
110         mStructuredData = structuredData;
111     }
112 
113     /**
114      * Returns the current {@link #setStructuredData}.
115      */
getStructuredData()116     public String getStructuredData() {
117         return mStructuredData;
118     }
119 
120     /**
121      * Set a web URI associated with the current data being shown to the user.
122      * This URI could be opened in a web browser, or in the app as an
123      * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently
124      * being displayed by it.  The URI here should be something that is transportable
125      * off the device into other environments to acesss the same data as is currently
126      * being shown in the app; if the app does not have such a representation, it should
127      * leave the null and only report the local intent and clip data.
128      */
setWebUri(Uri uri)129     public void setWebUri(Uri uri) {
130         mIsAppProvidedWebUri = true;
131         mUri = uri;
132     }
133 
134     /**
135      * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if
136      * there is none.
137      */
getWebUri()138     public Uri getWebUri() {
139         return mUri;
140     }
141 
142     /**
143      * Returns whether or not the current {@link #getWebUri} was explicitly provided in
144      * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not,
145      * the Intent was automatically set based on
146      * {@link android.app.Activity#getIntent Activity.getIntent}.
147      */
isAppProvidedWebUri()148     public boolean isAppProvidedWebUri() {
149         return mIsAppProvidedWebUri;
150     }
151 
152     /**
153      * Return Bundle for extra vendor-specific data that can be modified and examined.
154      */
getExtras()155     public Bundle getExtras() {
156         return mExtras;
157     }
158 
159     @UnsupportedAppUsage
AssistContent(Parcel in)160     AssistContent(Parcel in) {
161         if (in.readInt() != 0) {
162             mIntent = Intent.CREATOR.createFromParcel(in);
163         }
164         if (in.readInt() != 0) {
165             mClipData = ClipData.CREATOR.createFromParcel(in);
166         }
167         if (in.readInt() != 0) {
168             mUri = Uri.CREATOR.createFromParcel(in);
169         }
170         if (in.readInt() != 0) {
171             mStructuredData = in.readString();
172         }
173         mIsAppProvidedIntent = in.readInt() == 1;
174         mExtras = in.readBundle();
175         mIsAppProvidedWebUri = in.readInt() == 1;
176     }
177 
178     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
writeToParcelInternal(Parcel dest, int flags)179     void writeToParcelInternal(Parcel dest, int flags) {
180         if (mIntent != null) {
181             dest.writeInt(1);
182             mIntent.writeToParcel(dest, flags);
183         } else {
184             dest.writeInt(0);
185         }
186         if (mClipData != null) {
187             dest.writeInt(1);
188             mClipData.writeToParcel(dest, flags);
189         } else {
190             dest.writeInt(0);
191         }
192         if (mUri != null) {
193             dest.writeInt(1);
194             mUri.writeToParcel(dest, flags);
195         } else {
196             dest.writeInt(0);
197         }
198         if (mStructuredData != null) {
199             dest.writeInt(1);
200             dest.writeString(mStructuredData);
201         } else {
202             dest.writeInt(0);
203         }
204         dest.writeInt(mIsAppProvidedIntent ? 1 : 0);
205         dest.writeBundle(mExtras);
206         dest.writeInt(mIsAppProvidedWebUri ? 1 : 0);
207     }
208 
209     @Override
describeContents()210     public int describeContents() {
211         return 0;
212     }
213 
214     @Override
writeToParcel(Parcel dest, int flags)215     public void writeToParcel(Parcel dest, int flags) {
216         writeToParcelInternal(dest, flags);
217     }
218 
219     public static final @android.annotation.NonNull Parcelable.Creator<AssistContent> CREATOR
220             = new Parcelable.Creator<AssistContent>() {
221         public AssistContent createFromParcel(Parcel in) {
222             return new AssistContent(in);
223         }
224 
225         public AssistContent[] newArray(int size) {
226             return new AssistContent[size];
227         }
228     };
229 }
230