diff --git a/src/ch/deletescape/lawnchair/sesame/SesameDataProvider.kt b/src/ch/deletescape/lawnchair/sesame/SesameDataProvider.kt index f6dc954bac..509711d25a 100644 --- a/src/ch/deletescape/lawnchair/sesame/SesameDataProvider.kt +++ b/src/ch/deletescape/lawnchair/sesame/SesameDataProvider.kt @@ -9,7 +9,7 @@ import ch.deletescape.lawnchair.useApplicationContext import ch.deletescape.lawnchair.util.SingletonHolder class SesameDataProvider private constructor(private val context: Context) { - private val defaultCount = 10 + private val defaultCount = 20 fun recentlyUsedShortcuts(count: Int = defaultCount): List { return query(SesameProvider.RECENTLY_USED, count) diff --git a/src/ch/deletescape/lawnchair/sesame/SesameShortcutInfoCompat.java b/src/ch/deletescape/lawnchair/sesame/SesameShortcutInfoCompat.java new file mode 100644 index 0000000000..63a5810a5f --- /dev/null +++ b/src/ch/deletescape/lawnchair/sesame/SesameShortcutInfoCompat.java @@ -0,0 +1,150 @@ +package ch.deletescape.lawnchair.sesame; + +import android.annotation.TargetApi; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.LauncherApps; +import android.content.pm.PackageManager; +import android.content.pm.ShortcutInfo; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Process; +import android.os.UserHandle; +import android.provider.MediaStore; +import android.util.Log; + +import com.android.launcher3.FastBitmapDrawable; +import com.android.launcher3.R; +import com.android.launcher3.shortcuts.ShortcutInfoCompat; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; + +import ch.deletescape.lawnchair.sesame.SesameDataProvider; + +public class SesameShortcutInfoCompat extends ShortcutInfoCompat { + + private SesameDataProvider.SesameResult sesameResult; + + public SesameShortcutInfoCompat(SesameDataProvider.SesameResult sesameResult) { + super(null); + this.sesameResult = sesameResult; + } + + @TargetApi(Build.VERSION_CODES.N) + public Intent makeIntent() { + try { + return Intent + // TODO: use #getIntent() to relay through sesame once we get access to that + .parseUri(sesameResult.getDirectIntent().toString(),0) + .setPackage(getPackage()) + .putExtra("ch.deletescape.lawnchair.SESAME_MARKER", true) + .putExtra(ShortcutInfoCompat.EXTRA_SHORTCUT_ID, getId()); + } catch (URISyntaxException e) { + return null; + } + } + + public Drawable getIcon(Context context, int density) { + if(sesameResult.getIconUri() != null){ + String scheme = sesameResult.getIconUri().getScheme(); + if(scheme != null && scheme.startsWith("http")){ + try { + Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(sesameResult.getIconUri().toString()).getContent()); + if (bitmap != null) return new FastBitmapDrawable(bitmap); + } catch (IOException ignored) {} + } else { + try { + Bitmap bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(sesameResult.getIconUri())); + if (bitmap != null) return new FastBitmapDrawable(bitmap); + } catch (FileNotFoundException ignored) {} + } + } + if (sesameResult.getComponentName() != null){ + try { + return context.getPackageManager().getActivityIcon(sesameResult.getComponentName()); + } catch (PackageManager.NameNotFoundException ignored) {} + } + if (sesameResult.getPackageName() != null) { + try { + return context.getPackageManager().getApplicationIcon(sesameResult.getPackageName()); + } catch (PackageManager.NameNotFoundException ignored) {} + } + return context.getResources().getDrawableForDensity(R.drawable.ic_default_shortcut, density); + } + + public String getPackage() { + if(sesameResult.getPackageName() != null){ + return sesameResult.getPackageName(); + } else { + return "ninja.sesame.app.edge"; + } + } + + public String getId() { + return sesameResult.getUri(); + } + + public CharSequence getShortLabel() { + return sesameResult.getDisplayLabel(); + } + + public CharSequence getLongLabel() { + return sesameResult.getDisplayLabel(); + } + + public long getLastChangedTimestamp() { + return System.currentTimeMillis(); + } + + public ComponentName getActivity() { + if(sesameResult.getComponentName() != null) { + return sesameResult.getComponentName(); + } else { + return new ComponentName(getPackage(), getId()); + } + } + + public UserHandle getUserHandle() { + return Process.myUserHandle(); + } + + public boolean hasKeyFieldsOnly() { + return true; + } + + public boolean isPinned() { + return false; + } + + public boolean isDeclaredInManifest() { + return false; + } + + public boolean isEnabled() { + return true; + } + + public boolean isDynamic() { + return true; + } + + public int getRank() { + return 1; + } + + public CharSequence getDisabledMessage() { + return ""; + } + + @Override + public String toString() { + return ""; + } +} diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java index 83eb178052..162742cfae 100644 --- a/src/com/android/launcher3/BaseDraggingActivity.java +++ b/src/com/android/launcher3/BaseDraggingActivity.java @@ -202,7 +202,9 @@ public abstract class BaseDraggingActivity extends BaseActivity StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll() .penaltyLog().build()); - if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { + if (intent.hasExtra("ch.deletescape.lawnchair.SESAME_MARKER")) { + startActivity(intent, optsBundle); + } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { String id = ((ShortcutInfo) info).getDeepShortcutId(); String packageName = intent.getPackage(); DeepShortcutManager.getInstance(this).startShortcut( diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java index 6e37b8433d..9f1ab3093f 100644 --- a/src/com/android/launcher3/popup/PopupDataProvider.java +++ b/src/com/android/launcher3/popup/PopupDataProvider.java @@ -46,6 +46,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import ch.deletescape.lawnchair.sesame.SesameDataProvider; + /** * Provides data for the popup menu that appears after long-clicking on apps. */ @@ -172,19 +174,22 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan if (component == null) { return Collections.EMPTY_LIST; } - + List ids = new ArrayList<>(); if (!Utilities.ATLEAST_NOUGAT_MR1) { - List ids = new ArrayList<>(); for (ShortcutInfoCompat compat : DeepShortcutManagerBackport.getForPackage(mLauncher, (LauncherApps) mLauncher.getSystemService(Context.LAUNCHER_APPS_SERVICE), info.getTargetComponent(), info.getTargetComponent().getPackageName())) { ids.add(compat.getId()); } - return ids; + } else { + List tmp = mDeepShortcutMap.get(new ComponentKey(component, info.user)); + if(tmp != null) ids.addAll(tmp); } - List ids = mDeepShortcutMap.get(new ComponentKey(component, info.user)); - return ids == null ? Collections.EMPTY_LIST : ids; + for(SesameDataProvider.SesameResult result : SesameDataProvider.Companion.getInstance(mLauncher).queryShortcutsForPackage(info.getTargetComponent().getPackageName())){ + ids.add(result.getUri()); + } + return ids; } public BadgeInfo getBadgeInfoForItem(ItemInfo info) { diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java index 0b28c5d8cc..b66abc115e 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java @@ -27,16 +27,19 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.util.Log; -import ch.deletescape.lawnchair.override.CustomInfoProvider; + import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherSettings; import com.android.launcher3.Utilities; import com.android.launcher3.util.ComponentKey; import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import ch.deletescape.lawnchair.override.CustomInfoProvider; +import ch.deletescape.lawnchair.sesame.SesameDataProvider; +import ch.deletescape.lawnchair.sesame.SesameShortcutInfoCompat; + /** * Performs operations related to deep shortcuts, such as querying for them, pinning them, etc. */ @@ -106,8 +109,7 @@ public class DeepShortcutManager { */ public List queryForShortcutsContainer(ComponentName activity, List ids, UserHandle user) { - return query(ShortcutQuery.FLAG_MATCH_MANIFEST | ShortcutQuery.FLAG_MATCH_DYNAMIC, - activity.getPackageName(), activity, ids, user); + return query(ShortcutQuery.FLAG_MATCH_MANIFEST | ShortcutQuery.FLAG_MATCH_DYNAMIC, activity.getPackageName(), activity, ids, user); } /** @@ -169,7 +171,9 @@ public class DeepShortcutManager { @TargetApi(25) public Drawable getShortcutIconDrawable(ShortcutInfoCompat shortcutInfo, int density) { - if (Utilities.ATLEAST_NOUGAT_MR1) { + if (shortcutInfo instanceof SesameShortcutInfoCompat){ + return ((SesameShortcutInfoCompat) shortcutInfo).getIcon(mContext, density); + } else if (Utilities.ATLEAST_NOUGAT_MR1) { try { Drawable icon = mLauncherApps.getShortcutIconDrawable( shortcutInfo.getShortcutInfo(), density); @@ -219,6 +223,12 @@ public class DeepShortcutManager { @TargetApi(25) private List query(int flags, String packageName, ComponentName activity, List shortcutIds, UserHandle user) { + List shortcutInfoCompats = new ArrayList<>(); + SesameDataProvider provider = SesameDataProvider.Companion.getInstance(mContext); + List results = provider.queryShortcutsForPackage(packageName); + for (SesameDataProvider.SesameResult result : results) { + shortcutInfoCompats.add( new SesameShortcutInfoCompat(result)); + } if (Utilities.ATLEAST_NOUGAT_MR1) { ShortcutQuery q = new ShortcutQuery(); q.setQueryFlags(flags); @@ -235,17 +245,15 @@ public class DeepShortcutManager { Log.e(TAG, "Failed to query for shortcuts", e); mWasLastCallSuccess = false; } - if (shortcutInfos == null) { - return Collections.EMPTY_LIST; + if (shortcutInfos != null) { + for (ShortcutInfo shortcutInfo : shortcutInfos) { + shortcutInfoCompats.add(new ShortcutInfoCompat(shortcutInfo)); + } } - List shortcutInfoCompats = new ArrayList<>(shortcutInfos.size()); - for (ShortcutInfo shortcutInfo : shortcutInfos) { - shortcutInfoCompats.add(new ShortcutInfoCompat(shortcutInfo)); - } - return shortcutInfoCompats; } else { - return DeepShortcutManagerBackport.getForPackage(mContext, mLauncherApps, activity, packageName); + shortcutInfoCompats.addAll(DeepShortcutManagerBackport.getForPackage(mContext, mLauncherApps, activity, packageName)); } + return shortcutInfoCompats; } @TargetApi(25)