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

Commit e5bb705f authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Homescreen migration from a larger grid to a smaller grid.

Adding support for restoring from a larger device, if the grid size
difference is not more that 1.
During restore add all the items in the DB, and run a one-time migration
the next time launcher starts.

The migration strategy is defined in ShrinkWorkspaceTask.java which involves
resizing, moving and removing some items.

Change-Id: I6ee411f6db5bf0152b527e16146a88c56dec2d97
parent e40e77b3
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.launcher3;

import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -147,7 +146,7 @@ public class LauncherAppState {
        sLauncherProvider = new WeakReference<LauncherProvider>(provider);
    }

    static LauncherProvider getLauncherProvider() {
    public static LauncherProvider getLauncherProvider() {
        return sLauncherProvider.get();
    }

+12 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Parcel;
@@ -110,4 +111,15 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo {
            mMinSpanY = minResizeSpan[1];
        }
    }

    public Point getMinSpans(InvariantDeviceProfile idp, Context context) {
        // Calculate the spans corresponding to any one of the orientations as it should not change
        // based on orientation.
        // TODO: Use the max of both profiles
        int[] minSpans = CellLayout.rectToCell(
                idp.portraitProfile, context, minResizeWidth, minResizeHeight, null);
        return new Point(
                (resizeMode & RESIZE_HORIZONTAL) != 0 ? minSpans[0] : -1,
                        (resizeMode & RESIZE_VERTICAL) != 0 ? minSpans[1] : -1);
    }
 }
+9 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import android.database.Cursor;
import android.os.ParcelFileDescriptor;
import android.util.Log;

import com.android.launcher3.model.MigrateFromRestoreTask;

import java.io.IOException;

public class LauncherBackupAgentHelper extends BackupAgentHelper {
@@ -96,6 +98,13 @@ public class LauncherBackupAgentHelper extends BackupAgentHelper {
                LauncherAppState.getLauncherProvider().updateFolderItemsRank();
            }

            if (mHelper.shouldAttemptWorkspaceMigration()) {
                MigrateFromRestoreTask.markForMigration(getApplicationContext(),
                        (int) mHelper.migrationCompatibleProfileData.desktopCols,
                        (int) mHelper.migrationCompatibleProfileData.desktopRows,
                        mHelper.widgetSizes);
            }

