summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2016-11-22 03:23:51 +0530
committerSunny Goyal <sunnygoyal@google.com>2016-12-03 15:55:13 +0530
commitf75baa9f4023c0cf728360806891fd344aa8f3cd (patch)
tree4e435203ac1763e72675b7cbd9cda480aec7e0c7 /src
parent36f71f873b5176fdd2b24886d0bc4371b1d5cb82 (diff)
downloadandroid_packages_apps_Trebuchet-f75baa9f4023c0cf728360806891fd344aa8f3cd.tar.gz
android_packages_apps_Trebuchet-f75baa9f4023c0cf728360806891fd344aa8f3cd.tar.bz2
android_packages_apps_Trebuchet-f75baa9f4023c0cf728360806891fd344aa8f3cd.zip
Adding support for deep shortcuts in Install queue
Bug: 32904959 Change-Id: Ida43bcf78da716defdf95eb704c31973bc390ea1
Diffstat (limited to 'src')
-rw-r--r--src/com/android/launcher3/InstallShortcutReceiver.java201
-rw-r--r--src/com/android/launcher3/LauncherModel.java5
-rw-r--r--src/com/android/launcher3/model/BgDataModel.java10
3 files changed, 148 insertions, 68 deletions
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index d2f25a4a0..46df0b283 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -32,6 +32,9 @@ import com.android.launcher3.compat.LauncherActivityInfoCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.shortcuts.DeepShortcutManager;
+import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider;
@@ -40,10 +43,10 @@ import com.android.launcher3.util.Thunk;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
-import org.json.JSONTokener;
import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -63,6 +66,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
private static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage";
private static final String APP_SHORTCUT_TYPE_KEY = "isAppShortcut";
+ private static final String DEEPSHORTCUT_TYPE_KEY = "isDeepShortcut";
private static final String USER_HANDLE_KEY = "userHandle";
// The set of shortcuts that are pending install
@@ -98,19 +102,25 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
Log.d(TAG, "APPS_PENDING_INSTALL: " + strings
+ ", removing packages: " + packageNames);
}
- if (strings != null) {
- Set<String> newStrings = new HashSet<String>(strings);
- Iterator<String> newStringsIter = newStrings.iterator();
- while (newStringsIter.hasNext()) {
- String encoded = newStringsIter.next();
- PendingInstallShortcutInfo info = decode(encoded, context);
- if (info == null || (packageNames.contains(info.getTargetPackage())
- && user.equals(info.user))) {
+ if (Utilities.isEmpty(strings)) {
+ return;
+ }
+ Set<String> newStrings = new HashSet<>(strings);
+ Iterator<String> newStringsIter = newStrings.iterator();
+ while (newStringsIter.hasNext()) {
+ String encoded = newStringsIter.next();
+ try {
+ Decoder decoder = new Decoder(encoded, context);
+ if (packageNames.contains(getIntentPackage(decoder.launcherIntent)) &&
+ user.equals(decoder.user)) {
newStringsIter.remove();
}
+ } catch (JSONException | URISyntaxException e) {
+ Log.d(TAG, "Exception reading shortcut to add: " + e);
+ newStringsIter.remove();
}
- sp.edit().putStringSet(APPS_PENDING_INSTALL, newStrings).apply();
}
+ sp.edit().putStringSet(APPS_PENDING_INSTALL, newStrings).apply();
}
}
@@ -178,7 +188,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
return null;
}
- PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context);
+ PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(
+ data, UserHandleCompat.myUserHandle(), context);
if (info.launchIntent == null || info.label == null) {
if (DBG) Log.e(TAG, "Invalid install shortcut intent");
return null;
@@ -192,6 +203,31 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
return info == null ? null : info.getShortcutInfo();
}
+ public static void queueShortcut(ShortcutInfoCompat info, Context context) {
+ queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, context), context);
+ }
+
+ public static HashSet<ShortcutKey> getPendingShortcuts(Context context) {
+ HashSet<ShortcutKey> result = new HashSet<>();
+
+ Set<String> strings = Utilities.getPrefs(context).getStringSet(APPS_PENDING_INSTALL, null);
+ if (Utilities.isEmpty(strings)) {
+ return result;
+ }
+
+ for (String encoded : strings) {
+ try {
+ Decoder decoder = new Decoder(encoded, context);
+ if (decoder.optBoolean(DEEPSHORTCUT_TYPE_KEY)) {
+ result.add(ShortcutKey.fromIntent(decoder.launcherIntent, decoder.user));
+ }
+ } catch (JSONException | URISyntaxException e) {
+ Log.d(TAG, "Exception reading shortcut to add: " + e);
+ }
+ }
+ return result;
+ }
+
private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) {
// Queue the item up for adding if launcher has not loaded properly yet
LauncherAppState app = LauncherAppState.getInstance();
@@ -239,6 +275,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
private static class PendingInstallShortcutInfo {
final LauncherActivityInfoCompat activityInfo;
+ final ShortcutInfoCompat shortcutInfo;
final Intent data;
final Context mContext;
@@ -249,14 +286,15 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
/**
* Initializes a PendingInstallShortcutInfo received from a different app.
*/
- public PendingInstallShortcutInfo(Intent data, Context context) {
+ public PendingInstallShortcutInfo(Intent data, UserHandleCompat user, Context context) {
this.data = data;
+ this.user = user;
mContext = context;
launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
- user = UserHandleCompat.myUserHandle();
activityInfo = null;
+ shortcutInfo = null;
}
/**
@@ -266,15 +304,30 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
this.data = null;
mContext = context;
activityInfo = info;
+ shortcutInfo = null;
user = info.getUser();
launchIntent = AppInfo.makeLaunchIntent(context, info, user);
label = info.getLabel().toString();
}
+ /**
+ * Initializes a PendingInstallShortcutInfo to represent a launcher target.
+ */
+ public PendingInstallShortcutInfo(ShortcutInfoCompat info, Context context) {
+ this.data = null;
+ shortcutInfo = info;
+ mContext = context;
+ activityInfo = null;
+ user = info.getUserHandle();
+
+ launchIntent = info.makeIntent(context);
+ label = info.getShortLabel().toString();
+ }
+
public String encodeToString() {
- if (activityInfo != null) {
- try {
+ try {
+ if (activityInfo != null) {
// If it a launcher target, we only need component name, and user to
// recreate this.
return new JSONStringer()
@@ -284,30 +337,35 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
.key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
.getSerialNumberForUser(user))
.endObject().toString();
- } catch (JSONException e) {
- Log.d(TAG, "Exception when adding shortcut: " + e);
- return null;
+ } else if (shortcutInfo != null) {
+ // If it a launcher target, we only need component name, and user to
+ // recreate this.
+ return new JSONStringer()
+ .object()
+ .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
+ .key(DEEPSHORTCUT_TYPE_KEY).value(true)
+ .key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
+ .getSerialNumberForUser(user))
+ .endObject().toString();
}
- }
- if (launchIntent.getAction() == null) {
- launchIntent.setAction(Intent.ACTION_VIEW);
- } else if (launchIntent.getAction().equals(Intent.ACTION_MAIN) &&
- launchIntent.getCategories() != null &&
- launchIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
- launchIntent.addFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- }
+ if (launchIntent.getAction() == null) {
+ launchIntent.setAction(Intent.ACTION_VIEW);
+ } else if (launchIntent.getAction().equals(Intent.ACTION_MAIN) &&
+ launchIntent.getCategories() != null &&
+ launchIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
+ launchIntent.addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ }
- // This name is only used for comparisons and notifications, so fall back to activity
- // name if not supplied
- String name = ensureValidName(mContext, launchIntent, label).toString();
- Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
- Intent.ShortcutIconResource iconResource =
- data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
+ // This name is only used for comparisons and notifications, so fall back to activity
+ // name if not supplied
+ String name = ensureValidName(mContext, launchIntent, label).toString();
+ Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
+ Intent.ShortcutIconResource iconResource =
+ data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
- // Only encode the parameters which are supported by the API.
- try {
+ // Only encode the parameters which are supported by the API.
JSONStringer json = new JSONStringer()
.object()
.key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
@@ -326,57 +384,56 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
return json.endObject().toString();
} catch (JSONException e) {
Log.d(TAG, "Exception when adding shortcut: " + e);
+ return null;
}
- return null;
}
public ShortcutInfo getShortcutInfo() {
if (activityInfo != null) {
return new ShortcutInfo(activityInfo, mContext);
+ } else if (shortcutInfo != null) {
+ return new ShortcutInfo(shortcutInfo, mContext);
} else {
return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data);
}
}
- public String getTargetPackage() {
- String packageName = launchIntent.getPackage();
- if (packageName == null) {
- packageName = launchIntent.getComponent() == null ? null :
- launchIntent.getComponent().getPackageName();
- }
- return packageName;
- }
-
public boolean isLauncherActivity() {
return activityInfo != null;
}
}
+ private static String getIntentPackage(Intent intent) {
+ return intent.getComponent() == null
+ ? intent.getPackage() : intent.getComponent().getPackageName();
+ }
+
private static PendingInstallShortcutInfo decode(String encoded, Context context) {
try {
- JSONObject object = (JSONObject) new JSONTokener(encoded).nextValue();
- Intent launcherIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
-
- if (object.optBoolean(APP_SHORTCUT_TYPE_KEY)) {
- // The is an internal launcher target shortcut.
- UserHandleCompat user = UserManagerCompat.getInstance(context)
- .getUserForSerialNumber(object.getLong(USER_HANDLE_KEY));
- if (user == null) {
- return null;
- }
-
+ Decoder decoder = new Decoder(encoded, context);
+ if (decoder.optBoolean(APP_SHORTCUT_TYPE_KEY)) {
LauncherActivityInfoCompat info = LauncherAppsCompat.getInstance(context)
- .resolveActivity(launcherIntent, user);
+ .resolveActivity(decoder.launcherIntent, decoder.user);
return info == null ? null : new PendingInstallShortcutInfo(info, context);
+ } else if (decoder.optBoolean(DEEPSHORTCUT_TYPE_KEY)) {
+ DeepShortcutManager sm = DeepShortcutManager.getInstance(context);
+ List<ShortcutInfoCompat> si = sm.queryForFullDetails(
+ decoder.launcherIntent.getPackage(),
+ Arrays.asList(ShortcutInfoCompat.EXTRA_SHORTCUT_ID), decoder.user);
+ if (si.isEmpty()) {
+ return null;
+ } else {
+ return new PendingInstallShortcutInfo(si.get(0), context);
+ }
}
Intent data = new Intent();
- data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);
- data.putExtra(Intent.EXTRA_SHORTCUT_NAME, object.getString(NAME_KEY));
+ data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, decoder.launcherIntent);
+ data.putExtra(Intent.EXTRA_SHORTCUT_NAME, decoder.getString(NAME_KEY));
- String iconBase64 = object.optString(ICON_KEY);
- String iconResourceName = object.optString(ICON_RESOURCE_NAME_KEY);
- String iconResourcePackageName = object.optString(ICON_RESOURCE_PACKAGE_NAME_KEY);
+ String iconBase64 = decoder.optString(ICON_KEY);
+ String iconResourceName = decoder.optString(ICON_RESOURCE_NAME_KEY);
+ String iconResourcePackageName = decoder.optString(ICON_RESOURCE_PACKAGE_NAME_KEY);
if (iconBase64 != null && !iconBase64.isEmpty()) {
byte[] iconArray = Base64.decode(iconBase64, Base64.DEFAULT);
Bitmap b = BitmapFactory.decodeByteArray(iconArray, 0, iconArray.length);
@@ -389,13 +446,29 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
data.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
}
- return new PendingInstallShortcutInfo(data, context);
+ return new PendingInstallShortcutInfo(data, decoder.user, context);
} catch (JSONException | URISyntaxException e) {
Log.d(TAG, "Exception reading shortcut to add: " + e);
}
return null;
}
+ private static class Decoder extends JSONObject {
+ public final Intent launcherIntent;
+ public final UserHandleCompat user;
+
+ private Decoder(String encoded, Context context) throws JSONException, URISyntaxException {
+ super(encoded);
+ launcherIntent = Intent.parseUri(getString(LAUNCH_INTENT_KEY), 0);
+ user = has(USER_HANDLE_KEY) ? UserManagerCompat.getInstance(context)
+ .getUserForSerialNumber(getLong(USER_HANDLE_KEY))
+ : UserHandleCompat.myUserHandle();
+ if (user == null) {
+ throw new JSONException("Invalid user");
+ }
+ }
+ }
+
/**
* Tries to create a new PendingInstallShortcutInfo which represents the same target,
* but is an app target and not a shortcut.
@@ -441,7 +514,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
for (PendingInstallShortcutInfo pendingInfo : mPendingItems) {
// If the intent specifies a package, make sure the package exists
- String packageName = pendingInfo.getTargetPackage();
+ String packageName = getIntentPackage(pendingInfo.launchIntent);
if (!TextUtils.isEmpty(packageName) && !launcherApps.isPackageEnabledForProfile(
packageName, pendingInfo.user)) {
if (DBG) Log.d(TAG, "Ignoring shortcut for absent package: "
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index c7bb188b3..cc56d439f 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1776,9 +1776,12 @@ public class LauncherModel extends BroadcastReceiver
}
// Unpin shortcuts that don't exist on the workspace.
+ HashSet<ShortcutKey> pendingShortcuts =
+ InstallShortcutReceiver.getPendingShortcuts(context);
for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) {
MutableInt numTimesPinned = sBgDataModel.pinnedShortcutCounts.get(key);
- if (numTimesPinned == null || numTimesPinned.value == 0) {
+ if ((numTimesPinned == null || numTimesPinned.value == 0)
+ && !pendingShortcuts.contains(key)) {
// Shortcut is pinned but doesn't exist on the workspace; unpin it.
shortcutManager.unpinShortcut(key);
}
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 29defdd08..3d5463724 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -15,10 +15,12 @@
*/
package com.android.launcher3.model;
+import android.content.Context;
import android.util.Log;
import android.util.MutableInt;
import com.android.launcher3.FolderInfo;
+import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
@@ -123,9 +125,11 @@ public class BgDataModel {
// Decrement pinned shortcut count
ShortcutKey pinnedShortcut = ShortcutKey.fromShortcutInfo((ShortcutInfo) item);
MutableInt count = pinnedShortcutCounts.get(pinnedShortcut);
- if (count == null || --count.value == 0) {
- DeepShortcutManager.getInstance(LauncherAppState.getInstance().getContext())
- .unpinShortcut(pinnedShortcut);
+ Context context = LauncherAppState.getInstance().getContext();
+ if ((count == null || --count.value == 0)
+ && !InstallShortcutReceiver.getPendingShortcuts(context)
+ .contains(pinnedShortcut)) {
+ DeepShortcutManager.getInstance(context).unpinShortcut(pinnedShortcut);
}
// Fall through.
}