From 3ff9047221820a01c6510503466f8c78b43fdc6d Mon Sep 17 00:00:00 2001 From: Charles He Date: Wed, 15 Feb 2017 12:22:56 +0000 Subject: [PATCH] Launcher3: fix app shortcuts for suspended apps This CL fixes app shortcuts for suspended packages. 1) When DO/PO suspends an app, its pinned shortcuts are instantly grayed out, but this is not persisted after the launcher restarts (e.g. device reboot). We now enforce the launcher to check the suspended state when loading the workspace, and gray out pinned shortcut icons accordingly. 2) When DO/PO suspends an app, its app shortcut popup is still available. We now temporarily disable the popup when the app is suspended, and persist the state across restarts. Bug: 32365540 Test: manual, by following the steps in the bug above Test: manual, by restarting the launcher package Change-Id: I983d7c17fa198beca23b66459b50bd67b447bdd2 --- src/com/android/launcher3/LauncherModel.java | 7 +++++-- .../android/launcher3/compat/LauncherAppsCompat.java | 2 ++ .../android/launcher3/compat/LauncherAppsCompatVL.java | 7 +++++++ .../android/launcher3/compat/LauncherAppsCompatVO.java | 6 ++++++ .../launcher3/shortcuts/DeepShortcutManager.java | 3 ++- .../android/launcher3/util/PackageManagerHelper.java | 18 ++++++++++++++++++ 6 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 9ad8433e7..4d48fea49 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -26,7 +26,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.LauncherActivityInfo; -import android.content.pm.PackageManager; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; @@ -84,7 +83,6 @@ import com.android.launcher3.util.ViewOnDrawExecutor; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -1340,6 +1338,11 @@ public class LauncherModel extends BroadcastReceiver info = new ShortcutInfo(pinnedShortcut, context); info.iconBitmap = LauncherIcons .createShortcutIcon(pinnedShortcut, context); + if (pmHelper.isAppSuspended( + info.getTargetComponent().getPackageName(), + info.user)) { + info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; + } intent = info.intent; } else { // Create a shortcut info in disabled mode for now. diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java index b9142ed16..44a3686ed 100644 --- a/src/com/android/launcher3/compat/LauncherAppsCompat.java +++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java @@ -19,6 +19,7 @@ package com.android.launcher3.compat; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.LauncherActivityInfo; import android.graphics.Rect; import android.os.Bundle; @@ -72,6 +73,7 @@ public abstract class LauncherAppsCompat { UserHandle user); public abstract void startActivityForProfile(ComponentName component, UserHandle user, Rect sourceBounds, Bundle opts); + public abstract ApplicationInfo getApplicationInfo(String packageName, UserHandle user); public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user); public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener); public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener); diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java index 3cb721ccc..776f59360 100644 --- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java +++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java @@ -19,6 +19,7 @@ package com.android.launcher3.compat; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; @@ -65,6 +66,12 @@ public class LauncherAppsCompatVL extends LauncherAppsCompat { } @Override + public ApplicationInfo getApplicationInfo(String packageName, UserHandle user) { + List activityList = mLauncherApps.getActivityList(packageName, user); + return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null; + } + + @Override public void showAppDetailsForProfile(ComponentName component, UserHandle user) { mLauncherApps.startAppDetailsActivity(component, user, null, null); } diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java index 0610726a7..377907aa9 100644 --- a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java +++ b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java @@ -17,6 +17,7 @@ package com.android.launcher3.compat; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; import android.os.UserHandle; @@ -34,6 +35,11 @@ public class LauncherAppsCompatVO extends LauncherAppsCompatVL { } @Override + public ApplicationInfo getApplicationInfo(String packageName, UserHandle user) { + return mLauncherApps.getApplicationInfo(packageName, 0, user); + } + + @Override public List getCustomShortcutActivityList() { List result = new ArrayList<>(); diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java index 941391362..df7f6954d 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java @@ -65,7 +65,8 @@ public class DeepShortcutManager { } public static boolean supportsShortcuts(ItemInfo info) { - return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; + return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION + && !info.isDisabled(); } public boolean wasLastCallSuccess() { diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java index e89fc0ca0..bfa932b6d 100644 --- a/src/com/android/launcher3/util/PackageManagerHelper.java +++ b/src/com/android/launcher3/util/PackageManagerHelper.java @@ -71,6 +71,10 @@ public class PackageManagerHelper { } } + /** + * Returns whether a package is suspended for the current user as per + * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}. + */ public boolean isAppSuspended(String packageName) { try { ApplicationInfo info = mPm.getApplicationInfo(packageName, 0); @@ -80,6 +84,16 @@ public class PackageManagerHelper { } } + /** + * Returns whether the target app is suspended for a given user as per + * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}. + */ + public boolean isAppSuspended(String packageName, UserHandle user) { + ApplicationInfo info = + LauncherAppsCompat.getInstance(mContext).getApplicationInfo(packageName, user); + return info != null && isAppSuspended(info); + } + public boolean isSafeMode() { return mPm.isSafeMode(); } @@ -91,6 +105,10 @@ public class PackageManagerHelper { AppInfo.makeLaunchIntent(mContext, activities.get(0), user); } + /** + * Returns whether an application is suspended as per + * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}. + */ public static boolean isAppSuspended(ApplicationInfo info) { // The value of FLAG_SUSPENDED was reused by a hidden constant // ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N -- 2.11.0