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