blob: 7408c34538ab8902e7d717e8345a54f709008fb2 [file] [log] [blame]
Makoto Onuki6f7362d92016-03-04 13:39:41 -08001/*
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 */
16package android.content.pm;
17
18import android.annotation.IntDef;
19import android.annotation.NonNull;
20import android.annotation.Nullable;
21import android.content.ComponentName;
Makoto Onuki55046222016-03-08 10:49:47 -080022import android.content.ContentResolver;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080023import android.content.Context;
24import android.content.Intent;
25import android.graphics.drawable.Icon;
Makoto Onuki55046222016-03-08 10:49:47 -080026import android.os.Bundle;
Makoto Onuki6f7362d92016-03-04 13:39:41 -080027import android.os.Parcel;
28import android.os.Parcelable;
29import android.os.PersistableBundle;
30import android.os.UserHandle;
31
32import com.android.internal.util.Preconditions;
33
34import java.lang.annotation.Retention;
35import java.lang.annotation.RetentionPolicy;
36
37/**
38 * TODO Enhance javadoc
39 *
40 * Represents a shortcut form an application.
41 *
42 * Notes...
43 * - If an {@link Icon} is of a resource, then we'll just persist the package name and resource ID.
44 *
45 * Otherwise, the bitmap will be fetched when it's registered to ShortcutManager, then *shrunk*
46 * if necessary, and persisted.
47 *
48 * We will disallow byte[] icons, because they can easily go over binder size limit.
Makoto Onuki6f7362d92016-03-04 13:39:41 -080049 */
50public class ShortcutInfo implements Parcelable {
51 /* @hide */
52 public static final int FLAG_DYNAMIC = 1 << 0;
53
54 /* @hide */
55 public static final int FLAG_PINNED = 1 << 1;
56
57 /* @hide */
58 public static final int FLAG_HAS_ICON_RES = 1 << 2;
59
60 /* @hide */
61 public static final int FLAG_HAS_ICON_FILE = 1 << 3;
62
Makoto Onuki55046222016-03-08 10:49:47 -080063 /* @hide */
64 public static final int FLAG_KEY_FIELDS_ONLY = 1 << 4;
65
Makoto Onuki6f7362d92016-03-04 13:39:41 -080066 /** @hide */
67 @IntDef(flag = true,
68 value = {
69 FLAG_DYNAMIC,
70 FLAG_PINNED,
71 FLAG_HAS_ICON_RES,
72 FLAG_HAS_ICON_FILE,
Makoto Onuki55046222016-03-08 10:49:47 -080073 FLAG_KEY_FIELDS_ONLY,
Makoto Onuki6f7362d92016-03-04 13:39:41 -080074 })
75 @Retention(RetentionPolicy.SOURCE)
76 public @interface ShortcutFlags {}
77
78 // Cloning options.
79
80 /* @hide */
81 private static final int CLONE_REMOVE_ICON = 1 << 0;
82
83 /* @hide */
84 private static final int CLONE_REMOVE_INTENT = 1 << 1;
85
86 /* @hide */
87 public static final int CLONE_REMOVE_NON_KEY_INFO = 1 << 2;
88
89 /* @hide */
90 public static final int CLONE_REMOVE_FOR_CREATOR = CLONE_REMOVE_ICON;
91
92 /* @hide */
93 public static final int CLONE_REMOVE_FOR_LAUNCHER = CLONE_REMOVE_ICON | CLONE_REMOVE_INTENT;
94
95 /** @hide */
96 @IntDef(flag = true,
97 value = {
98 CLONE_REMOVE_ICON,
99 CLONE_REMOVE_INTENT,
100 CLONE_REMOVE_NON_KEY_INFO,
101 CLONE_REMOVE_FOR_CREATOR,
102 CLONE_REMOVE_FOR_LAUNCHER
103 })
104 @Retention(RetentionPolicy.SOURCE)
105 public @interface CloneFlags {}
106
107 private final String mId;
108
109 @NonNull
110 private final String mPackageName;
111
112 @Nullable
113 private ComponentName mActivityComponent;
114
115 @Nullable
116 private Icon mIcon;
117
118 @NonNull
119 private String mTitle;
120
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700121 @Nullable
122 private String mText;
123
Makoto Onuki55046222016-03-08 10:49:47 -0800124 /**
125 * Intent *with extras removed*.
126 */
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800127 @NonNull
128 private Intent mIntent;
129
Makoto Onuki55046222016-03-08 10:49:47 -0800130 /**
131 * Extras for the intent.
132 */
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800133 @NonNull
134 private PersistableBundle mIntentPersistableExtras;
135
136 private int mWeight;
137
138 @Nullable
139 private PersistableBundle mExtras;
140
141 private long mLastChangedTimestamp;
142
143 // Internal use only.
144 @ShortcutFlags
145 private int mFlags;
146
147 // Internal use only.
148 private int mIconResourceId;
149
150 // Internal use only.
151 @Nullable
152 private String mBitmapPath;
153
154 private ShortcutInfo(Builder b) {
155 mId = Preconditions.checkStringNotEmpty(b.mId, "Shortcut ID must be provided");
156
157 // Note we can't do other null checks here because SM.updateShortcuts() takes partial
158 // information.
159 mPackageName = b.mContext.getPackageName();
160 mActivityComponent = b.mActivityComponent;
161 mIcon = b.mIcon;
162 mTitle = b.mTitle;
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700163 mText = b.mText;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800164 mIntent = b.mIntent;
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800165 if (mIntent != null) {
166 final Bundle intentExtras = mIntent.getExtras();
167 if (intentExtras != null) {
168 mIntent.replaceExtras((Bundle) null);
169 mIntentPersistableExtras = new PersistableBundle(intentExtras);
170 }
Makoto Onuki55046222016-03-08 10:49:47 -0800171 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800172 mWeight = b.mWeight;
173 mExtras = b.mExtras;
174 updateTimestamp();
175 }
176
177 /**
178 * Throws if any of the mandatory fields is not set.
179 *
180 * @hide
181 */
182 public void enforceMandatoryFields() {
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700183 Preconditions.checkStringNotEmpty(mId, "Shortcut ID must be provided");
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800184 Preconditions.checkStringNotEmpty(mTitle, "Shortcut title must be provided");
185 Preconditions.checkNotNull(mIntent, "Shortcut Intent must be provided");
186 }
187
188 /**
189 * Copy constructor.
190 */
191 private ShortcutInfo(ShortcutInfo source, @CloneFlags int cloneFlags) {
192 mId = source.mId;
193 mPackageName = source.mPackageName;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800194 mFlags = source.mFlags;
195 mLastChangedTimestamp = source.mLastChangedTimestamp;
196
197 if ((cloneFlags & CLONE_REMOVE_NON_KEY_INFO) == 0) {
Makoto Onuki55046222016-03-08 10:49:47 -0800198 mActivityComponent = source.mActivityComponent;
199
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800200 if ((cloneFlags & CLONE_REMOVE_ICON) == 0) {
201 mIcon = source.mIcon;
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800202 mBitmapPath = source.mBitmapPath;
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700203 mIconResourceId = source.mIconResourceId;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800204 }
205
206 mTitle = source.mTitle;
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700207 mText = source.mText;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800208 if ((cloneFlags & CLONE_REMOVE_INTENT) == 0) {
209 mIntent = source.mIntent;
210 mIntentPersistableExtras = source.mIntentPersistableExtras;
211 }
212 mWeight = source.mWeight;
213 mExtras = source.mExtras;
Makoto Onuki55046222016-03-08 10:49:47 -0800214 } else {
215 // Set this bit.
216 mFlags |= FLAG_KEY_FIELDS_ONLY;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800217 }
218 }
219
220 /**
221 * Copy a {@link ShortcutInfo}, optionally removing fields.
222 * @hide
223 */
224 public ShortcutInfo clone(@CloneFlags int cloneFlags) {
225 return new ShortcutInfo(this, cloneFlags);
226 }
227
228 /**
229 * Copy non-null/zero fields from another {@link ShortcutInfo}. Only "public" information
230 * will be overwritten. The timestamp will be updated.
231 *
232 * - Flags will not change
233 * - mBitmapPath will not change
234 * - Current time will be set to timestamp
235 *
236 * @hide
237 */
238 public void copyNonNullFieldsFrom(ShortcutInfo source) {
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800239 Preconditions.checkState(mId.equals(source.mId), "ID must match");
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800240 Preconditions.checkState(mPackageName.equals(source.mPackageName),
Makoto Onuki7a6a05f2016-03-10 17:01:08 -0800241 "Package name must match");
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800242
243 if (source.mActivityComponent != null) {
244 mActivityComponent = source.mActivityComponent;
245 }
246
247 if (source.mIcon != null) {
248 mIcon = source.mIcon;
249 }
250 if (source.mTitle != null) {
251 mTitle = source.mTitle;
252 }
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700253 if (source.mText != null) {
254 mText = source.mText;
255 }
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800256 if (source.mIntent != null) {
257 mIntent = source.mIntent;
258 mIntentPersistableExtras = source.mIntentPersistableExtras;
259 }
260 if (source.mWeight != 0) {
261 mWeight = source.mWeight;
262 }
263 if (source.mExtras != null) {
264 mExtras = source.mExtras;
265 }
266
267 updateTimestamp();
268 }
269
270 /**
Makoto Onuki55046222016-03-08 10:49:47 -0800271 * @hide
272 */
273 public static Icon validateIcon(Icon icon) {
274 switch (icon.getType()) {
275 case Icon.TYPE_RESOURCE:
276 case Icon.TYPE_BITMAP:
277 break; // OK
278 case Icon.TYPE_URI:
279 if (ContentResolver.SCHEME_CONTENT.equals(icon.getUri().getScheme())) {
280 break;
281 }
282 // Note "file:" is not supported, because depending on the path, system server
283 // cannot access it. // TODO Revisit "file:" icon support
284
285 // fall through
286 default:
287 throw getInvalidIconException();
288 }
289 if (icon.hasTint()) {
290 // TODO support it
291 throw new IllegalArgumentException("Icons with tints are not supported");
292 }
293
294 return icon;
295 }
296
297 /** @hide */
298 public static IllegalArgumentException getInvalidIconException() {
299 return new IllegalArgumentException("Unsupported icon type:"
300 +" only bitmap, resource and content URI are supported");
301 }
302
303 /**
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800304 * Builder class for {@link ShortcutInfo} objects.
305 */
306 public static class Builder {
307 private final Context mContext;
308
309 private String mId;
310
311 private ComponentName mActivityComponent;
312
313 private Icon mIcon;
314
315 private String mTitle;
316
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700317 private String mText;
318
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800319 private Intent mIntent;
320
321 private int mWeight;
322
323 private PersistableBundle mExtras;
324
325 /** Constructor. */
326 public Builder(Context context) {
327 mContext = context;
328 }
329
330 /**
331 * Sets the ID of the shortcut. This is a mandatory field.
332 */
333 @NonNull
334 public Builder setId(@NonNull String id) {
335 mId = Preconditions.checkStringNotEmpty(id, "id");
336 return this;
337 }
338
339 /**
Makoto Onuki55046222016-03-08 10:49:47 -0800340 * Optionally sets the target activity. If it's not set, and if the caller application
341 * has multiple launcher icons, this shortcut will be shown on all those icons.
342 * If it's set, this shortcut will be only shown on this activity.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800343 */
344 @NonNull
345 public Builder setActivityComponent(@NonNull ComponentName activityComponent) {
346 mActivityComponent = Preconditions.checkNotNull(activityComponent, "activityComponent");
347 return this;
348 }
349
350 /**
351 * Optionally sets an icon.
352 *
Makoto Onuki55046222016-03-08 10:49:47 -0800353 * <ul>
354 * <li>Tints are not supported.
355 * <li>Bitmaps, resources and "content:" URIs are supported.
356 * <li>"content:" URI will be fetched when a shortcut is registered to
357 * {@link ShortcutManager}. Changing the content from the same URI later will
358 * not be reflected to launcher icons.
359 * </ul>
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800360 *
Makoto Onuki55046222016-03-08 10:49:47 -0800361 * <p>For performance reasons, icons will <b>NOT</b> be available on instances
362 * returned by {@link ShortcutManager} or {@link LauncherApps}. Launcher applications
363 * need to use {@link LauncherApps#getShortcutIconFd(ShortcutInfo, UserHandle)}
364 * and {@link LauncherApps#getShortcutIconResId(ShortcutInfo, UserHandle)}.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800365 */
366 @NonNull
367 public Builder setIcon(Icon icon) {
Makoto Onuki55046222016-03-08 10:49:47 -0800368 mIcon = validateIcon(icon);
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800369 return this;
370 }
371
372 /**
373 * Sets the title of a shortcut. This is a mandatory field.
374 */
375 @NonNull
376 public Builder setTitle(@NonNull String title) {
377 mTitle = Preconditions.checkStringNotEmpty(title, "title");
378 return this;
379 }
380
381 /**
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700382 * Sets the text of a shortcut. This is an optional field.
383 */
384 @NonNull
385 public Builder setText(@NonNull String text) {
386 mText = Preconditions.checkStringNotEmpty(text, "text");
387 return this;
388 }
389
390 /**
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800391 * Sets the intent of a shortcut. This is a mandatory field. The extras must only contain
392 * persistable information. (See {@link PersistableBundle}).
393 */
394 @NonNull
395 public Builder setIntent(@NonNull Intent intent) {
396 mIntent = Preconditions.checkNotNull(intent, "intent");
397 return this;
398 }
399
400 /**
Makoto Onuki55046222016-03-08 10:49:47 -0800401 * Optionally sets the weight of a shortcut, which will be used by the launcher for sorting.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800402 * The larger the weight, the more "important" a shortcut is.
403 */
404 @NonNull
405 public Builder setWeight(int weight) {
406 mWeight = weight;
407 return this;
408 }
409
410 /**
Makoto Onuki55046222016-03-08 10:49:47 -0800411 * Optional values that applications can set. Applications can store any meta-data of
412 * shortcuts in this, and retrieve later from {@link ShortcutInfo#getExtras()}.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800413 */
414 @NonNull
415 public Builder setExtras(@NonNull PersistableBundle extras) {
416 mExtras = extras;
417 return this;
418 }
419
420 /**
421 * Creates a {@link ShortcutInfo} instance.
422 */
423 @NonNull
424 public ShortcutInfo build() {
425 return new ShortcutInfo(this);
426 }
427 }
428
429 /**
430 * Return the ID of the shortcut.
431 */
432 @NonNull
433 public String getId() {
434 return mId;
435 }
436
437 /**
Makoto Onuki55046222016-03-08 10:49:47 -0800438 * Return the package name of the creator application.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800439 */
440 @NonNull
441 public String getPackageName() {
442 return mPackageName;
443 }
444
445 /**
446 * Return the target activity, which may be null, in which case the shortcut is not associated
447 * with a specific activity.
448 */
449 @Nullable
450 public ComponentName getActivityComponent() {
451 return mActivityComponent;
452 }
453
454 /**
455 * Icon.
456 *
457 * For performance reasons, this will <b>NOT</b> be available when an instance is returned
458 * by {@link ShortcutManager} or {@link LauncherApps}. A launcher application needs to use
Makoto Onuki55046222016-03-08 10:49:47 -0800459 * other APIs in LauncherApps to fetch the bitmap.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800460 *
461 * @hide
462 */
463 @Nullable
464 public Icon getIcon() {
465 return mIcon;
466 }
467
468 /**
469 * Return the shortcut title.
Makoto Onuki55046222016-03-08 10:49:47 -0800470 *
471 * <p>All shortcuts must have a non-empty title, but this method will return null when
472 * {@link #hasKeyFieldsOnly()} is true.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800473 */
Makoto Onuki55046222016-03-08 10:49:47 -0800474 @Nullable
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800475 public String getTitle() {
476 return mTitle;
477 }
478
479 /**
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700480 * Return the shortcut text.
481 */
482 @Nullable
483 public String getText() {
484 return mText;
485 }
486
487 /**
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800488 * Return the intent.
Makoto Onuki55046222016-03-08 10:49:47 -0800489 *
490 * <p>All shortcuts must have an intent, but this method will return null when
491 * {@link #hasKeyFieldsOnly()} is true.
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800492 */
Makoto Onuki55046222016-03-08 10:49:47 -0800493 @Nullable
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800494 public Intent getIntent() {
Makoto Onuki55046222016-03-08 10:49:47 -0800495 if (mIntent == null) {
496 return null;
497 }
498 final Intent intent = new Intent(mIntent);
499 intent.replaceExtras(
500 mIntentPersistableExtras != null ? new Bundle(mIntentPersistableExtras) : null);
501 return intent;
502 }
503
504 /**
505 * Return "raw" intent, which is the original intent without the extras.
506 * @hide
507 */
508 @Nullable
509 public Intent getIntentNoExtras() {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800510 return mIntent;
511 }
512
Makoto Onuki55046222016-03-08 10:49:47 -0800513 /**
514 * The extras in the intent. We convert extras into {@link PersistableBundle} so we can
515 * persist them.
516 * @hide
517 */
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800518 @Nullable
519 public PersistableBundle getIntentPersistableExtras() {
520 return mIntentPersistableExtras;
521 }
522
523 /**
524 * Return the weight of a shortcut, which will be used by Launcher for sorting.
525 * The larger the weight, the more "important" a shortcut is.
526 */
527 public int getWeight() {
528 return mWeight;
529 }
530
531 /**
532 * Optional values that application can set.
533 */
534 @Nullable
535 public PersistableBundle getExtras() {
536 return mExtras;
537 }
538
539 /**
540 * Last time when any of the fields was updated.
541 */
542 public long getLastChangedTimestamp() {
543 return mLastChangedTimestamp;
544 }
545
546 /** @hide */
547 @ShortcutFlags
548 public int getFlags() {
549 return mFlags;
550 }
551
552 /** @hide*/
Makoto Onukide667372016-03-15 14:29:20 -0700553 public void replaceFlags(@ShortcutFlags int flags) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800554 mFlags = flags;
555 }
556
557 /** @hide*/
558 public void addFlags(@ShortcutFlags int flags) {
559 mFlags |= flags;
560 }
561
562 /** @hide*/
563 public void clearFlags(@ShortcutFlags int flags) {
564 mFlags &= ~flags;
565 }
566
567 /** @hide*/
568 public boolean hasFlags(@ShortcutFlags int flags) {
569 return (mFlags & flags) == flags;
570 }
571
572 /** Return whether a shortcut is dynamic. */
573 public boolean isDynamic() {
574 return hasFlags(FLAG_DYNAMIC);
575 }
576
577 /** Return whether a shortcut is pinned. */
578 public boolean isPinned() {
579 return hasFlags(FLAG_PINNED);
580 }
581
582 /**
583 * Return whether a shortcut's icon is a resource in the owning package.
584 *
585 * @see LauncherApps#getShortcutIconResId(ShortcutInfo, UserHandle)
586 */
587 public boolean hasIconResource() {
588 return hasFlags(FLAG_HAS_ICON_RES);
589 }
590
591 /**
592 * Return whether a shortcut's icon is stored as a file.
593 *
594 * @see LauncherApps#getShortcutIconFd(ShortcutInfo, UserHandle)
595 */
596 public boolean hasIconFile() {
597 return hasFlags(FLAG_HAS_ICON_FILE);
598 }
599
Makoto Onuki55046222016-03-08 10:49:47 -0800600 /**
601 * Return whether a shortcut only contains "key" information only or not. If true, only the
602 * following fields are available.
603 * <ul>
604 * <li>{@link #getId()}
605 * <li>{@link #getPackageName()}
606 * <li>{@link #getLastChangedTimestamp()}
607 * <li>{@link #isDynamic()}
608 * <li>{@link #isPinned()}
609 * <li>{@link #hasIconResource()}
610 * <li>{@link #hasIconFile()}
611 * </ul>
612 */
613 public boolean hasKeyFieldsOnly() {
614 return hasFlags(FLAG_KEY_FIELDS_ONLY);
615 }
616
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800617 /** @hide */
618 public void updateTimestamp() {
619 mLastChangedTimestamp = System.currentTimeMillis();
620 }
621
622 /** @hide */
623 // VisibleForTesting
624 public void setTimestamp(long value) {
625 mLastChangedTimestamp = value;
626 }
627
628 /** @hide */
Makoto Onuki55046222016-03-08 10:49:47 -0800629 public void clearIcon() {
630 mIcon = null;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800631 }
632
633 /** @hide */
Makoto Onuki55046222016-03-08 10:49:47 -0800634 public void setIconResourceId(int iconResourceId) {
635 mIconResourceId = iconResourceId;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800636 }
637
638 /** @hide */
639 public int getIconResourceId() {
640 return mIconResourceId;
641 }
642
643 /** @hide */
644 public String getBitmapPath() {
645 return mBitmapPath;
646 }
647
648 /** @hide */
649 public void setBitmapPath(String bitmapPath) {
650 mBitmapPath = bitmapPath;
651 }
652
653 private ShortcutInfo(Parcel source) {
654 final ClassLoader cl = getClass().getClassLoader();
655
656 mId = source.readString();
657 mPackageName = source.readString();
658 mActivityComponent = source.readParcelable(cl);
659 mIcon = source.readParcelable(cl);
660 mTitle = source.readString();
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700661 mText = source.readString();
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800662 mIntent = source.readParcelable(cl);
663 mIntentPersistableExtras = source.readParcelable(cl);
664 mWeight = source.readInt();
665 mExtras = source.readParcelable(cl);
666 mLastChangedTimestamp = source.readLong();
667 mFlags = source.readInt();
668 mIconResourceId = source.readInt();
669 mBitmapPath = source.readString();
670 }
671
672 @Override
673 public void writeToParcel(Parcel dest, int flags) {
674 dest.writeString(mId);
675 dest.writeString(mPackageName);
676 dest.writeParcelable(mActivityComponent, flags);
677 dest.writeParcelable(mIcon, flags);
678 dest.writeString(mTitle);
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700679 dest.writeString(mText);
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800680 dest.writeParcelable(mIntent, flags);
681 dest.writeParcelable(mIntentPersistableExtras, flags);
682 dest.writeInt(mWeight);
683 dest.writeParcelable(mExtras, flags);
684 dest.writeLong(mLastChangedTimestamp);
685 dest.writeInt(mFlags);
686 dest.writeInt(mIconResourceId);
687 dest.writeString(mBitmapPath);
688 }
689
690 public static final Creator<ShortcutInfo> CREATOR =
691 new Creator<ShortcutInfo>() {
692 public ShortcutInfo createFromParcel(Parcel source) {
693 return new ShortcutInfo(source);
694 }
695 public ShortcutInfo[] newArray(int size) {
696 return new ShortcutInfo[size];
697 }
698 };
699
700 @Override
701 public int describeContents() {
702 return 0;
703 }
704
705 /**
706 * Return a string representation, intended for logging. Some fields will be retracted.
707 */
708 @Override
709 public String toString() {
710 return toStringInner(/* secure =*/ true, /* includeInternalData =*/ false);
711 }
712
713 /** @hide */
714 public String toInsecureString() {
715 return toStringInner(/* secure =*/ false, /* includeInternalData =*/ true);
716 }
717
718 private String toStringInner(boolean secure, boolean includeInternalData) {
719 final StringBuilder sb = new StringBuilder();
720 sb.append("ShortcutInfo {");
721
722 sb.append("id=");
723 sb.append(secure ? "***" : mId);
724
725 sb.append(", packageName=");
726 sb.append(mPackageName);
727
728 if (isDynamic()) {
729 sb.append(", dynamic");
730 }
731 if (isPinned()) {
732 sb.append(", pinned");
733 }
734
735 sb.append(", activity=");
736 sb.append(mActivityComponent);
737
738 sb.append(", title=");
739 sb.append(secure ? "***" : mTitle);
740
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700741 sb.append(", text=");
742 sb.append(secure ? "***" : mText);
743
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800744 sb.append(", icon=");
745 sb.append(mIcon);
746
747 sb.append(", weight=");
748 sb.append(mWeight);
749
750 sb.append(", timestamp=");
751 sb.append(mLastChangedTimestamp);
752
753 sb.append(", intent=");
754 sb.append(mIntent);
755
756 sb.append(", intentExtras=");
757 sb.append(secure ? "***" : mIntentPersistableExtras);
758
759 sb.append(", extras=");
760 sb.append(mExtras);
761
Makoto Onuki55046222016-03-08 10:49:47 -0800762 sb.append(", flags=");
763 sb.append(mFlags);
764
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800765 if (includeInternalData) {
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800766
767 sb.append(", iconRes=");
768 sb.append(mIconResourceId);
769
770 sb.append(", bitmapPath=");
771 sb.append(mBitmapPath);
772 }
773
774 sb.append("}");
775 return sb.toString();
776 }
777
778 /** @hide */
779 public ShortcutInfo(String id, String packageName, ComponentName activityComponent,
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700780 Icon icon, String title, String text, Intent intent,
781 PersistableBundle intentPersistableExtras,
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800782 int weight, PersistableBundle extras, long lastChangedTimestamp,
783 int flags, int iconResId, String bitmapPath) {
784 mId = id;
785 mPackageName = packageName;
786 mActivityComponent = activityComponent;
787 mIcon = icon;
788 mTitle = title;
Makoto Onukie3ae7ec2016-03-29 15:45:25 -0700789 mText = text;
Makoto Onuki6f7362d92016-03-04 13:39:41 -0800790 mIntent = intent;
791 mIntentPersistableExtras = intentPersistableExtras;
792 mWeight = weight;
793 mExtras = extras;
794 mLastChangedTimestamp = lastChangedTimestamp;
795 mFlags = flags;
796 mIconResourceId = iconResId;
797 mBitmapPath = bitmapPath;
798 }
799}