blob: c2f70cc02f056da9be8bf9980e1764a8f43251f8 [file] [log] [blame]
Adam Powelle30c9af32015-02-27 15:51:11 -08001/*
2 * Copyright (C) 2015 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
18package android.service.chooser;
19
Adam Powell666d82a2015-07-15 20:14:57 -070020import android.annotation.Nullable;
Adam Powelle30c9af32015-02-27 15:51:11 -080021import android.content.ComponentName;
Adam Powelle30c9af32015-02-27 15:51:11 -080022import android.content.Intent;
23import android.content.IntentFilter;
Adam Powell13036be2015-05-12 14:43:56 -070024import android.graphics.drawable.Icon;
Adam Powell24428412015-04-01 17:19:56 -070025import android.os.Bundle;
Adam Powelle30c9af32015-02-27 15:51:11 -080026import android.os.Parcel;
27import android.os.Parcelable;
Adam Powelle30c9af32015-02-27 15:51:11 -080028
29/**
30 * A ChooserTarget represents a deep-link into an application as returned by a
31 * {@link android.service.chooser.ChooserTargetService}.
Adam Powell13036be2015-05-12 14:43:56 -070032 *
33 * <p>A chooser target represents a specific deep link target into an application exposed
34 * for selection by the user. This might be a frequently emailed contact, a recently active
35 * group messaging conversation, a folder in a cloud storage app, a collection of related
36 * items published on a social media service or any other contextually relevant grouping
37 * of target app + relevant metadata.</p>
38 *
39 * <p>Creators of chooser targets should consult the relevant design guidelines for the type
40 * of target they are presenting. For example, targets involving people should be presented
41 * with a circular icon.</p>
Adam Powelle30c9af32015-02-27 15:51:11 -080042 */
43public final class ChooserTarget implements Parcelable {
44 private static final String TAG = "ChooserTarget";
45
46 /**
47 * The title of this target that will be shown to the user. The title may be truncated
48 * if it is too long to display in the space provided.
49 */
50 private CharSequence mTitle;
51
52 /**
53 * The icon that will be shown to the user to represent this target.
54 * The system may resize this icon as appropriate.
55 */
Adam Powell13036be2015-05-12 14:43:56 -070056 private Icon mIcon;
Adam Powelle30c9af32015-02-27 15:51:11 -080057
58 /**
Adam Powell666d82a2015-07-15 20:14:57 -070059 * The ComponentName of the Activity to be invoked. Must be part of the target creator's
60 * own package or an Activity exported by its package.
Adam Powelle30c9af32015-02-27 15:51:11 -080061 */
Adam Powell666d82a2015-07-15 20:14:57 -070062 private ComponentName mComponentName;
63
64 /**
65 * A Bundle to merge with the extras of the intent sent to this target.
66 * Any extras here will override the extras from the original intent.
67 */
68 private Bundle mIntentExtras;
Adam Powelle30c9af32015-02-27 15:51:11 -080069
70 /**
71 * The score given to this item. It can be normalized.
72 */
73 private float mScore;
74
75 /**
76 * Construct a deep link target for presentation by a chooser UI.
77 *
78 * <p>A target is composed of a title and an icon for presentation to the user.
79 * The UI presenting this target may truncate the title if it is too long to be presented
80 * in the available space, as well as crop, resize or overlay the supplied icon.</p>
81 *
82 * <p>The creator of a target may supply a ranking score. This score is assumed to be relative
83 * to the other targets supplied by the same
84 * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}.
Adam Powellc6d5e3a2015-04-23 12:22:20 -070085 * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).
86 * Scores for a set of targets do not need to sum to 1.</p>
Adam Powelle30c9af32015-02-27 15:51:11 -080087 *
Adam Powell666d82a2015-07-15 20:14:57 -070088 * <p>The ComponentName must be the name of an Activity component in the creator's own
89 * package, or an exported component from any other package. You may provide an optional
90 * Bundle of extras that will be merged into the final intent before it is sent to the
91 * target Activity; use this to add any additional data about the deep link that the target
92 * activity will read. e.g. conversation IDs, email addresses, etc.</p>
Adam Powelle30c9af32015-02-27 15:51:11 -080093 *
94 * <p>Take care not to place custom {@link android.os.Parcelable} types into
Adam Powell666d82a2015-07-15 20:14:57 -070095 * the extras bundle, as the system will not be able to unparcel them to merge them.</p>
Adam Powelle30c9af32015-02-27 15:51:11 -080096 *
97 * @param title title of this target that will be shown to a user
98 * @param icon icon to represent this target
99 * @param score ranking score for this target between 0.0f and 1.0f, inclusive
Adam Powell666d82a2015-07-15 20:14:57 -0700100 * @param componentName Name of the component to be launched if this target is chosen
101 * @param intentExtras Bundle of extras to merge with the extras of the launched intent
Adam Powelle30c9af32015-02-27 15:51:11 -0800102 */
Adam Powell13036be2015-05-12 14:43:56 -0700103 public ChooserTarget(CharSequence title, Icon icon, float score,
Adam Powell666d82a2015-07-15 20:14:57 -0700104 ComponentName componentName, @Nullable Bundle intentExtras) {
Adam Powelle30c9af32015-02-27 15:51:11 -0800105 mTitle = title;
106 mIcon = icon;
107 if (score > 1.f || score < 0.f) {
108 throw new IllegalArgumentException("Score " + score + " out of range; "
109 + "must be between 0.0f and 1.0f");
110 }
111 mScore = score;
Adam Powell666d82a2015-07-15 20:14:57 -0700112 mComponentName = componentName;
113 mIntentExtras = intentExtras;
Adam Powelle30c9af32015-02-27 15:51:11 -0800114 }
115
116 ChooserTarget(Parcel in) {
117 mTitle = in.readCharSequence();
118 if (in.readInt() != 0) {
Adam Powell13036be2015-05-12 14:43:56 -0700119 mIcon = Icon.CREATOR.createFromParcel(in);
Adam Powelle30c9af32015-02-27 15:51:11 -0800120 } else {
121 mIcon = null;
122 }
123 mScore = in.readFloat();
Adam Powell666d82a2015-07-15 20:14:57 -0700124 mComponentName = ComponentName.readFromParcel(in);
125 mIntentExtras = in.readBundle();
Adam Powelle30c9af32015-02-27 15:51:11 -0800126 }
127
128 /**
129 * Returns the title of this target for display to a user. The UI displaying the title
130 * may truncate this title if it is too long to be displayed in full.
131 *
132 * @return the title of this target, intended to be shown to a user
133 */
134 public CharSequence getTitle() {
135 return mTitle;
136 }
137
138 /**
139 * Returns the icon representing this target for display to a user. The UI displaying the icon
140 * may crop, resize or overlay this icon.
141 *
142 * @return the icon representing this target, intended to be shown to a user
143 */
Adam Powell13036be2015-05-12 14:43:56 -0700144 public Icon getIcon() {
Adam Powelle30c9af32015-02-27 15:51:11 -0800145 return mIcon;
146 }
147
148 /**
149 * Returns the ranking score supplied by the creator of this ChooserTarget.
150 * Values are between 0.0f and 1.0f. The UI displaying the target may
151 * take this score into account when sorting and merging targets from multiple sources.
152 *
153 * @return the ranking score for this target between 0.0f and 1.0f, inclusive
154 */
155 public float getScore() {
156 return mScore;
157 }
158
159 /**
Adam Powell666d82a2015-07-15 20:14:57 -0700160 * Returns the ComponentName of the Activity that should be launched for this ChooserTarget.
Adam Powelle30c9af32015-02-27 15:51:11 -0800161 *
Adam Powell666d82a2015-07-15 20:14:57 -0700162 * @return the name of the target Activity to launch
Adam Powelle30c9af32015-02-27 15:51:11 -0800163 */
Adam Powell666d82a2015-07-15 20:14:57 -0700164 public ComponentName getComponentName() {
165 return mComponentName;
Adam Powelle30c9af32015-02-27 15:51:11 -0800166 }
167
168 /**
Adam Powell666d82a2015-07-15 20:14:57 -0700169 * Returns the Bundle of extras to be added to an intent launched to this target.
Adam Powelle30c9af32015-02-27 15:51:11 -0800170 *
Adam Powell666d82a2015-07-15 20:14:57 -0700171 * @return the extras to merge with the extras of the intent being launched
Adam Powelle30c9af32015-02-27 15:51:11 -0800172 */
Adam Powell666d82a2015-07-15 20:14:57 -0700173 public Bundle getIntentExtras() {
174 return mIntentExtras;
Adam Powelle30c9af32015-02-27 15:51:11 -0800175 }
176
177 @Override
178 public String toString() {
Adam Powell24428412015-04-01 17:19:56 -0700179 return "ChooserTarget{"
Adam Powell666d82a2015-07-15 20:14:57 -0700180 + mComponentName
181 + ", " + mIntentExtras
182 + ", '" + mTitle
Adam Powelle30c9af32015-02-27 15:51:11 -0800183 + "', " + mScore + "}";
184 }
185
186 @Override
187 public int describeContents() {
188 return 0;
189 }
190
191 @Override
192 public void writeToParcel(Parcel dest, int flags) {
193 dest.writeCharSequence(mTitle);
194 if (mIcon != null) {
195 dest.writeInt(1);
196 mIcon.writeToParcel(dest, 0);
197 } else {
198 dest.writeInt(0);
199 }
200 dest.writeFloat(mScore);
Adam Powell666d82a2015-07-15 20:14:57 -0700201 ComponentName.writeToParcel(mComponentName, dest);
202 dest.writeBundle(mIntentExtras);
Adam Powelle30c9af32015-02-27 15:51:11 -0800203 }
204
205 public static final Creator<ChooserTarget> CREATOR
206 = new Creator<ChooserTarget>() {
207 @Override
208 public ChooserTarget createFromParcel(Parcel source) {
209 return new ChooserTarget(source);
210 }
211
212 @Override
213 public ChooserTarget[] newArray(int size) {
214 return new ChooserTarget[size];
215 }
216 };
217}