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