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 17 package com.android.launcher3; 18 19 import android.annotation.TargetApi; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.Build; 23 import android.text.TextUtils; 24 25 import com.android.launcher3.LauncherSettings.Favorites; 26 import com.android.launcher3.compat.UserManagerCompat; 27 import com.android.launcher3.shortcuts.ShortcutInfoCompat; 28 import com.android.launcher3.util.ContentWriter; 29 30 /** 31 * Represents a launchable icon on the workspaces and in folders. 32 */ 33 public class ShortcutInfo extends ItemInfoWithIcon { 34 35 public static final int DEFAULT = 0; 36 37 /** 38 * The shortcut was restored from a backup and it not ready to be used. This is automatically 39 * set during backup/restore 40 */ 41 public static final int FLAG_RESTORED_ICON = 1; 42 43 /** 44 * The icon was added as an auto-install app, and is not ready to be used. This flag can't 45 * be present along with {@link #FLAG_RESTORED_ICON}, and is set during default layout 46 * parsing. 47 */ 48 public static final int FLAG_AUTOINTALL_ICON = 2; //0B10; 49 50 /** 51 * The icon is being installed. If {@link #FLAG_RESTORED_ICON} or {@link #FLAG_AUTOINTALL_ICON} 52 * is set, then the icon is either being installed or is in a broken state. 53 */ 54 public static final int FLAG_INSTALL_SESSION_ACTIVE = 4; // 0B100; 55 56 /** 57 * Indicates that the widget restore has started. 58 */ 59 public static final int FLAG_RESTORE_STARTED = 8; //0B1000; 60 61 /** 62 * Indicates if it represents a common type mentioned in {@link CommonAppTypeParser}. 63 * Upto 15 different types supported. 64 */ 65 @Deprecated 66 public static final int FLAG_RESTORED_APP_TYPE = 0B0011110000; 67 68 /** 69 * The intent used to start the application. 70 */ 71 public Intent intent; 72 73 /** 74 * If isShortcut=true and customIcon=false, this contains a reference to the 75 * shortcut icon as an application's resource. 76 */ 77 public Intent.ShortcutIconResource iconResource; 78 79 /** 80 * Indicates that the icon is disabled due to safe mode restrictions. 81 */ 82 public static final int FLAG_DISABLED_SAFEMODE = 1 << 0; 83 84 /** 85 * Indicates that the icon is disabled as the app is not available. 86 */ 87 public static final int FLAG_DISABLED_NOT_AVAILABLE = 1 << 1; 88 89 /** 90 * Indicates that the icon is disabled as the app is suspended 91 */ 92 public static final int FLAG_DISABLED_SUSPENDED = 1 << 2; 93 94 /** 95 * Indicates that the icon is disabled as the user is in quiet mode. 96 */ 97 public static final int FLAG_DISABLED_QUIET_USER = 1 << 3; 98 99 /** 100 * Indicates that the icon is disabled as the publisher has disabled the actual shortcut. 101 */ 102 public static final int FLAG_DISABLED_BY_PUBLISHER = 1 << 4; 103 104 /** 105 * Indicates that the icon is disabled as the user partition is currently locked. 106 */ 107 public static final int FLAG_DISABLED_LOCKED_USER = 1 << 5; 108 109 /** 110 * Could be disabled, if the the app is installed but unavailable (eg. in safe mode or when 111 * sd-card is not available). 112 */ 113 public int isDisabled = DEFAULT; 114 115 /** 116 * A message to display when the user tries to start a disabled shortcut. 117 * This is currently only used for deep shortcuts. 118 */ 119 CharSequence disabledMessage; 120 121 public int status; 122 123 /** 124 * The installation progress [0-100] of the package that this shortcut represents. 125 */ 126 private int mInstallProgress; 127 128 public ShortcutInfo() { 129 itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT; 130 } 131 132 public ShortcutInfo(ShortcutInfo info) { 133 super(info); 134 title = info.title; 135 intent = new Intent(info.intent); 136 iconResource = info.iconResource; 137 status = info.status; 138 mInstallProgress = info.mInstallProgress; 139 isDisabled = info.isDisabled; 140 } 141 142 /** TODO: Remove this. It's only called by ApplicationInfo.makeShortcut. */ 143 public ShortcutInfo(AppInfo info) { 144 super(info); 145 title = Utilities.trim(info.title); 146 intent = new Intent(info.intent); 147 isDisabled = info.isDisabled; 148 } 149 150 /** 151 * Creates a {@link ShortcutInfo} from a {@link ShortcutInfoCompat}. 152 */ 153 @TargetApi(Build.VERSION_CODES.N) 154 public ShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) { 155 user = shortcutInfo.getUserHandle(); 156 itemType = LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; 157 updateFromDeepShortcutInfo(shortcutInfo, context); 158 } 159 160 @Override 161 public void onAddToDatabase(ContentWriter writer) { 162 super.onAddToDatabase(writer); 163 writer.put(LauncherSettings.BaseLauncherColumns.TITLE, title) 164 .put(LauncherSettings.BaseLauncherColumns.INTENT, getIntent()) 165 .put(LauncherSettings.Favorites.RESTORED, status); 166 167 if (!usingLowResIcon) { 168 writer.putIcon(iconBitmap, user); 169 } 170 if (iconResource != null) { 171 writer.put(LauncherSettings.BaseLauncherColumns.ICON_PACKAGE, iconResource.packageName) 172 .put(LauncherSettings.BaseLauncherColumns.ICON_RESOURCE, 173 iconResource.resourceName); 174 } 175 } 176 177 @Override 178 public Intent getIntent() { 179 return intent; 180 } 181 182 public boolean hasStatusFlag(int flag) { 183 return (status & flag) != 0; 184 } 185 186 187 public final boolean isPromise() { 188 return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINTALL_ICON); 189 } 190 191 public int getInstallProgress() { 192 return mInstallProgress; 193 } 194 195 public void setInstallProgress(int progress) { 196 mInstallProgress = progress; 197 status |= FLAG_INSTALL_SESSION_ACTIVE; 198 } 199 200 public void updateFromDeepShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) { 201 // {@link ShortcutInfoCompat#getActivity} can change during an update. Recreate the intent 202 intent = shortcutInfo.makeIntent(); 203 title = shortcutInfo.getShortLabel(); 204 205 CharSequence label = shortcutInfo.getLongLabel(); 206 if (TextUtils.isEmpty(label)) { 207 label = shortcutInfo.getShortLabel(); 208 } 209 contentDescription = UserManagerCompat.getInstance(context) 210 .getBadgedLabelForUser(label, user); 211 if (shortcutInfo.isEnabled()) { 212 isDisabled &= ~FLAG_DISABLED_BY_PUBLISHER; 213 } else { 214 isDisabled |= FLAG_DISABLED_BY_PUBLISHER; 215 } 216 disabledMessage = shortcutInfo.getDisabledMessage(); 217 } 218 219 /** Returns the ShortcutInfo id associated with the deep shortcut. */ 220 public String getDeepShortcutId() { 221 return itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT ? 222 getIntent().getStringExtra(ShortcutInfoCompat.EXTRA_SHORTCUT_ID) : null; 223 } 224 225 @Override 226 public boolean isDisabled() { 227 return isDisabled != 0; 228 } 229 } 230