1 /*
2  * Copyright (C) 2018 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 package android.app.prediction;
17 
18 import android.annotation.IntRange;
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.SystemApi;
22 import android.content.pm.ShortcutInfo;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.os.UserHandle;
26 
27 import java.util.Objects;
28 
29 /**
30  * A representation of a launchable target.
31  *
32  * @hide
33  */
34 @SystemApi
35 public final class AppTarget implements Parcelable {
36 
37     private final AppTargetId mId;
38     private final String mPackageName;
39     private final String mClassName;
40     private final UserHandle mUser;
41 
42     private final ShortcutInfo mShortcutInfo;
43 
44     private final int mRank;
45 
46     /**
47      * @deprecated use the Builder class
48      * @hide
49      */
50     @Deprecated
AppTarget(@onNull AppTargetId id, @NonNull String packageName, @Nullable String className, @NonNull UserHandle user)51     public AppTarget(@NonNull AppTargetId id, @NonNull String packageName,
52             @Nullable String className, @NonNull UserHandle user) {
53         mId = id;
54         mShortcutInfo = null;
55 
56         mPackageName = Objects.requireNonNull(packageName);
57         mClassName = className;
58         mUser = Objects.requireNonNull(user);
59         mRank = 0;
60     }
61 
62     /**
63      * @deprecated use the Builder class
64      * @hide
65      */
66     @Deprecated
AppTarget(@onNull AppTargetId id, @NonNull ShortcutInfo shortcutInfo, @Nullable String className)67     public AppTarget(@NonNull AppTargetId id, @NonNull ShortcutInfo shortcutInfo,
68             @Nullable String className) {
69         mId = id;
70         mShortcutInfo = Objects.requireNonNull(shortcutInfo);
71 
72         mPackageName = mShortcutInfo.getPackage();
73         mUser = mShortcutInfo.getUserHandle();
74         mClassName = className;
75         mRank = 0;
76     }
77 
AppTarget(AppTargetId id, String packageName, UserHandle user, ShortcutInfo shortcutInfo, String className, int rank)78     private AppTarget(AppTargetId id, String packageName, UserHandle user,
79             ShortcutInfo shortcutInfo, String className, int rank) {
80         mId = id;
81         mShortcutInfo = shortcutInfo;
82         mPackageName = packageName;
83         mClassName = className;
84         mUser = user;
85         mRank = rank;
86     }
87 
AppTarget(Parcel parcel)88     private AppTarget(Parcel parcel) {
89         mId = parcel.readTypedObject(AppTargetId.CREATOR);
90         mShortcutInfo = parcel.readTypedObject(ShortcutInfo.CREATOR);
91         if (mShortcutInfo == null) {
92             mPackageName = parcel.readString();
93             mUser = UserHandle.of(parcel.readInt());
94         } else {
95             mPackageName = mShortcutInfo.getPackage();
96             mUser = mShortcutInfo.getUserHandle();
97         }
98         mClassName = parcel.readString();
99         mRank = parcel.readInt();
100     }
101 
102     /**
103      * Returns the target id.
104      */
105     @NonNull
getId()106     public AppTargetId getId() {
107         return mId;
108     }
109 
110     /**
111      * Returns the class name for the app target.
112      */
113     @Nullable
getClassName()114     public String getClassName() {
115         return mClassName;
116     }
117 
118     /**
119      * Returns the package name for the app target.
120      */
121     @NonNull
getPackageName()122     public String getPackageName() {
123         return mPackageName;
124     }
125 
126     /**
127      * Returns the user for the app target.
128      */
129     @NonNull
getUser()130     public UserHandle getUser() {
131         return mUser;
132     }
133 
134     /**
135      * Returns the shortcut info for the target.
136      */
137     @Nullable
getShortcutInfo()138     public ShortcutInfo getShortcutInfo() {
139         return mShortcutInfo;
140     }
141 
142     /**
143      * Returns the rank for the target. Rank of an AppTarget is a non-negative integer that
144      * represents the importance of this target compared to other candidate targets. A smaller value
145      * means higher importance in the list.
146      */
getRank()147     public @IntRange(from = 0) int getRank() {
148         return mRank;
149     }
150 
151     @Override
equals(@ullable Object o)152     public boolean equals(@Nullable Object o) {
153         if (!getClass().equals(o != null ? o.getClass() : null)) return false;
154 
155         AppTarget other = (AppTarget) o;
156         boolean sameClassName = (mClassName == null && other.mClassName == null)
157                 || (mClassName != null && mClassName.equals(other.mClassName));
158         boolean sameShortcutInfo = (mShortcutInfo == null && other.mShortcutInfo == null)
159                 || (mShortcutInfo != null && other.mShortcutInfo != null
160                         && mShortcutInfo.getId() == other.mShortcutInfo.getId());
161         return mId.equals(other.mId)
162                 && mPackageName.equals(other.mPackageName)
163                 && sameClassName
164                 && mUser.equals(other.mUser)
165                 && sameShortcutInfo
166                 && mRank == other.mRank;
167     }
168 
169     @Override
describeContents()170     public int describeContents() {
171         return 0;
172     }
173 
174     @Override
writeToParcel(Parcel dest, int flags)175     public void writeToParcel(Parcel dest, int flags) {
176         dest.writeTypedObject(mId, flags);
177         dest.writeTypedObject(mShortcutInfo, flags);
178         if (mShortcutInfo == null) {
179             dest.writeString(mPackageName);
180             dest.writeInt(mUser.getIdentifier());
181         }
182         dest.writeString(mClassName);
183         dest.writeInt(mRank);
184     }
185 
186     /**
187      * A builder for app targets.
188      * @hide
189      */
190     @SystemApi
191     public static final class Builder {
192 
193         @NonNull
194         private final AppTargetId mId;
195 
196         private String mPackageName;
197         private UserHandle mUser;
198         private ShortcutInfo mShortcutInfo;
199 
200         private String mClassName;
201         private int mRank;
202 
203         /**
204          * @deprecated Use the other Builder constructors.
205          * @hide
206          * @removed
207          */
208         @Deprecated
209         @SystemApi
Builder(@onNull AppTargetId id)210         public Builder(@NonNull AppTargetId id) {
211             mId = id;
212         }
213 
214         /**
215          * @param id A unique id for this launchable target.
216          * @param packageName PackageName of the target.
217          * @param user The UserHandle of the user which this target belongs to.
218          * @hide
219          */
220         @SystemApi
Builder(@onNull AppTargetId id, @NonNull String packageName, @NonNull UserHandle user)221         public Builder(@NonNull AppTargetId id, @NonNull String packageName,
222                 @NonNull UserHandle user) {
223             mId = Objects.requireNonNull(id);
224             mPackageName = Objects.requireNonNull(packageName);
225             mUser = Objects.requireNonNull(user);
226         }
227 
228         /**
229          * @param id A unique id for this launchable target.
230          * @param info The ShortcutInfo that represents this launchable target.
231          * @hide
232          */
233         @SystemApi
Builder(@onNull AppTargetId id, @NonNull ShortcutInfo info)234         public Builder(@NonNull AppTargetId id, @NonNull ShortcutInfo info) {
235             mId = Objects.requireNonNull(id);
236             mShortcutInfo = Objects.requireNonNull(info);
237             mPackageName = info.getPackage();
238             mUser = info.getUserHandle();
239         }
240 
241         /**
242          * @deprecated Use the appropriate constructor.
243          * @removed
244          */
245         @NonNull
246         @Deprecated
setTarget(@onNull String packageName, @NonNull UserHandle user)247         public Builder setTarget(@NonNull String packageName, @NonNull UserHandle user) {
248             if (mPackageName != null) {
249                 throw new IllegalArgumentException("Target is already set");
250             }
251             mPackageName = Objects.requireNonNull(packageName);
252             mUser = Objects.requireNonNull(user);
253             return this;
254         }
255 
256         /**
257          * @deprecated Use the appropriate constructor.
258          * @removed
259          */
260         @NonNull
261         @Deprecated
setTarget(@onNull ShortcutInfo info)262         public Builder setTarget(@NonNull ShortcutInfo info) {
263             setTarget(info.getPackage(), info.getUserHandle());
264             mShortcutInfo = Objects.requireNonNull(info);
265             return this;
266         }
267 
268         /**
269          * Sets the className for the target.
270          */
271         @NonNull
setClassName(@onNull String className)272         public Builder setClassName(@NonNull String className) {
273             mClassName = Objects.requireNonNull(className);
274             return this;
275         }
276 
277         /**
278          * Sets the rank of the target.
279          */
280         @NonNull
setRank(@ntRangefrom = 0) int rank)281         public Builder setRank(@IntRange(from = 0) int rank) {
282             if (rank < 0) {
283                 throw new IllegalArgumentException("rank cannot be a negative value");
284             }
285             mRank = rank;
286             return this;
287         }
288 
289         /**
290          * Builds a new AppTarget instance.
291          *
292          * @throws IllegalStateException if no target is set
293          * @see #setTarget(ShortcutInfo)
294          * @see #setTarget(String, UserHandle)
295          */
296         @NonNull
build()297         public AppTarget build() {
298             if (mPackageName == null) {
299                 throw new IllegalStateException("No target is set");
300             }
301             return new AppTarget(mId, mPackageName, mUser, mShortcutInfo, mClassName, mRank);
302         }
303     }
304 
305     public static final @android.annotation.NonNull Parcelable.Creator<AppTarget> CREATOR =
306             new Parcelable.Creator<AppTarget>() {
307                 public AppTarget createFromParcel(Parcel parcel) {
308                     return new AppTarget(parcel);
309                 }
310 
311                 public AppTarget[] newArray(int size) {
312                     return new AppTarget[size];
313                 }
314             };
315 }
316