content: /*
   * Copyright (C) 2008 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package com.android.launcher3;
  
  import android.annotation.TargetApi;
  import android.content.ComponentName;
  import android.content.Context;
  import android.content.Intent;
  import android.os.Build;
  import android.text.TextUtils;
  
  import com.android.launcher3.LauncherSettings.Favorites;
  import com.android.launcher3.compat.UserManagerCompat;
  import com.android.launcher3.shortcuts.ShortcutInfoCompat;
  import com.android.launcher3.util.ContentWriter;
  
  /**
   * Represents a launchable icon on the workspaces and in folders.
   */
  public class ShortcutInfo extends ItemInfoWithIcon {
  
      public static final int DEFAULT = 0;
  
      /**
       * The shortcut was restored from a backup and it not ready to be used. This is automatically
       * set during backup/restore
       */
      public static final int FLAG_RESTORED_ICON = 1;
  
      /**
       * The icon was added as an auto-install app, and is not ready to be used. This flag can't
       * be present along with {@link #FLAG_RESTORED_ICON}, and is set during default layout
       * parsing.
       */
      public static final int FLAG_AUTOINSTALL_ICON = 2; //0B10;
  
      /**
       * The icon is being installed. If {@link #FLAG_RESTORED_ICON} or {@link #FLAG_AUTOINSTALL_ICON}
       * is set, then the icon is either being installed or is in a broken state.
       */
      public static final int FLAG_INSTALL_SESSION_ACTIVE = 4; // 0B100;
  
      /**
       * Indicates that the widget restore has started.
       */
      public static final int FLAG_RESTORE_STARTED = 8; //0B1000;
  
      /**
       * Web UI supported.
       */
      public static final int FLAG_SUPPORTS_WEB_UI = 16; //0B10000;
  
      /**
       * Indicates if it represents a common type mentioned in {@link CommonAppTypeParser}.
       * Upto 15 different types supported.
       */
      @Deprecated
      public static final int FLAG_RESTORED_APP_TYPE = 0B0011110000;
  
      /**
       * The intent used to start the application.
       */
      public Intent intent;
  
      /**
       * If isShortcut=true and customIcon=false, this contains a reference to the
       * shortcut icon as an application's resource.
       */
      public Intent.ShortcutIconResource iconResource;
  
      /**
       * Indicates that the icon is disabled due to safe mode restrictions.
       */
      public static final int FLAG_DISABLED_SAFEMODE = 1 << 0;
  
      /**
       * Indicates that the icon is disabled as the app is not available.
       */
      public static final int FLAG_DISABLED_NOT_AVAILABLE = 1 << 1;
  
      /**
       * Indicates that the icon is disabled as the app is suspended
       */
      public static final int FLAG_DISABLED_SUSPENDED = 1 << 2;
  
      /**
       * Indicates that the icon is disabled as the user is in quiet mode.
       */
      public static final int FLAG_DISABLED_QUIET_USER = 1 << 3;
  
      /**
       * Indicates that the icon is disabled as the publisher has disabled the actual shortcut.
       */
      public static final int FLAG_DISABLED_BY_PUBLISHER = 1 << 4;
  
      /**
       * Indicates that the icon is disabled as the user partition is currently locked.
       */
      public static final int FLAG_DISABLED_LOCKED_USER = 1 << 5;
  
      /**
       * Could be disabled, if the the app is installed but unavailable (eg. in safe mode or when
       * sd-card is not available).
       */
      public int isDisabled = DEFAULT;
  
      /**
       * A message to display when the user tries to start a disabled shortcut.
       * This is currently only used for deep shortcuts.
       */
      CharSequence disabledMessage;
  
      public int status;
  
      /**
       * The installation progress [0-100] of the package that this shortcut represents.
       */
      private int mInstallProgress;
  
      public ShortcutInfo() {
          itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
      }
  
      public ShortcutInfo(ShortcutInfo info) {
          super(info);
          title = info.title;
          intent = new Intent(info.intent);
          iconResource = info.iconResource;
          status = info.status;
          mInstallProgress = info.mInstallProgress;
          isDisabled = info.isDisabled;
      }
  
      /** TODO: Remove this.  It's only called by ApplicationInfo.makeShortcut. */
      public ShortcutInfo(AppInfo info) {
          super(info);
          title = Utilities.trim(info.title);
          intent = new Intent(info.intent);
          isDisabled = info.isDisabled;
      }
  
      /**
       * Creates a {@link ShortcutInfo} from a {@link ShortcutInfoCompat}.
       */
      @TargetApi(Build.VERSION_CODES.N)
      public ShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
          user = shortcutInfo.getUserHandle();
          itemType = LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
          updateFromDeepShortcutInfo(shortcutInfo, context);
      }
  
      @Override
      public void onAddToDatabase(ContentWriter writer) {
          super.onAddToDatabase(writer);
          writer.put(LauncherSettings.BaseLauncherColumns.TITLE, title)
                  .put(LauncherSettings.BaseLauncherColumns.INTENT, getIntent())
                  .put(LauncherSettings.Favorites.RESTORED, status);
  
          if (!usingLowResIcon) {
              writer.putIcon(iconBitmap, user);
          }
          if (iconResource != null) {
              writer.put(LauncherSettings.BaseLauncherColumns.ICON_PACKAGE, iconResource.packageName)
                      .put(LauncherSettings.BaseLauncherColumns.ICON_RESOURCE,
                              iconResource.resourceName);
          }
      }
  
      @Override
      public Intent getIntent() {
          return intent;
      }
  
      public boolean hasStatusFlag(int flag) {
          return (status & flag) != 0;
      }
  
  
      public final boolean isPromise() {
          return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON);
      }
  
      public boolean hasPromiseIconUi() {
          return isPromise() && !hasStatusFlag(FLAG_SUPPORTS_WEB_UI);
      }
  
      public int getInstallProgress() {
          return mInstallProgress;
      }
  
      public void setInstallProgress(int progress) {
          mInstallProgress = progress;
          status |= FLAG_INSTALL_SESSION_ACTIVE;
      }
  
      public void updateFromDeepShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
          // {@link ShortcutInfoCompat#getActivity} can change during an update. Recreate the intent
          intent = shortcutInfo.makeIntent();
          title = shortcutInfo.getShortLabel();
  
          CharSequence label = shortcutInfo.getLongLabel();
          if (TextUtils.isEmpty(label)) {
              label = shortcutInfo.getShortLabel();
          }
          contentDescription = UserManagerCompat.getInstance(context)
                  .getBadgedLabelForUser(label, user);
          if (shortcutInfo.isEnabled()) {
              isDisabled &= ~FLAG_DISABLED_BY_PUBLISHER;
          } else {
              isDisabled |= FLAG_DISABLED_BY_PUBLISHER;
          }
          disabledMessage = shortcutInfo.getDisabledMessage();
      }
  
      /** Returns the ShortcutInfo id associated with the deep shortcut. */
      public String getDeepShortcutId() {
          return itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT ?
                  getIntent().getStringExtra(ShortcutInfoCompat.EXTRA_SHORTCUT_ID) : null;
      }
  
      @Override
      public boolean isDisabled() {
          return isDisabled != 0;
      }
  
      @Override
      public ComponentName getTargetComponent() {
          ComponentName cn = super.getTargetComponent();
          if (cn == null && (itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
                  || hasStatusFlag(FLAG_SUPPORTS_WEB_UI))) {
              // Legacy shortcuts and promise icons with web UI may not have a componentName but just
              // a packageName. In that case create a dummy componentName instead of adding additional
              // check everywhere.
              String pkg = intent.getPackage();
              return pkg == null ? null : new ComponentName(pkg, IconCache.EMPTY_CLASS_NAME);
          }
          return cn;
      }
  }
  