            LauncherAppState.getLauncherProvider().convertShortcutsToLauncherActivities();
        } else {
            if (VERBOSE) Log.v(TAG, "Nothing was restored, clearing DB");
+39 −15
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
@@ -152,6 +153,9 @@ public class LauncherBackupHelper implements BackupHelper {
    private DeviceProfieData mDeviceProfileData;
    private InvariantDeviceProfile mIdp;

    DeviceProfieData migrationCompatibleProfileData;
    HashSet<String> widgetSizes = new HashSet<>();

    boolean restoreSuccessful;
    int restoredBackupVersion = 1;

@@ -288,9 +292,9 @@ public class LauncherBackupHelper implements BackupHelper {
            return true;
        }

        boolean isHotsetCompatible = false;
        boolean isHotseatCompatible = false;
        if (currentProfile.allappsRank >= oldProfile.hotseatCount) {
            isHotsetCompatible = true;
            isHotseatCompatible = true;
            mHotseatShift = 0;
        }

@@ -298,12 +302,28 @@ public class LauncherBackupHelper implements BackupHelper {
                && ((currentProfile.hotseatCount - currentProfile.allappsRank) >=
                        (oldProfile.hotseatCount - oldProfile.allappsRank))) {
            // There is enough space on both sides of the hotseat.
            isHotsetCompatible = true;
            isHotseatCompatible = true;
            mHotseatShift = currentProfile.allappsRank - oldProfile.allappsRank;
        }

        return isHotsetCompatible && (currentProfile.desktopCols >= oldProfile.desktopCols)
                && (currentProfile.desktopRows >= oldProfile.desktopRows);
        if (!isHotseatCompatible) {
            return false;
        }
        if ((currentProfile.desktopCols >= oldProfile.desktopCols)
                && (currentProfile.desktopRows >= oldProfile.desktopRows)) {
            return true;
        }

        if ((oldProfile.desktopCols - currentProfile.desktopCols <= 1) &&
                (oldProfile.desktopRows - currentProfile.desktopRows <= 1)) {
            // Allow desktop migration when row and/or column count contracts by 1.

            migrationCompatibleProfileData = initDeviceProfileData(mIdp);
            migrationCompatibleProfileData.desktopCols = oldProfile.desktopCols;
            migrationCompatibleProfileData.desktopRows = oldProfile.desktopRows;
            return true;
        }
        return false;
    }

    /**
@@ -706,7 +726,8 @@ public class LauncherBackupHelper implements BackupHelper {
            }
        }

        // future site of widget table mutation
        // Cache widget min sizes incase migration is required.
        widgetSizes.add(widget.provider + "#" + widget.minSpanX + "," + widget.minSpanY);
    }

    /** create a new key, with an integer ID.
@@ -904,7 +925,11 @@ public class LauncherBackupHelper implements BackupHelper {
                UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
        values.put(LauncherSettings.Favorites.PROFILE_ID, userSerialNumber);

        DeviceProfieData currentProfile = mDeviceProfileData;
        // If we will attempt grid resize, use the original profile to validate grid size, as
        // anything which fits in the original grid should fit in the current grid after
        // grid migration.
        DeviceProfieData currentProfile = migrationCompatibleProfileData == null
                ? mDeviceProfileData : migrationCompatibleProfileData;

        if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
            if (!TextUtils.isEmpty(favorite.appWidgetProvider)) {
@@ -996,14 +1021,9 @@ public class LauncherBackupHelper implements BackupHelper {
            widget.icon.dpi = dpi;
        }

        // Calculate the spans corresponding to any one of the orientations as it should not change
        // based on orientation.
        int[] minSpans = CellLayout.rectToCell(
                mIdp.portraitProfile, mContext, info.minResizeWidth, info.minResizeHeight, null);
        widget.minSpanX = (info.resizeMode & LauncherAppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0
                ? minSpans[0] : -1;
        widget.minSpanY = (info.resizeMode & LauncherAppWidgetProviderInfo.RESIZE_VERTICAL) != 0
                ? minSpans[1] : -1;
        Point spans = info.getMinSpans(mIdp, mContext);
        widget.minSpanX = spans.x;
        widget.minSpanY = spans.y;

        return widget;
    }
@@ -1188,6 +1208,10 @@ public class LauncherBackupHelper implements BackupHelper {
        }
    }

    public boolean shouldAttemptWorkspaceMigration() {
        return migrationCompatibleProfileData != null;
    }

    /**
     * A class to check if an activity can handle one of the intents from a list of
     * predefined intents.
+20 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
@@ -55,6 +56,7 @@ import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.model.MigrateFromRestoreTask;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.CursorIconInfo;
@@ -1133,7 +1135,7 @@ public class LauncherModel extends BroadcastReceiver
     * Update the order of the workspace screens in the database. The array list contains
     * a list of screen ids in the order that they should appear.
     */
    void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) {
    public void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) {
        final ArrayList<Long> screensCopy = new ArrayList<Long>(screens);
        final ContentResolver cr = context.getContentResolver();
        final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
@@ -1411,7 +1413,7 @@ public class LauncherModel extends BroadcastReceiver
    /**
     * Loads the workspace screen ids in an ordered list.
     */
    @Thunk static ArrayList<Long> loadWorkspaceScreensDb(Context context) {
    public static ArrayList<Long> loadWorkspaceScreensDb(Context context) {
        final ContentResolver contentResolver = context.getContentResolver();
        final Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI;

@@ -1757,6 +1759,22 @@ public class LauncherModel extends BroadcastReceiver
            int countX = (int) profile.numColumns;
            int countY = (int) profile.numRows;


            if (MigrateFromRestoreTask.shouldRunTask(mContext)) {
                try {
                    MigrateFromRestoreTask task = new MigrateFromRestoreTask(mContext);
                    // Clear the flags before starting the task, so that we do not run the task
                    // again, in case there was an uncaught error.
                    MigrateFromRestoreTask.clearFlags(mContext);
                    task.execute();
                } catch (Exception e) {
                    Log.e(TAG, "Error during grid migration", e);

                    // Clear workspace.
                    mFlags = mFlags | LOADER_FLAG_CLEAR_WORKSPACE;
                }
            }

            if ((mFlags & LOADER_FLAG_CLEAR_WORKSPACE) != 0) {
                Launcher.addDumpLog(TAG, "loadWorkspace: resetting launcher database", true);
                LauncherAppState.getLauncherProvider().deleteDatabase();
Loading