1/** 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v13.view.inputmethod; 18 19import android.content.ClipDescription; 20import android.net.Uri; 21import android.os.Build; 22import android.support.annotation.NonNull; 23import android.support.annotation.Nullable; 24import android.support.annotation.RequiresApi; 25import android.view.inputmethod.InputContentInfo; 26 27/** 28 * Helper for accessing features in InputContentInfo introduced after API level 13 in a backwards 29 * compatible fashion. 30 */ 31public final class InputContentInfoCompat { 32 33 private interface InputContentInfoCompatImpl { 34 @NonNull 35 Uri getContentUri(); 36 37 @NonNull 38 ClipDescription getDescription(); 39 40 @Nullable 41 Uri getLinkUri(); 42 43 @Nullable 44 Object getInputContentInfo(); 45 46 void requestPermission(); 47 48 void releasePermission(); 49 } 50 51 private static final class InputContentInfoCompatBaseImpl 52 implements InputContentInfoCompatImpl { 53 @NonNull 54 private final Uri mContentUri; 55 @NonNull 56 private final ClipDescription mDescription; 57 @Nullable 58 private final Uri mLinkUri; 59 60 InputContentInfoCompatBaseImpl(@NonNull Uri contentUri, 61 @NonNull ClipDescription description, @Nullable Uri linkUri) { 62 mContentUri = contentUri; 63 mDescription = description; 64 mLinkUri = linkUri; 65 } 66 67 @NonNull 68 @Override 69 public Uri getContentUri() { 70 return mContentUri; 71 } 72 73 @NonNull 74 @Override 75 public ClipDescription getDescription() { 76 return mDescription; 77 } 78 79 @Nullable 80 @Override 81 public Uri getLinkUri() { 82 return mLinkUri; 83 } 84 85 @Nullable 86 @Override 87 public Object getInputContentInfo() { 88 return null; 89 } 90 91 @Override 92 public void requestPermission() { 93 return; 94 } 95 96 @Override 97 public void releasePermission() { 98 return; 99 } 100 } 101 102 @RequiresApi(25) 103 private static final class InputContentInfoCompatApi25Impl 104 implements InputContentInfoCompatImpl { 105 @NonNull 106 final InputContentInfo mObject; 107 108 InputContentInfoCompatApi25Impl(@NonNull Object inputContentInfo) { 109 mObject = (InputContentInfo) inputContentInfo; 110 } 111 112 InputContentInfoCompatApi25Impl(@NonNull Uri contentUri, 113 @NonNull ClipDescription description, @Nullable Uri linkUri) { 114 mObject = new InputContentInfo(contentUri, description, linkUri); 115 } 116 117 @Override 118 @NonNull 119 public Uri getContentUri() { 120 return mObject.getContentUri(); 121 } 122 123 @Override 124 @NonNull 125 public ClipDescription getDescription() { 126 return mObject.getDescription(); 127 } 128 129 @Override 130 @Nullable 131 public Uri getLinkUri() { 132 return mObject.getLinkUri(); 133 } 134 135 @Override 136 @Nullable 137 public Object getInputContentInfo() { 138 return mObject; 139 } 140 141 @Override 142 public void requestPermission() { 143 mObject.requestPermission(); 144 } 145 146 @Override 147 public void releasePermission() { 148 mObject.releasePermission(); 149 } 150 } 151 152 private final InputContentInfoCompatImpl mImpl; 153 154 /** 155 * Constructs {@link InputContentInfoCompat}. 156 * 157 * @param contentUri content URI to be exported from the input method. This cannot be 158 * {@code null}. 159 * @param description a {@link ClipDescription} object that contains the metadata of 160 * {@code contentUri} such as MIME type(s). This object cannot be 161 * {@code null}. Also {@link ClipDescription#getLabel()} should be describing 162 * the content specified by {@code contentUri} for accessibility reasons. 163 * @param linkUri an optional {@code http} or {@code https} URI. The editor author may provide 164 * a way to navigate the user to the specified web page if this is not 165 * {@code null}. 166 */ 167 public InputContentInfoCompat(@NonNull Uri contentUri, 168 @NonNull ClipDescription description, @Nullable Uri linkUri) { 169 if (Build.VERSION.SDK_INT >= 25) { 170 mImpl = new InputContentInfoCompatApi25Impl(contentUri, description, linkUri); 171 } else { 172 mImpl = new InputContentInfoCompatBaseImpl(contentUri, description, linkUri); 173 } 174 } 175 176 private InputContentInfoCompat(@NonNull InputContentInfoCompatImpl impl) { 177 mImpl = impl; 178 } 179 180 /** 181 * @return content URI with which the content can be obtained. 182 */ 183 @NonNull 184 public Uri getContentUri() { 185 return mImpl.getContentUri(); 186 } 187 188 /** 189 * @return {@link ClipDescription} object that contains the metadata of {@code #getContentUri()} 190 * such as MIME type(s). {@link ClipDescription#getLabel()} can be used for accessibility 191 * purpose. 192 */ 193 @NonNull 194 public ClipDescription getDescription() { 195 return mImpl.getDescription(); 196 } 197 198 /** 199 * @return an optional {@code http} or {@code https} URI that is related to this content. 200 */ 201 @Nullable 202 public Uri getLinkUri() { 203 return mImpl.getLinkUri(); 204 } 205 206 /** 207 * Creates an instance from a framework android.view.inputmethod.InputContentInfo object. 208 * 209 * <p>This method always returns {@code null} on API <= 24.</p> 210 * 211 * @param inputContentInfo an android.view.inputmethod.InputContentInfo object, or {@code null} 212 * if none. 213 * @return an equivalent {@link InputContentInfoCompat} object, or {@code null} if not 214 * supported. 215 */ 216 @Nullable 217 public static InputContentInfoCompat wrap(@Nullable Object inputContentInfo) { 218 if (inputContentInfo == null) { 219 return null; 220 } 221 if (Build.VERSION.SDK_INT < 25) { 222 return null; 223 } 224 return new InputContentInfoCompat(new InputContentInfoCompatApi25Impl(inputContentInfo)); 225 } 226 227 /** 228 * Gets the underlying framework android.view.inputmethod.InputContentInfo object. 229 * 230 * <p>This method always returns {@code null} on API <= 24.</p> 231 * 232 * @return an equivalent android.view.inputmethod.InputContentInfo object, or {@code null} if 233 * not supported. 234 */ 235 @Nullable 236 public Object unwrap() { 237 return mImpl.getInputContentInfo(); 238 } 239 240 /** 241 * Requests a temporary read-only access permission for content URI associated with this object. 242 * 243 * <p>Does nothing if the temporary permission is already granted.</p> 244 */ 245 public void requestPermission() { 246 mImpl.requestPermission(); 247 } 248 249 /** 250 * Releases a temporary read-only access permission for content URI associated with this object. 251 * 252 * <p>Does nothing if the temporary permission is not granted.</p> 253 */ 254 public void releasePermission() { 255 mImpl.releasePermission(); 256 } 257} 258