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

Commit 3be633b8 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Adding support for app widgets in the InstallQueue

Bug: 32904959
Change-Id: I0d07a0c59d266493ae30a42579c1fa69b805009e
parent 621e2006
Loading
Loading
Loading
Loading
+75 −9
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.launcher3;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -67,6 +69,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {

    private static final String APP_SHORTCUT_TYPE_KEY = "isAppShortcut";
    private static final String DEEPSHORTCUT_TYPE_KEY = "isDeepShortcut";
    private static final String APP_WIDGET_TYPE_KEY = "isAppWidget";
    private static final String USER_HANDLE_KEY = "userHandle";

    // The set of shortcuts that are pending install
@@ -200,13 +203,17 @@ public class InstallShortcutReceiver extends BroadcastReceiver {

    public static ShortcutInfo fromShortcutIntent(Context context, Intent data) {
        PendingInstallShortcutInfo info = createPendingInfo(context, data);
        return info == null ? null : info.getShortcutInfo();
        return info == null ? null : (ShortcutInfo) info.getItemInfo();
    }

    public static void queueShortcut(ShortcutInfoCompat info, Context context) {
        queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, context), context);
    }

    public static void queueWidget(AppWidgetProviderInfo info, int widgetId, Context context) {
        queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, widgetId, context), context);
    }

    public static HashSet<ShortcutKey> getPendingShortcuts(Context context) {
        HashSet<ShortcutKey> result = new HashSet<>();

@@ -276,6 +283,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {

        final LauncherActivityInfoCompat activityInfo;
        final ShortcutInfoCompat shortcutInfo;
        final AppWidgetProviderInfo providerInfo;

        final Intent data;
        final Context mContext;
@@ -287,25 +295,30 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
         * Initializes a PendingInstallShortcutInfo received from a different app.
         */
        public PendingInstallShortcutInfo(Intent data, UserHandleCompat user, Context context) {
            activityInfo = null;
            shortcutInfo = null;
            providerInfo = null;

            this.data = data;
            this.user = user;
            mContext = context;

            launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
            label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
            activityInfo = null;
            shortcutInfo = null;

        }

        /**
         * Initializes a PendingInstallShortcutInfo to represent a launcher target.
         */
        public PendingInstallShortcutInfo(LauncherActivityInfoCompat info, Context context) {
            this.data = null;
            mContext = context;
            activityInfo = info;
            shortcutInfo = null;
            providerInfo = null;

            data = null;
            user = info.getUser();
            mContext = context;

            launchIntent = AppInfo.makeLaunchIntent(context, info, user);
            label = info.getLabel().toString();
@@ -315,16 +328,36 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
         * Initializes a PendingInstallShortcutInfo to represent a launcher target.
         */
        public PendingInstallShortcutInfo(ShortcutInfoCompat info, Context context) {
            this.data = null;
            activityInfo = null;
            shortcutInfo = info;
            providerInfo = null;

            data = null;
            mContext = context;
            activityInfo = null;
            user = info.getUserHandle();

            launchIntent = info.makeIntent(context);
            label = info.getShortLabel().toString();
        }

        /**
         * Initializes a PendingInstallShortcutInfo to represent a launcher target.
         */
        public PendingInstallShortcutInfo(
                AppWidgetProviderInfo info, int widgetId, Context context) {
            activityInfo = null;
            shortcutInfo = null;
            providerInfo = info;

            data = null;
            mContext = context;
            user = UserHandleCompat.fromUser(info.getProfile());

            launchIntent = new Intent().setComponent(info.provider)
                    .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
            label = info.label;
        }

        public String encodeToString() {
            try {
                if (activityInfo != null) {
@@ -347,6 +380,16 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
                            .key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
                                    .getSerialNumberForUser(user))
                            .endObject().toString();
                } else if (providerInfo != 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(APP_WIDGET_TYPE_KEY).value(true)
                            .key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
                                    .getSerialNumberForUser(user))
                            .endObject().toString();
                }

                if (launchIntent.getAction() == null) {
@@ -388,11 +431,24 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
            }
        }

        public ShortcutInfo getShortcutInfo() {
        public ItemInfo getItemInfo() {
            if (activityInfo != null) {
                return new ShortcutInfo(activityInfo, mContext);
            } else if (shortcutInfo != null) {
                return new ShortcutInfo(shortcutInfo, mContext);
            } else if (providerInfo != null) {
                LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo
                        .fromProviderInfo(mContext, providerInfo);
                LauncherAppWidgetInfo widgetInfo = new LauncherAppWidgetInfo(
                        launchIntent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0),
                        info.provider);
                InvariantDeviceProfile idp = LauncherAppState.getInstance()
                        .getInvariantDeviceProfile();
                widgetInfo.minSpanX = info.minSpanX;
                widgetInfo.minSpanY = info.minSpanY;
                widgetInfo.spanX = Math.min(info.spanX, idp.numColumns);
                widgetInfo.spanY = Math.min(info.spanY, idp.numRows);
                return widgetInfo;
            } else {
                return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data);
            }
@@ -425,6 +481,16 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
                } else {
                    return new PendingInstallShortcutInfo(si.get(0), context);
                }
            } else if (decoder.optBoolean(APP_WIDGET_TYPE_KEY)) {
                int widgetId = decoder.launcherIntent
                        .getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
                AppWidgetProviderInfo info = AppWidgetManager.getInstance(context)
                        .getAppWidgetInfo(widgetId);
                if (info == null || !info.provider.equals(decoder.launcherIntent.getComponent()) ||
                        !info.getProfile().equals(decoder.user.getUser())) {
                    return null;
                }
                return new PendingInstallShortcutInfo(info, widgetId, context);
            }

            Intent data = new Intent();
