OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / core / java / android / view / inputmethod / InputContentInfo.java
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
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
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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
14  * the License.
15  */
16
17 package android.view.inputmethod;
18
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;
26
27 import com.android.internal.inputmethod.IInputContentUriToken;
28
29 import java.security.InvalidParameterException;
30
31 /**
32  * A container object with which input methods can send content files to the target application.
33  */
34 public final class InputContentInfo implements Parcelable {
35
36     @NonNull
37     private final Uri mContentUri;
38     @NonNull
39     private final ClipDescription mDescription;
40     @Nullable
41     private final Uri mLinkUri;
42     @NonNull
43     private IInputContentUriToken mUriToken;
44
45     /**
46      * Constructs {@link InputContentInfo} object only with mandatory data.
47      *
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.
54      */
55     public InputContentInfo(@NonNull Uri contentUri, @NonNull ClipDescription description) {
56         this(contentUri, description, null /* link Uri */);
57     }
58
59     /**
60      * Constructs {@link InputContentInfo} object with additional link URI.
61      *
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.
71      */
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;
77         mLinkUri = linkUri;
78     }
79
80     /**
81      * @return {@code true} if all the fields are valid.
82      * @hide
83      */
84     public boolean validate() {
85         return validateInternal(mContentUri, mDescription, mLinkUri, false /* throwException */);
86     }
87
88     /**
89      * Constructs {@link InputContentInfo} object with additional link URI.
90      *
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.
102      */
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");
108             }
109             return false;
110         }
111         if (description == null) {
112             if (throwException) {
113                 throw new NullPointerException("description");
114             }
115             return false;
116         }
117         final String contentUriScheme = contentUri.getScheme();
118         if (!"content".equals(contentUriScheme)) {
119             if (throwException) {
120                 throw new InvalidParameterException("contentUri must have content scheme");
121             }
122             return false;
123         }
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");
131                 }
132                 return false;
133             }
134         }
135         return true;
136     }
137
138     /**
139      * @return Content URI with which the content can be obtained.
140      */
141     @NonNull
142     public Uri getContentUri() { return mContentUri; }
143
144     /**
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
147      * purpose.
148      */
149     @NonNull
150     public ClipDescription getDescription() { return mDescription; }
151
152     /**
153      * @return An optional {@code http} or {@code https} URI that is related to this content.
154      */
155     @Nullable
156     public Uri getLinkUri() { return mLinkUri; }
157
158     void setUriToken(IInputContentUriToken token) {
159         if (mUriToken != null) {
160             throw new IllegalStateException("URI token is already set");
161         }
162         mUriToken = token;
163     }
164
165     /**
166      * Requests a temporary read-only access permission for content URI associated with this object.
167      *
168      * <p>Does nothing if the temporary permission is already granted.</p>
169      */
170     public void requestPermission() {
171         if (mUriToken == null) {
172             return;
173         }
174         try {
175             mUriToken.take();
176         } catch (RemoteException e) {
177             e.rethrowFromSystemServer();
178         }
179     }
180
181     /**
182      * Releases a temporary read-only access permission for content URI associated with this object.
183      *
184      * <p>Does nothing if the temporary permission is not granted.</p>
185      */
186     public void releasePermission() {
187         if (mUriToken == null) {
188             return;
189         }
190         try {
191             mUriToken.release();
192         } catch (RemoteException e) {
193             e.rethrowFromSystemServer();
194         }
195     }
196
197     /**
198      * Used to package this object into a {@link Parcel}.
199      *
200      * @param dest The {@link Parcel} to be written.
201      * @param flags The flags used for parceling.
202      */
203     @Override
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) {
209             dest.writeInt(1);
210             dest.writeStrongBinder(mUriToken.asBinder());
211         } else {
212             dest.writeInt(0);
213         }
214     }
215
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());
222         } else {
223             mUriToken = null;
224         }
225     }
226
227     /**
228      * Used to make this class parcelable.
229      */
230     public static final Parcelable.Creator<InputContentInfo> CREATOR
231             = new Parcelable.Creator<InputContentInfo>() {
232         @Override
233         public InputContentInfo createFromParcel(Parcel source) {
234             return new InputContentInfo(source);
235         }
236
237         @Override
238         public InputContentInfo[] newArray(int size) {
239             return new InputContentInfo[size];
240         }
241     };
242
243     /**
244      * {@inheritDoc}
245      */
246     @Override
247     public int describeContents() {
248         return 0;
249     }
250 }