ShortcutInfo.java revision a214a63bfe365a0e81bc3082d56896c6df24d0b4
1/*
2 * Copyright (C) 2008 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 com.android.launcher3;
18
19import android.content.ComponentName;
20import android.content.ContentValues;
21import android.content.Context;
22import android.content.Intent;
23import android.graphics.Bitmap;
24import android.util.Log;
25
26import com.android.launcher3.LauncherSettings.Favorites;
27import com.android.launcher3.compat.LauncherActivityInfoCompat;
28import com.android.launcher3.compat.UserHandleCompat;
29import com.android.launcher3.compat.UserManagerCompat;
30
31import java.util.ArrayList;
32import java.util.Arrays;
33
34/**
35 * Represents a launchable icon on the workspaces and in folders.
36 */
37public class ShortcutInfo extends ItemInfo {
38
39    public static final int DEFAULT = 0;
40
41    /**
42     * The shortcut was restored from a backup and it not ready to be used. This is automatically
43     * set during backup/restore
44     */
45    public static final int FLAG_RESTORED_ICON = 1;
46
47    /**
48     * The icon was added as an auto-install app, and is not ready to be used. This flag can't
49     * be present along with {@link #FLAG_RESTORED_ICON}, and is set during default layout
50     * parsing.
51     */
52    public static final int FLAG_AUTOINTALL_ICON = 2; //0B10;
53
54    /**
55     * The icon is being installed. If {@link FLAG_RESTORED_ICON} or {@link FLAG_AUTOINTALL_ICON}
56     * is set, then the icon is either being installed or is in a broken state.
57     */
58    public static final int FLAG_INSTALL_SESSION_ACTIVE = 4; // 0B100;
59
60    /**
61     * Indicates that the widget restore has started.
62     */
63    public static final int FLAG_RESTORE_STARTED = 8; //0B1000;
64
65    /**
66     * Indicates if it represents a common type mentioned in {@link CommonAppTypeParser}.
67     * Upto 15 different types supported.
68     */
69    public static final int FLAG_RESTORED_APP_TYPE = 0B0011110000;
70
71    /**
72     * The intent used to start the application.
73     */
74    Intent intent;
75
76    /**
77     * Indicates whether the icon comes from an application's resource (if false)
78     * or from a custom Bitmap (if true.)
79     */
80    boolean customIcon;
81
82    /**
83     * Indicates whether we're using the default fallback icon instead of something from the
84     * app.
85     */
86    boolean usingFallbackIcon;
87
88    /**
89     * Indicates whether we're using a low res icon
90     */
91    boolean usingLowResIcon;
92
93    /**
94     * If isShortcut=true and customIcon=false, this contains a reference to the
95     * shortcut icon as an application's resource.
96     */
97    Intent.ShortcutIconResource iconResource;
98
99    /**
100     * The application icon.
101     */
102    private Bitmap mIcon;
103
104    /**
105     * Indicates that the icon is disabled due to safe mode restrictions.
106     */
107    public static final int FLAG_DISABLED_SAFEMODE = 1;
108
109    /**
110     * Indicates that the icon is disabled as the app is not available.
111     */
112    public static final int FLAG_DISABLED_NOT_AVAILABLE = 2;
113
114    /**
115     * Could be disabled, if the the app is installed but unavailable (eg. in safe mode or when
116     * sd-card is not available).
117     */
118    int isDisabled = DEFAULT;
119
120    int status;
121
122    /**
123     * The installation progress [0-100] of the package that this shortcut represents.
124     */
125    private int mInstallProgress;
126
127    /**
128     * Refer {@link AppInfo#firstInstallTime}.
129     */
130    public long firstInstallTime;
131
132    /**
133     * TODO move this to {@link status}
134     */
135    int flags = 0;
136
137    /**
138     * If this shortcut is a placeholder, then intent will be a market intent for the package, and
139     * this will hold the original intent from the database.  Otherwise, null.
140     * Refer {@link #FLAG_RESTORE_PENDING}, {@link #FLAG_INSTALL_PENDING}
141     */
142    Intent promisedIntent;
143
144    ShortcutInfo() {
145        itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
146    }
147
148    public Intent getIntent() {
149        return intent;
150    }
151
152    ShortcutInfo(Intent intent, CharSequence title, CharSequence contentDescription,
153            Bitmap icon, UserHandleCompat user) {
154        this();
155        this.intent = intent;
156        this.title = Utilities.trim(title);
157        this.contentDescription = contentDescription;
158        mIcon = icon;
159        this.user = user;
160    }
161
162    public ShortcutInfo(Context context, ShortcutInfo info) {
163        super(info);
164        title = Utilities.trim(info.title);
165        intent = new Intent(info.intent);
166        if (info.iconResource != null) {
167            iconResource = new Intent.ShortcutIconResource();
168            iconResource.packageName = info.iconResource.packageName;
169            iconResource.resourceName = info.iconResource.resourceName;
170        }
171        mIcon = info.mIcon; // TODO: should make a copy here.  maybe we don't need this ctor at all
172        customIcon = info.customIcon;
173        flags = info.flags;
174        firstInstallTime = info.firstInstallTime;
175        user = info.user;
176        status = info.status;
177    }
178
179    /** TODO: Remove this.  It's only called by ApplicationInfo.makeShortcut. */
180    public ShortcutInfo(AppInfo info) {
181        super(info);
182        title = Utilities.trim(info.title);
183        intent = new Intent(info.intent);
184        customIcon = false;
185        flags = info.flags;
186        firstInstallTime = info.firstInstallTime;
187    }
188
189    public void setIcon(Bitmap b) {
190        mIcon = b;
191    }
192
193    public Bitmap getIcon(IconCache iconCache) {
194        if (mIcon == null) {
195            updateIcon(iconCache);
196        }
197        return mIcon;
198    }
199
200    public void updateIcon(IconCache iconCache) {
201        if (itemType == Favorites.ITEM_TYPE_APPLICATION) {
202            iconCache.getTitleAndIcon(this, promisedIntent != null ? promisedIntent : intent, user,
203                    shouldUseLowResIcon());
204        }
205    }
206
207    @Override
208    void onAddToDatabase(Context context, ContentValues values) {
209        super.onAddToDatabase(context, values);
210
211        String titleStr = title != null ? title.toString() : null;
212        values.put(LauncherSettings.BaseLauncherColumns.TITLE, titleStr);
213
214        String uri = promisedIntent != null ? promisedIntent.toUri(0)
215                : (intent != null ? intent.toUri(0) : null);
216        values.put(LauncherSettings.BaseLauncherColumns.INTENT, uri);
217        values.put(LauncherSettings.Favorites.RESTORED, status);
218
219        if (customIcon) {
220            values.put(LauncherSettings.BaseLauncherColumns.ICON_TYPE,
221                    LauncherSettings.BaseLauncherColumns.ICON_TYPE_BITMAP);
222            writeBitmap(values, mIcon);
223        } else {
224            if (!usingFallbackIcon) {
225                writeBitmap(values, mIcon);
226            }
227            if (iconResource != null) {
228                values.put(LauncherSettings.BaseLauncherColumns.ICON_TYPE,
229                        LauncherSettings.BaseLauncherColumns.ICON_TYPE_RESOURCE);
230                values.put(LauncherSettings.BaseLauncherColumns.ICON_PACKAGE,
231                        iconResource.packageName);
232                values.put(LauncherSettings.BaseLauncherColumns.ICON_RESOURCE,
233                        iconResource.resourceName);
234            }
235        }
236    }
237
238    @Override
239    public String toString() {
240        return "ShortcutInfo(title=" + title + "intent=" + intent + "id=" + this.id
241                + " type=" + this.itemType + " container=" + this.container + " screen=" + screenId
242                + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX + " spanY=" + spanY
243                + " dropPos=" + Arrays.toString(dropPos) + " user=" + user + ")";
244    }
245
246    public static void dumpShortcutInfoList(String tag, String label,
247            ArrayList<ShortcutInfo> list) {
248        Log.d(tag, label + " size=" + list.size());
249        for (ShortcutInfo info: list) {
250            Log.d(tag, "   title=\"" + info.title + " icon=" + info.mIcon
251                    + " customIcon=" + info.customIcon);
252        }
253    }
254
255    public ComponentName getTargetComponent() {
256        return promisedIntent != null ? promisedIntent.getComponent() : intent.getComponent();
257    }
258
259    public boolean hasStatusFlag(int flag) {
260        return (status & flag) != 0;
261    }
262
263
264    public final boolean isPromise() {
265        return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINTALL_ICON);
266    }
267
268    public int getInstallProgress() {
269        return mInstallProgress;
270    }
271
272    public void setInstallProgress(int progress) {
273        mInstallProgress = progress;
274        status |= FLAG_INSTALL_SESSION_ACTIVE;
275    }
276
277    public boolean shouldUseLowResIcon() {
278        return usingLowResIcon && container >= 0 && rank >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
279    }
280
281    public static ShortcutInfo fromActivityInfo(LauncherActivityInfoCompat info, Context context) {
282        final ShortcutInfo shortcut = new ShortcutInfo();
283        shortcut.user = info.getUser();
284        shortcut.title = Utilities.trim(info.getLabel());
285        shortcut.contentDescription = UserManagerCompat.getInstance(context)
286                .getBadgedLabelForUser(info.getLabel(), info.getUser());
287        shortcut.customIcon = false;
288        shortcut.intent = AppInfo.makeLaunchIntent(context, info, info.getUser());
289        shortcut.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
290        shortcut.flags = AppInfo.initFlags(info);
291        shortcut.firstInstallTime = info.getFirstInstallTime();
292        return shortcut;
293    }
294}
295
296