Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2017 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 | |
| 17 | package androidx.app.slice; |
| 18 | |
| 19 | import static android.app.slice.Slice.HINT_ACTIONS; |
| 20 | import static android.app.slice.Slice.HINT_HORIZONTAL; |
| 21 | import static android.app.slice.Slice.HINT_LARGE; |
| 22 | import static android.app.slice.Slice.HINT_LIST; |
| 23 | import static android.app.slice.Slice.HINT_LIST_ITEM; |
| 24 | import static android.app.slice.Slice.HINT_NO_TINT; |
| 25 | import static android.app.slice.Slice.HINT_PARTIAL; |
| 26 | import static android.app.slice.Slice.HINT_SELECTED; |
| 27 | import static android.app.slice.Slice.HINT_TITLE; |
| 28 | import static android.app.slice.SliceItem.FORMAT_ACTION; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 29 | import static android.app.slice.SliceItem.FORMAT_IMAGE; |
Jason Monk | 98ae4f8 | 2017-12-18 11:29:07 -0500 | [diff] [blame] | 30 | import static android.app.slice.SliceItem.FORMAT_INT; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 31 | import static android.app.slice.SliceItem.FORMAT_REMOTE_INPUT; |
| 32 | import static android.app.slice.SliceItem.FORMAT_SLICE; |
| 33 | import static android.app.slice.SliceItem.FORMAT_TEXT; |
| 34 | import static android.app.slice.SliceItem.FORMAT_TIMESTAMP; |
| 35 | |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 36 | import static androidx.app.slice.SliceConvert.unwrap; |
| 37 | |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 38 | import android.annotation.TargetApi; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 39 | import android.app.PendingIntent; |
| 40 | import android.app.RemoteInput; |
| 41 | import android.content.ContentProvider; |
| 42 | import android.content.Context; |
| 43 | import android.content.Intent; |
| 44 | import android.graphics.drawable.Icon; |
| 45 | import android.net.Uri; |
| 46 | import android.os.Bundle; |
| 47 | import android.os.Parcelable; |
| 48 | import android.support.annotation.NonNull; |
| 49 | import android.support.annotation.Nullable; |
| 50 | import android.support.annotation.RestrictTo; |
| 51 | import android.support.annotation.RestrictTo.Scope; |
| 52 | import android.support.annotation.StringDef; |
| 53 | import android.support.v4.os.BuildCompat; |
| 54 | |
| 55 | import java.util.ArrayList; |
| 56 | import java.util.Arrays; |
| 57 | import java.util.List; |
| 58 | |
| 59 | import androidx.app.slice.compat.SliceProviderCompat; |
| 60 | import androidx.app.slice.core.SliceHints; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 61 | |
| 62 | /** |
| 63 | * A slice is a piece of app content and actions that can be surfaced outside of the app. |
| 64 | * |
Jason Monk | 0dd353b | 2017-12-18 11:32:04 -0500 | [diff] [blame] | 65 | * <p>They are constructed using {@link androidx.app.slice.builders.TemplateSliceBuilder}s |
| 66 | * in a tree structure that provides the OS some information about how the content should be |
| 67 | * displayed. |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 68 | */ |
| 69 | public final class Slice { |
| 70 | |
| 71 | private static final String HINTS = "hints"; |
| 72 | private static final String ITEMS = "items"; |
| 73 | private static final String URI = "uri"; |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 74 | private static final String SPEC_TYPE = "type"; |
| 75 | private static final String SPEC_REVISION = "revision"; |
| 76 | private final SliceSpec mSpec; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 77 | |
| 78 | /** |
| 79 | * @hide |
| 80 | */ |
| 81 | @RestrictTo(Scope.LIBRARY) |
| 82 | @StringDef({HINT_TITLE, HINT_LIST, HINT_LIST_ITEM, HINT_LARGE, HINT_ACTIONS, HINT_SELECTED, |
| 83 | HINT_HORIZONTAL, HINT_NO_TINT, HINT_PARTIAL, |
Mady Mellor | 71ef84d | 2017-12-11 13:33:36 -0800 | [diff] [blame] | 84 | SliceHints.HINT_SUMMARY, SliceHints.SUBTYPE_TOGGLE}) |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 85 | public @interface SliceHint{ } |
| 86 | |
| 87 | private final SliceItem[] mItems; |
| 88 | private final @SliceHint String[] mHints; |
| 89 | private Uri mUri; |
| 90 | |
| 91 | /** |
| 92 | * @hide |
| 93 | */ |
| 94 | @RestrictTo(Scope.LIBRARY) |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 95 | Slice(ArrayList<SliceItem> items, @SliceHint String[] hints, Uri uri, |
| 96 | SliceSpec spec) { |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 97 | mHints = hints; |
| 98 | mItems = items.toArray(new SliceItem[items.size()]); |
| 99 | mUri = uri; |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 100 | mSpec = spec; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | /** |
| 104 | * @hide |
| 105 | */ |
| 106 | @RestrictTo(Scope.LIBRARY) |
| 107 | public Slice(Bundle in) { |
| 108 | mHints = in.getStringArray(HINTS); |
| 109 | Parcelable[] items = in.getParcelableArray(ITEMS); |
| 110 | mItems = new SliceItem[items.length]; |
| 111 | for (int i = 0; i < mItems.length; i++) { |
| 112 | if (items[i] instanceof Bundle) { |
| 113 | mItems[i] = new SliceItem((Bundle) items[i]); |
| 114 | } |
| 115 | } |
| 116 | mUri = in.getParcelable(URI); |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 117 | mSpec = in.containsKey(SPEC_TYPE) |
| 118 | ? new SliceSpec(in.getString(SPEC_TYPE), in.getInt(SPEC_REVISION)) |
| 119 | : null; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | /** |
| 123 | * @hide |
| 124 | */ |
| 125 | @RestrictTo(Scope.LIBRARY) |
| 126 | public Bundle toBundle() { |
| 127 | Bundle b = new Bundle(); |
| 128 | b.putStringArray(HINTS, mHints); |
| 129 | Parcelable[] p = new Parcelable[mItems.length]; |
| 130 | for (int i = 0; i < mItems.length; i++) { |
| 131 | p[i] = mItems[i].toBundle(); |
| 132 | } |
| 133 | b.putParcelableArray(ITEMS, p); |
| 134 | b.putParcelable(URI, mUri); |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 135 | if (mSpec != null) { |
| 136 | b.putString(SPEC_TYPE, mSpec.getType()); |
| 137 | b.putInt(SPEC_REVISION, mSpec.getRevision()); |
| 138 | } |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 139 | return b; |
| 140 | } |
| 141 | |
| 142 | /** |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 143 | * @return The spec for this slice |
| 144 | * @hide |
| 145 | */ |
| 146 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| 147 | public @Nullable SliceSpec getSpec() { |
| 148 | return mSpec; |
| 149 | } |
| 150 | |
| 151 | /** |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 152 | * @return The Uri that this Slice represents. |
| 153 | */ |
| 154 | public Uri getUri() { |
| 155 | return mUri; |
| 156 | } |
| 157 | |
| 158 | /** |
| 159 | * @return All child {@link SliceItem}s that this Slice contains. |
| 160 | */ |
| 161 | public List<SliceItem> getItems() { |
| 162 | return Arrays.asList(mItems); |
| 163 | } |
| 164 | |
| 165 | /** |
| 166 | * @return All hints associated with this Slice. |
| 167 | */ |
| 168 | public @SliceHint List<String> getHints() { |
| 169 | return Arrays.asList(mHints); |
| 170 | } |
| 171 | |
| 172 | /** |
| 173 | * @hide |
| 174 | */ |
| 175 | @RestrictTo(Scope.LIBRARY_GROUP) |
| 176 | public boolean hasHint(@SliceHint String hint) { |
| 177 | return ArrayUtils.contains(mHints, hint); |
| 178 | } |
| 179 | |
| 180 | /** |
| 181 | * A Builder used to construct {@link Slice}s |
Jason Monk | 0dd353b | 2017-12-18 11:32:04 -0500 | [diff] [blame] | 182 | * @hide |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 183 | */ |
Jason Monk | 0dd353b | 2017-12-18 11:32:04 -0500 | [diff] [blame] | 184 | @RestrictTo(Scope.LIBRARY_GROUP) |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 185 | public static class Builder { |
| 186 | |
| 187 | private final Uri mUri; |
| 188 | private ArrayList<SliceItem> mItems = new ArrayList<>(); |
| 189 | private @SliceHint ArrayList<String> mHints = new ArrayList<>(); |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 190 | private SliceSpec mSpec; |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 191 | |
| 192 | /** |
| 193 | * Create a builder which will construct a {@link Slice} for the Given Uri. |
| 194 | * @param uri Uri to tag for this slice. |
| 195 | */ |
| 196 | public Builder(@NonNull Uri uri) { |
| 197 | mUri = uri; |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * Create a builder for a {@link Slice} that is a sub-slice of the slice |
| 202 | * being constructed by the provided builder. |
| 203 | * @param parent The builder constructing the parent slice |
| 204 | */ |
| 205 | public Builder(@NonNull Slice.Builder parent) { |
| 206 | mUri = parent.mUri.buildUpon().appendPath("_gen") |
| 207 | .appendPath(String.valueOf(mItems.size())).build(); |
| 208 | } |
| 209 | |
| 210 | /** |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 211 | * Add the spec for this slice. |
| 212 | * @hide |
| 213 | */ |
| 214 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
| 215 | public Builder setSpec(SliceSpec spec) { |
| 216 | mSpec = spec; |
| 217 | return this; |
| 218 | } |
| 219 | |
| 220 | /** |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 221 | * Add hints to the Slice being constructed |
| 222 | */ |
| 223 | public Builder addHints(@SliceHint String... hints) { |
| 224 | mHints.addAll(Arrays.asList(hints)); |
| 225 | return this; |
| 226 | } |
| 227 | |
| 228 | /** |
| 229 | * Add hints to the Slice being constructed |
| 230 | */ |
| 231 | public Builder addHints(@SliceHint List<String> hints) { |
| 232 | return addHints(hints.toArray(new String[hints.size()])); |
| 233 | } |
| 234 | |
| 235 | /** |
| 236 | * Add a sub-slice to the slice being constructed |
| 237 | */ |
| 238 | public Builder addSubSlice(@NonNull Slice slice) { |
| 239 | return addSubSlice(slice, null); |
| 240 | } |
| 241 | |
| 242 | /** |
| 243 | * Add a sub-slice to the slice being constructed |
| 244 | * @param subType Optional template-specific type information |
| 245 | * @see {@link SliceItem#getSubType()} |
| 246 | */ |
| 247 | public Builder addSubSlice(@NonNull Slice slice, String subType) { |
| 248 | mItems.add(new SliceItem(slice, FORMAT_SLICE, subType, slice.getHints().toArray( |
| 249 | new String[slice.getHints().size()]))); |
| 250 | return this; |
| 251 | } |
| 252 | |
| 253 | /** |
| 254 | * Add an action to the slice being constructed |
| 255 | * @param subType Optional template-specific type information |
| 256 | * @see {@link SliceItem#getSubType()} |
| 257 | */ |
| 258 | public Slice.Builder addAction(@NonNull PendingIntent action, |
| 259 | @NonNull Slice s, @Nullable String subType) { |
| 260 | mItems.add(new SliceItem(action, s, FORMAT_ACTION, subType, new String[0])); |
| 261 | return this; |
| 262 | } |
| 263 | |
| 264 | /** |
| 265 | * Add text to the slice being constructed |
| 266 | * @param subType Optional template-specific type information |
| 267 | * @see {@link SliceItem#getSubType()} |
| 268 | */ |
| 269 | public Builder addText(CharSequence text, @Nullable String subType, |
| 270 | @SliceHint String... hints) { |
| 271 | mItems.add(new SliceItem(text, FORMAT_TEXT, subType, hints)); |
| 272 | return this; |
| 273 | } |
| 274 | |
| 275 | /** |
| 276 | * Add text to the slice being constructed |
| 277 | * @param subType Optional template-specific type information |
| 278 | * @see {@link SliceItem#getSubType()} |
| 279 | */ |
| 280 | public Builder addText(CharSequence text, @Nullable String subType, |
| 281 | @SliceHint List<String> hints) { |
| 282 | return addText(text, subType, hints.toArray(new String[hints.size()])); |
| 283 | } |
| 284 | |
| 285 | /** |
| 286 | * Add an image to the slice being constructed |
| 287 | * @param subType Optional template-specific type information |
| 288 | * @see {@link SliceItem#getSubType()} |
| 289 | */ |
| 290 | public Builder addIcon(Icon icon, @Nullable String subType, |
| 291 | @SliceHint String... hints) { |
| 292 | mItems.add(new SliceItem(icon, FORMAT_IMAGE, subType, hints)); |
| 293 | return this; |
| 294 | } |
| 295 | |
| 296 | /** |
| 297 | * Add an image to the slice being constructed |
| 298 | * @param subType Optional template-specific type information |
| 299 | * @see {@link SliceItem#getSubType()} |
| 300 | */ |
| 301 | public Builder addIcon(Icon icon, @Nullable String subType, |
| 302 | @SliceHint List<String> hints) { |
| 303 | return addIcon(icon, subType, hints.toArray(new String[hints.size()])); |
| 304 | } |
| 305 | |
| 306 | /** |
| 307 | * Add remote input to the slice being constructed |
| 308 | * @param subType Optional template-specific type information |
| 309 | * @see {@link SliceItem#getSubType()} |
Mady Mellor | c779101 | 2018-01-16 17:25:01 -0800 | [diff] [blame] | 310 | * @hide |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 311 | */ |
Mady Mellor | c779101 | 2018-01-16 17:25:01 -0800 | [diff] [blame] | 312 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 313 | public Slice.Builder addRemoteInput(RemoteInput remoteInput, @Nullable String subType, |
| 314 | @SliceHint List<String> hints) { |
| 315 | return addRemoteInput(remoteInput, subType, hints.toArray(new String[hints.size()])); |
| 316 | } |
| 317 | |
| 318 | /** |
| 319 | * Add remote input to the slice being constructed |
| 320 | * @param subType Optional template-specific type information |
| 321 | * @see {@link SliceItem#getSubType()} |
Mady Mellor | c779101 | 2018-01-16 17:25:01 -0800 | [diff] [blame] | 322 | * @hide |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 323 | */ |
Mady Mellor | c779101 | 2018-01-16 17:25:01 -0800 | [diff] [blame] | 324 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 325 | public Slice.Builder addRemoteInput(RemoteInput remoteInput, @Nullable String subType, |
| 326 | @SliceHint String... hints) { |
| 327 | mItems.add(new SliceItem(remoteInput, FORMAT_REMOTE_INPUT, subType, hints)); |
| 328 | return this; |
| 329 | } |
| 330 | |
| 331 | /** |
Jason Monk | 98ae4f8 | 2017-12-18 11:29:07 -0500 | [diff] [blame] | 332 | * Add a int to the slice being constructed |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 333 | * @param subType Optional template-specific type information |
| 334 | * @see {@link SliceItem#getSubType()} |
| 335 | */ |
Jason Monk | 98ae4f8 | 2017-12-18 11:29:07 -0500 | [diff] [blame] | 336 | public Builder addInt(int value, @Nullable String subType, |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 337 | @SliceHint String... hints) { |
Jason Monk | 98ae4f8 | 2017-12-18 11:29:07 -0500 | [diff] [blame] | 338 | mItems.add(new SliceItem(value, FORMAT_INT, subType, hints)); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 339 | return this; |
| 340 | } |
| 341 | |
| 342 | /** |
Jason Monk | 98ae4f8 | 2017-12-18 11:29:07 -0500 | [diff] [blame] | 343 | * Add a int to the slice being constructed |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 344 | * @param subType Optional template-specific type information |
| 345 | * @see {@link SliceItem#getSubType()} |
| 346 | */ |
Jason Monk | 98ae4f8 | 2017-12-18 11:29:07 -0500 | [diff] [blame] | 347 | public Builder addInt(int value, @Nullable String subType, |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 348 | @SliceHint List<String> hints) { |
Jason Monk | 98ae4f8 | 2017-12-18 11:29:07 -0500 | [diff] [blame] | 349 | return addInt(value, subType, hints.toArray(new String[hints.size()])); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 350 | } |
| 351 | |
| 352 | /** |
| 353 | * Add a timestamp to the slice being constructed |
| 354 | * @param subType Optional template-specific type information |
| 355 | * @see {@link SliceItem#getSubType()} |
| 356 | */ |
| 357 | public Slice.Builder addTimestamp(long time, @Nullable String subType, |
| 358 | @SliceHint String... hints) { |
| 359 | mItems.add(new SliceItem(time, FORMAT_TIMESTAMP, subType, hints)); |
| 360 | return this; |
| 361 | } |
| 362 | |
| 363 | /** |
| 364 | * Add a timestamp to the slice being constructed |
| 365 | * @param subType Optional template-specific type information |
| 366 | * @see {@link SliceItem#getSubType()} |
| 367 | */ |
| 368 | public Slice.Builder addTimestamp(long time, @Nullable String subType, |
| 369 | @SliceHint List<String> hints) { |
| 370 | return addTimestamp(time, subType, hints.toArray(new String[hints.size()])); |
| 371 | } |
| 372 | |
| 373 | /** |
Mady Mellor | c133418 | 2017-11-10 15:50:35 -0800 | [diff] [blame] | 374 | * Add a SliceItem to the slice being constructed. |
| 375 | * @hide |
| 376 | */ |
| 377 | @RestrictTo(Scope.LIBRARY) |
| 378 | public Slice.Builder addItem(SliceItem item) { |
| 379 | mItems.add(item); |
| 380 | return this; |
| 381 | } |
| 382 | |
| 383 | /** |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 384 | * Construct the slice. |
| 385 | */ |
| 386 | public Slice build() { |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 387 | return new Slice(mItems, mHints.toArray(new String[mHints.size()]), mUri, mSpec); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 388 | } |
| 389 | } |
| 390 | |
| 391 | /** |
| 392 | * @hide |
| 393 | * @return A string representation of this slice. |
| 394 | */ |
| 395 | @RestrictTo(Scope.LIBRARY) |
| 396 | @Override |
| 397 | public String toString() { |
| 398 | return toString(""); |
| 399 | } |
| 400 | |
Mady Mellor | 6b5cd61 | 2017-12-14 11:36:59 -0800 | [diff] [blame] | 401 | /** |
| 402 | * @hide |
| 403 | */ |
| 404 | @RestrictTo(Scope.LIBRARY) |
| 405 | public String toString(String indent) { |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 406 | StringBuilder sb = new StringBuilder(); |
| 407 | for (int i = 0; i < mItems.length; i++) { |
| 408 | sb.append(indent); |
| 409 | if (FORMAT_SLICE.equals(mItems[i].getFormat())) { |
| 410 | sb.append("slice:\n"); |
| 411 | sb.append(mItems[i].getSlice().toString(indent + " ")); |
Jason Monk | 901e2a6 | 2017-12-18 15:40:24 -0500 | [diff] [blame] | 412 | } else if (FORMAT_ACTION.equals(mItems[i].getFormat())) { |
| 413 | sb.append("action:\n"); |
| 414 | sb.append(mItems[i].getSlice().toString(indent + " ")); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 415 | } else if (FORMAT_TEXT.equals(mItems[i].getFormat())) { |
| 416 | sb.append("text: "); |
| 417 | sb.append(mItems[i].getText()); |
| 418 | sb.append("\n"); |
| 419 | } else { |
| 420 | sb.append(SliceItem.typeToString(mItems[i].getFormat())); |
| 421 | sb.append("\n"); |
| 422 | } |
| 423 | } |
| 424 | return sb.toString(); |
| 425 | } |
| 426 | |
| 427 | /** |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 428 | */ |
| 429 | public static @Nullable Slice bindSlice(Context context, @NonNull Uri uri) { |
| 430 | throw new RuntimeException("Stub, to be removed"); |
| 431 | } |
| 432 | |
| 433 | /** |
| 434 | */ |
| 435 | public static @Nullable Slice bindSlice(Context context, @NonNull Intent intent) { |
| 436 | throw new RuntimeException("Stub, to be removed"); |
| 437 | } |
| 438 | |
| 439 | /** |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 440 | * Turns a slice Uri into slice content. |
| 441 | * |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 442 | * @hide |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 443 | * @param context Context to be used. |
| 444 | * @param uri The URI to a slice provider |
| 445 | * @return The Slice provided by the app or null if none is given. |
| 446 | * @see Slice |
| 447 | */ |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 448 | @RestrictTo(Scope.LIBRARY_GROUP) |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 449 | @SuppressWarnings("NewApi") |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 450 | public static @Nullable Slice bindSlice(Context context, @NonNull Uri uri, |
| 451 | List<SliceSpec> supportedSpecs) { |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 452 | if (BuildCompat.isAtLeastP()) { |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 453 | return callBindSlice(context, uri, supportedSpecs); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 454 | } else { |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 455 | return SliceProviderCompat.bindSlice(context, uri, supportedSpecs); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 456 | } |
| 457 | } |
| 458 | |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 459 | @TargetApi(28) |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 460 | private static Slice callBindSlice(Context context, Uri uri, |
| 461 | List<SliceSpec> supportedSpecs) { |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 462 | return SliceConvert.wrap(android.app.slice.Slice.bindSlice( |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 463 | context.getContentResolver(), uri, unwrap(supportedSpecs))); |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 464 | } |
| 465 | |
| 466 | |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 467 | /** |
| 468 | * Turns a slice intent into slice content. Expects an explicit intent. If there is no |
| 469 | * {@link ContentProvider} associated with the given intent this will throw |
| 470 | * {@link IllegalArgumentException}. |
| 471 | * |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 472 | * @hide |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 473 | * @param context The context to use. |
| 474 | * @param intent The intent associated with a slice. |
| 475 | * @return The Slice provided by the app or null if none is given. |
| 476 | * @see Slice |
| 477 | * @see SliceProvider#onMapIntentToUri(Intent) |
| 478 | * @see Intent |
| 479 | */ |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 480 | @RestrictTo(Scope.LIBRARY_GROUP) |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 481 | @SuppressWarnings("NewApi") |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 482 | public static @Nullable Slice bindSlice(Context context, @NonNull Intent intent, |
| 483 | List<SliceSpec> supportedSpecs) { |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 484 | if (BuildCompat.isAtLeastP()) { |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 485 | return callBindSlice(context, intent, supportedSpecs); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 486 | } else { |
Jason Monk | a09cb67 | 2018-01-08 13:17:36 -0500 | [diff] [blame] | 487 | return SliceProviderCompat.bindSlice(context, intent, supportedSpecs); |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 488 | } |
| 489 | } |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 490 | |
| 491 | @TargetApi(28) |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 492 | private static Slice callBindSlice(Context context, Intent intent, |
| 493 | List<SliceSpec> supportedSpecs) { |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 494 | return SliceConvert.wrap(android.app.slice.Slice.bindSlice( |
Jason Monk | 6fa0c9b | 2017-12-12 20:55:35 -0500 | [diff] [blame] | 495 | context, intent, unwrap(supportedSpecs))); |
Jason Monk | 2a7d0fc | 2017-11-15 10:10:24 -0500 | [diff] [blame] | 496 | } |
Jason Monk | dcb5e2f | 2017-11-15 20:19:43 -0500 | [diff] [blame] | 497 | } |