2 * Copyright (C) 2016 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
17 package android.view.inputmethod;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.ClipDescription;
22 import android.net.Uri;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.os.RemoteException;
27 import com.android.internal.inputmethod.IInputContentUriToken;
29 import java.security.InvalidParameterException;
32 * A container object with which input methods can send content files to the target application.
34 public final class InputContentInfo implements Parcelable {
37 private final Uri mContentUri;
39 private final ClipDescription mDescription;
41 private final Uri mLinkUri;
43 private IInputContentUriToken mUriToken;
46 * Constructs {@link InputContentInfo} object only with mandatory data.
48 * @param contentUri Content URI to be exported from the input method.
49 * This cannot be {@code null}.
50 * @param description A {@link ClipDescription} object that contains the metadata of
51 * {@code contentUri} such as MIME type(s). This object cannot be {@code null}. Also
52 * {@link ClipDescription#getLabel()} should be describing the content specified by
53 * {@code contentUri} for accessibility reasons.
55 public InputContentInfo(@NonNull Uri contentUri, @NonNull ClipDescription description) {
56 this(contentUri, description, null /* link Uri */);
60 * Constructs {@link InputContentInfo} object with additional link URI.
62 * @param contentUri Content URI to be exported from the input method.
63 * This cannot be {@code null}.
64 * @param description A {@link ClipDescription} object that contains the metadata of
65 * {@code contentUri} such as MIME type(s). This object cannot be {@code null}. Also
66 * {@link ClipDescription#getLabel()} should be describing the content specified by
67 * {@code contentUri} for accessibility reasons.
68 * @param linkUri An optional {@code http} or {@code https} URI. The editor author may provide
69 * a way to navigate the user to the specified web page if this is not {@code null}.
70 * @throws InvalidParameterException if any invalid parameter is specified.
72 public InputContentInfo(@NonNull Uri contentUri, @NonNull ClipDescription description,
73 @Nullable Uri linkUri) {
74 validateInternal(contentUri, description, linkUri, true /* throwException */);
75 mContentUri = contentUri;
76 mDescription = description;
81 * @return {@code true} if all the fields are valid.
84 public boolean validate() {
85 return validateInternal(mContentUri, mDescription, mLinkUri, false /* throwException */);
89 * Constructs {@link InputContentInfo} object with additional link URI.
91 * @param contentUri Content URI to be exported from the input method.
92 * This cannot be {@code null}.
93 * @param description A {@link ClipDescription} object that contains the metadata of
94 * {@code contentUri} such as MIME type(s). This object cannot be {@code null}. Also
95 * {@link ClipDescription#getLabel()} should be describing the content specified by
96 * {@code contentUri} for accessibility reasons.
97 * @param linkUri An optional {@code http} or {@code https} URI. The editor author may provide
98 * a way to navigate the user to the specified web page if this is not {@code null}.
99 * @param throwException {@code true} if this method should throw an
100 * {@link InvalidParameterException}.
101 * @throws InvalidParameterException if any invalid parameter is specified.
103 private static boolean validateInternal(@NonNull Uri contentUri,
104 @NonNull ClipDescription description, @Nullable Uri linkUri, boolean throwException) {
105 if (contentUri == null) {
106 if (throwException) {
107 throw new NullPointerException("contentUri");
111 if (description == null) {
112 if (throwException) {
113 throw new NullPointerException("description");
117 final String contentUriScheme = contentUri.getScheme();
118 if (!"content".equals(contentUriScheme)) {
119 if (throwException) {
120 throw new InvalidParameterException("contentUri must have content scheme");
124 if (linkUri != null) {
125 final String scheme = linkUri.getScheme();
126 if (scheme == null ||
127 (!scheme.equalsIgnoreCase("http") && !scheme.equalsIgnoreCase("https"))) {
128 if (throwException) {
129 throw new InvalidParameterException(
130 "linkUri must have either http or https scheme");
139 * @return Content URI with which the content can be obtained.
142 public Uri getContentUri() { return mContentUri; }
145 * @return {@link ClipDescription} object that contains the metadata of {@code #getContentUri()}
146 * such as MIME type(s). {@link ClipDescription#getLabel()} can be used for accessibility
150 public ClipDescription getDescription() { return mDescription; }
153 * @return An optional {@code http} or {@code https} URI that is related to this content.
156 public Uri getLinkUri() { return mLinkUri; }
158 void setUriToken(IInputContentUriToken token) {
159 if (mUriToken != null) {
160 throw new IllegalStateException("URI token is already set");
166 * Requests a temporary read-only access permission for content URI associated with this object.
168 * <p>Does nothing if the temporary permission is already granted.</p>
170 public void requestPermission() {
171 if (mUriToken == null) {
176 } catch (RemoteException e) {
177 e.rethrowFromSystemServer();
182 * Releases a temporary read-only access permission for content URI associated with this object.
184 * <p>Does nothing if the temporary permission is not granted.</p>
186 public void releasePermission() {
187 if (mUriToken == null) {
192 } catch (RemoteException e) {
193 e.rethrowFromSystemServer();
198 * Used to package this object into a {@link Parcel}.
200 * @param dest The {@link Parcel} to be written.
201 * @param flags The flags used for parceling.
204 public void writeToParcel(Parcel dest, int flags) {
205 Uri.writeToParcel(dest, mContentUri);
206 mDescription.writeToParcel(dest, flags);
207 Uri.writeToParcel(dest, mLinkUri);
208 if (mUriToken != null) {
210 dest.writeStrongBinder(mUriToken.asBinder());
216 private InputContentInfo(@NonNull Parcel source) {
217 mContentUri = Uri.CREATOR.createFromParcel(source);
218 mDescription = ClipDescription.CREATOR.createFromParcel(source);
219 mLinkUri = Uri.CREATOR.createFromParcel(source);
220 if (source.readInt() == 1) {
221 mUriToken = IInputContentUriToken.Stub.asInterface(source.readStrongBinder());
228 * Used to make this class parcelable.
230 public static final Parcelable.Creator<InputContentInfo> CREATOR
231 = new Parcelable.Creator<InputContentInfo>() {
233 public InputContentInfo createFromParcel(Parcel source) {
234 return new InputContentInfo(source);
238 public InputContentInfo[] newArray(int size) {
239 return new InputContentInfo[size];
247 public int describeContents() {