@@ -523,7 +589,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
                }

                // Generate a shortcut info to add into the model
                installQueue.add(pendingInfo.getShortcutInfo());
                installQueue.add(pendingInfo.getItemInfo());
            }
            return installQueue;
        }
+29 −11
Original line number Diff line number Diff line
@@ -3295,25 +3295,25 @@ public class Launcher extends Activity
     * Implementation of the method from LauncherModel.Callbacks.
     */
    @Override
    public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,
    public void bindItems(final ArrayList<ItemInfo> items, final int start, final int end,
                          final boolean forceAnimateIcons) {
        Runnable r = new Runnable() {
            public void run() {
                bindItems(shortcuts, start, end, forceAnimateIcons);
                bindItems(items, start, end, forceAnimateIcons);
            }
        };
        if (waitUntilResume(r)) {
            return;
        }

        // Get the list of added shortcuts and intersect them with the set of shortcuts here
        // Get the list of added items and intersect them with the set of items here
        final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
        final Collection<Animator> bounceAnims = new ArrayList<Animator>();
        final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();
        Workspace workspace = mWorkspace;
        long newShortcutsScreenId = -1;
        long newItemsScreenId = -1;
        for (int i = start; i < end; i++) {
            final ItemInfo item = shortcuts.get(i);
            final ItemInfo item = items.get(i);

            // Short circuit if we are loading dock items for a configuration which has no dock
            if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
@@ -3325,15 +3325,33 @@ public class Launcher extends Activity
            switch (item.itemType) {
                case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
                case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
                case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: {
                    ShortcutInfo info = (ShortcutInfo) item;
                    view = createShortcut(info);
                    break;
                case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
                }
                case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: {
                    view = FolderIcon.fromXml(R.layout.folder_icon, this,
                            (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
                            (FolderInfo) item, mIconCache);
                    break;
                }
                case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: {
                    LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
                    if (mIsSafeModeEnabled) {
                        view = new PendingAppWidgetHostView(this, info, mIconCache, true);
                    } else {
                        LauncherAppWidgetProviderInfo providerInfo =
                                mAppWidgetManager.getLauncherAppWidgetInfo(info.appWidgetId);
                        if (providerInfo == null) {
                            deleteWidgetInfo(info);
                            continue;
                        }
                        view = mAppWidgetHost.createView(this, info.appWidgetId, providerInfo);
                    }
                    prepareAppWidget((AppWidgetHostView) view, info);
                    break;
                }
                default:
                    throw new RuntimeException("Invalid Item Type");
            }
@@ -3364,22 +3382,22 @@ public class Launcher extends Activity
                view.setScaleX(0f);
                view.setScaleY(0f);
                bounceAnims.add(createNewAppBounceAnimation(view, i));
                newShortcutsScreenId = item.screenId;
                newItemsScreenId = item.screenId;
            }
        }

        if (animateIcons) {
            // Animate to the correct page
            if (newShortcutsScreenId > -1) {
            if (newItemsScreenId > -1) {
                long currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());
                final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newShortcutsScreenId);
                final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newItemsScreenId);
                final Runnable startBounceAnimRunnable = new Runnable() {
                    public void run() {
                        anim.playTogether(bounceAnims);
                        anim.start();
                    }
                };
                if (newShortcutsScreenId != currentScreenId) {
                if (newItemsScreenId != currentScreenId) {
                    // We post the animation slightly delayed to prevent slowdowns
                    // when we are loading right after we return to launcher.
                    mWorkspace.postDelayed(new Runnable() {
+12 −10
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.launcher3.FolderInfo;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherModel.Callbacks;
@@ -60,8 +61,8 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
        }
        Context context = app.getContext();

        final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>();
        final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
        final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
        final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<>();

        // Get the list of workspace screens.  We need to append to this list and
        // can not use sBgWorkspaceScreens because loadWorkspace() may not have been
@@ -77,13 +78,14 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
                }

                // Find appropriate space for the item.
                Pair<Long, int[]> coords = findSpaceForItem(
                        app, dataModel, workspaceScreens, addedWorkspaceScreensFinal, 1, 1);
                Pair<Long, int[]> coords = findSpaceForItem(app, dataModel, workspaceScreens,
                        addedWorkspaceScreensFinal, item.spanX, item.spanY);
                long screenId = coords.first;
                int[] cordinates = coords.second;

                ItemInfo itemInfo;
                if (item instanceof ShortcutInfo || item instanceof FolderInfo) {
                if (item instanceof ShortcutInfo || item instanceof FolderInfo ||
                        item instanceof LauncherAppWidgetInfo) {
                    itemInfo = item;
                } else if (item instanceof AppInfo) {
                    itemInfo = ((AppInfo) item).makeShortcut();
@@ -95,23 +97,23 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask {
                addItemToDatabase(context, itemInfo, screenId, cordinates);

                // Save the ShortcutInfo for binding in the workspace
                addedShortcutsFinal.add(itemInfo);
                addedItemsFinal.add(itemInfo);
            }
        }

        // Update the workspace screens
        updateScreens(context, workspaceScreens);

        if (!addedShortcutsFinal.isEmpty()) {
        if (!addedItemsFinal.isEmpty()) {
            scheduleCallbackTask(new CallbackTask() {
                @Override
                public void execute(Callbacks callbacks) {
                    final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>();
                    final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>();
                    if (!addedShortcutsFinal.isEmpty()) {
                        ItemInfo info = addedShortcutsFinal.get(addedShortcutsFinal.size() - 1);
                    if (!addedItemsFinal.isEmpty()) {
                        ItemInfo info = addedItemsFinal.get(addedItemsFinal.size() - 1);
                        long lastScreenId = info.screenId;
                        for (ItemInfo i : addedShortcutsFinal) {
                        for (ItemInfo i : addedItemsFinal) {
                            if (i.screenId == lastScreenId) {
                                addAnimated.add(i);
                            } else {