From 0121d466ecd42610e92faae68d9e67721e87eaa3 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 1 Aug 2019 15:44:55 -0700 Subject: [PATCH] Fix launcher crash when trying to open work profile promise icon. Bug: 138609751 Change-Id: Ifb1c4628ce6307a19a2bb696e4771d5cd5810a90 --- .../launcher3/BaseDraggingActivity.java | 2 +- .../compat/PackageInstallerCompat.java | 6 ++++ .../compat/PackageInstallerCompatVL.java | 17 ++++++++-- .../launcher3/touch/ItemClickHandler.java | 31 +++++++++++++++++-- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index 50553095d6..f0b3afd14a 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -170,7 +170,7 @@ public abstract class BaseDraggingActivity extends BaseActivity getUserEventDispatcher().logAppLaunch(v, intent); getStatsLogManager().logAppLaunch(v, intent); return true; - } catch (ActivityNotFoundException|SecurityException e) { + } catch (NullPointerException|ActivityNotFoundException|SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e); } diff --git a/src/com/android/launcher3/compat/PackageInstallerCompat.java b/src/com/android/launcher3/compat/PackageInstallerCompat.java index 7dad7e9052..4f4d64161a 100644 --- a/src/com/android/launcher3/compat/PackageInstallerCompat.java +++ b/src/com/android/launcher3/compat/PackageInstallerCompat.java @@ -19,6 +19,7 @@ package com.android.launcher3.compat; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageInstaller; +import android.os.UserHandle; import java.util.HashMap; import java.util.List; @@ -48,6 +49,11 @@ public abstract class PackageInstallerCompat { */ public abstract HashMap updateAndGetActiveSessionCache(); + /** + * @return an active SessionInfo for {@param pkg} or null if none exists. + */ + public abstract PackageInstaller.SessionInfo getActiveSessionInfo(UserHandle user, String pkg); + public abstract void onStop(); public static final class PackageInstallInfo { diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java index a34ca50ebf..8a5eabca99 100644 --- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java +++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java @@ -64,9 +64,9 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat { @Override public HashMap updateAndGetActiveSessionCache() { HashMap activePackages = new HashMap<>(); - UserHandle user = Process.myUserHandle(); + UserHandle primaryUser = Process.myUserHandle(); for (SessionInfo info : getAllVerifiedSessions()) { - addSessionInfoToCache(info, user); + addSessionInfoToCache(info, Utilities.ATLEAST_Q ? info.getUser() : primaryUser); if (info.getAppPackageName() != null) { activePackages.put(info.getAppPackageName(), info); mActiveSessions.put(info.getSessionId(), info.getAppPackageName()); @@ -75,6 +75,19 @@ public class PackageInstallerCompatVL extends PackageInstallerCompat { return activePackages; } + public SessionInfo getActiveSessionInfo(UserHandle user, String pkg) { + for (SessionInfo info : getAllVerifiedSessions()) { + boolean match = pkg.equals(info.getAppPackageName()); + if (Utilities.ATLEAST_Q && !user.equals(info.getUser())) { + match = false; + } + if (match) { + return info; + } + } + return null; + } + @Thunk void addSessionInfoToCache(SessionInfo info, UserHandle user) { String packageName = info.getAppPackageName(); if (packageName != null) { diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index 2895a89be3..03493a5389 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -25,9 +25,15 @@ import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET; import static com.android.launcher3.model.AppLaunchTracker.CONTAINER_ALL_APPS; import android.app.AlertDialog; +import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.Intent; +import android.content.pm.LauncherApps; +import android.content.pm.PackageInstaller.SessionInfo; import android.os.Process; +import android.os.UserHandle; import android.text.TextUtils; +import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; @@ -43,11 +49,12 @@ import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.PromiseAppInfo; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.compat.AppWidgetManagerCompat; +import com.android.launcher3.compat.PackageInstallerCompat; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.views.FloatingIconView; import com.android.launcher3.widget.PendingAppWidgetHostView; @@ -58,6 +65,8 @@ import com.android.launcher3.widget.WidgetAddFlowHandler; */ public class ItemClickHandler { + private static final String TAG = ItemClickHandler.class.getSimpleName(); + /** * Instance used for click handling on items */ @@ -146,6 +155,8 @@ public class ItemClickHandler { startMarketIntentForPackage(v, launcher, packageName); return; } + UserHandle user = v.getTag() instanceof ItemInfo + ? ((ItemInfo) v.getTag()).user : Process.myUserHandle(); new AlertDialog.Builder(launcher) .setTitle(R.string.abandoned_promises_title) .setMessage(R.string.abandoned_promise_explanation) @@ -153,12 +164,28 @@ public class ItemClickHandler { (d, i) -> startMarketIntentForPackage(v, launcher, packageName)) .setNeutralButton(R.string.abandoned_clean_this, (d, i) -> launcher.getWorkspace() - .removeAbandonedPromise(packageName, Process.myUserHandle())) + .removeAbandonedPromise(packageName, user)) .create().show(); } private static void startMarketIntentForPackage(View v, Launcher launcher, String packageName) { ItemInfo item = (ItemInfo) v.getTag(); + if (Utilities.ATLEAST_Q) { + PackageInstallerCompat pkgInstaller = PackageInstallerCompat.getInstance(launcher); + SessionInfo sessionInfo = pkgInstaller.getActiveSessionInfo(item.user, packageName); + if (sessionInfo != null) { + LauncherApps launcherApps = launcher.getSystemService(LauncherApps.class); + try { + launcherApps.startPackageInstallerSessionDetailsActivity(sessionInfo, null, + launcher.getActivityLaunchOptionsAsBundle(v)); + return; + } catch (Exception e) { + Log.e(TAG, "Unable to launch market intent for package=" + packageName, e); + } + } + } + + // Fallback to using custom market intent. Intent intent = new PackageManagerHelper(launcher).getMarketIntent(packageName); launcher.startActivitySafely(v, intent, item, null); }