Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b037789 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Deduping shortcuts to app-shortcuts if they have a valid intent

> Only deduping shortcuts for the primary user as custom shortcuts
for secondary users is not supported.

Change-Id: If129dee64a395602006ebb996d4b09b93b89084f
parent 85e3d4cc
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
@@ -147,6 +148,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {

        if (DBG) Log.d(TAG, "Got INSTALL_SHORTCUT: " + data.toUri(0));
        PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context);
        info = convertToLauncherActivityIfPossible(info);

        queuePendingShortcutInfo(info, context);
    }
@@ -373,6 +375,10 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
            }
            return packageName;
        }

        public boolean isLuncherActivity() {
            return activityInfo != null;
        }
    }

    private static PendingInstallShortcutInfo decode(String encoded, Context context) {
@@ -420,4 +426,40 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
        }
        return null;
    }

    /**
     * Tries to create a new PendingInstallShortcutInfo which represents the same target,
     * but is an app target and not a shortcut.
     * @return the newly created info or the original one.
     */
    private static PendingInstallShortcutInfo convertToLauncherActivityIfPossible(
            PendingInstallShortcutInfo original) {
        if (original.isLuncherActivity()) {
            // Already an activity target
            return original;
        }
        if (isValidShortcutLaunchIntent(original.launchIntent)
                || !original.user.equals(UserHandleCompat.myUserHandle())) {
            // We can only convert shortcuts which point to a main activity in the current user.
            return original;
        }

        PackageManager pm = original.mContext.getPackageManager();
        ResolveInfo info = pm.resolveActivity(original.launchIntent, 0);

        if (info == null) {
            return original;
        }

        // Ignore any conflicts in the label name, as that can change based on locale.
        LauncherActivityInfoCompat launcherInfo = LauncherActivityInfoCompat
                .fromResolveInfo(info, original.mContext);
        return new PendingInstallShortcutInfo(launcherInfo, original.mContext);
    }

    public static boolean isLauncherActivity(Intent intent, Context context) {
        Intent data = new Intent().putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
        PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context);
        return convertToLauncherActivityIfPossible(info).isLuncherActivity();
    }
}
+62 −3
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.sqlite.SQLiteStatement;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -63,7 +64,7 @@ public class LauncherProvider extends ContentProvider {
    private static final String TAG = "Launcher.LauncherProvider";
    private static final boolean LOGD = false;

    private static final int DATABASE_VERSION = 23;
    private static final int DATABASE_VERSION = 24;

    static final String OLD_AUTHORITY = "com.android.launcher2.settings";
    static final String AUTHORITY = ProviderConfig.AUTHORITY;
@@ -617,7 +618,9 @@ public class LauncherProvider extends ContentProvider {
                        break;
                    }
                }
                case 23: {
                case 23:
                    convertShortcutsToLauncherActivities(db);
                case 24: {
                    // DB Upgraded successfully
                    return;
                }
@@ -636,7 +639,6 @@ public class LauncherProvider extends ContentProvider {
            createEmptyDB(db);
        }


        /**
         * Clears all the data for a fresh start.
         */
@@ -646,6 +648,63 @@ public class LauncherProvider extends ContentProvider {
            onCreate(db);
        }

        /**
         * Replaces all shortcuts of type {@link Favorites#ITEM_TYPE_SHORTCUT} which have a valid
         * launcher activity target with {@link Favorites#ITEM_TYPE_APPLICATION}.
         */
        private void convertShortcutsToLauncherActivities(SQLiteDatabase db) {
            db.beginTransaction();
            Cursor c = null;
            SQLiteStatement updateStmt = null;

            try {
                // Only consider the primary user as other users can't have a shortcut.
                long userSerial = UserManagerCompat.getInstance(mContext)
                        .getSerialNumberForUser(UserHandleCompat.myUserHandle());
                c = db.query(TABLE_FAVORITES, new String[] {
                        Favorites._ID,
                        Favorites.INTENT,
                    }, "itemType=" + Favorites.ITEM_TYPE_SHORTCUT + " AND profileId=" + userSerial,
                    null, null, null, null);

                updateStmt = db.compileStatement("UPDATE favorites SET itemType="
                        + Favorites.ITEM_TYPE_APPLICATION + " WHERE _id=?");

                final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
                final int intentIndex = c.getColumnIndexOrThrow(Favorites.INTENT);

                while (c.moveToNext()) {
                    String intentDescription = c.getString(intentIndex);
                    Intent intent;
                    try {
                        intent = Intent.parseUri(intentDescription, 0);
                    } catch (URISyntaxException e) {
                        Log.e(TAG, "Unable to parse intent", e);
                        continue;
                    }

                    if (!InstallShortcutReceiver.isLauncherActivity(intent, mContext)) {
                        continue;
                    }

                    long id = c.getLong(idIndex);
                    updateStmt.bindLong(1, id);
                    updateStmt.execute();
                }
                db.setTransactionSuccessful();
            } catch (SQLException ex) {
                Log.w(TAG, "Error deduping shortcuts", ex);
            } finally {
                db.endTransaction();
                if (c != null) {
                    c.close();
                }
                if (updateStmt != null) {
                    updateStmt.close();
                }
            }
        }

        /**
         * Recreates workspace table and migrates data to the new table.
         */
+9 −0
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@
package com.android.launcher3.compat;

import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;

public abstract class LauncherActivityInfoCompat {
@@ -32,4 +34,11 @@ public abstract class LauncherActivityInfoCompat {
    public abstract ApplicationInfo getApplicationInfo();
    public abstract long getFirstInstallTime();
    public abstract Drawable getBadgedIcon(int density);

    /**
     * Creates a LauncherActivityInfoCompat for the primary user.
     */
    public static LauncherActivityInfoCompat fromResolveInfo(ResolveInfo info, Context context) {
        return new LauncherActivityInfoCompatV16(context, info);
    }
}