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

Commit 24b449d5 authored by Tracy Zhou's avatar Tracy Zhou Committed by Android (Google) Code Review
Browse files

Merge "The new grid migration algorithm" into ub-launcher3-master

parents 61c14cb1 f601872a
Loading
Loading
Loading
Loading
+155 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3.model;

import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherSettings.Favorites.TMP_CONTENT_URI;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import static com.android.launcher3.util.LauncherModelHelper.APP_ICON;
import static com.android.launcher3.util.LauncherModelHelper.DESKTOP;
import static com.android.launcher3.util.LauncherModelHelper.HOTSEAT;
import static com.android.launcher3.util.LauncherModelHelper.SHORTCUT;
import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Point;
import android.os.Process;

import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.LauncherModelHelper;
import com.android.launcher3.util.LauncherRoboTestRunner;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;

import java.util.HashSet;

/** Unit tests for {@link GridSizeMigrationTaskV2} */
@RunWith(LauncherRoboTestRunner.class)
public class GridSizeMigrationTaskV2Test {

    private LauncherModelHelper mModelHelper;
    private Context mContext;
    private SQLiteDatabase mDb;

    private HashSet<String> mValidPackages;
    private InvariantDeviceProfile mIdp;

    @Before
    public void setUp() {
        mModelHelper = new LauncherModelHelper();
        mContext = RuntimeEnvironment.application;
        mDb = mModelHelper.provider.getDb();

        mValidPackages = new HashSet<>();
        mValidPackages.add(TEST_PACKAGE);
        mIdp = InvariantDeviceProfile.INSTANCE.get(mContext);

        long userSerial = UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
                Process.myUserHandle());
        dropTable(mDb, LauncherSettings.Favorites.TMP_TABLE);
        LauncherSettings.Favorites.addTableToDb(mDb, userSerial, false,
                LauncherSettings.Favorites.TMP_TABLE);
    }

    @Test
    public void testMigration() {
        final String testPackage1 = "com.android.launcher3.validpackage1";
        final String testPackage2 = "com.android.launcher3.validpackage2";
        final String testPackage3 = "com.android.launcher3.validpackage3";
        final String testPackage4 = "com.android.launcher3.validpackage4";
        final String testPackage5 = "com.android.launcher3.validpackage5";
        final String testPackage7 = "com.android.launcher3.validpackage7";

        mValidPackages.add(testPackage1);
        mValidPackages.add(testPackage2);
        mValidPackages.add(testPackage3);
        mValidPackages.add(testPackage4);
        mValidPackages.add(testPackage5);
        mValidPackages.add(testPackage7);

        int[] srcHotseatItems = {
                mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
                mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
                -1,
                mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
                mModelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
        };
        mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage5, 5, TMP_CONTENT_URI);

        int[] destHotseatItems = {
                -1,
                mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2),
                -1,
        };
        mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage7);

        mIdp.numHotseatIcons = 3;
        mIdp.numColumns = 3;
        mIdp.numRows = 3;
        GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
                LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages, 5);
        GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
                LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages, 3);
        GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
                destReader, 3, new Point(mIdp.numColumns, mIdp.numRows));
        task.migrate();

        Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
                new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
                "container=" + CONTAINER_HOTSEAT, null, null, null);
        assertEquals(c.getCount(), 3);
        int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
        int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
        c.moveToNext();
        assertEquals(c.getInt(screenIndex), 1);
        assertTrue(c.getString(intentIndex).contains(testPackage2));
        c.moveToNext();
        assertEquals(c.getInt(screenIndex), 0);
        assertTrue(c.getString(intentIndex).contains(testPackage1));
        c.moveToNext();
        assertEquals(c.getInt(screenIndex), 2);
        assertTrue(c.getString(intentIndex).contains(testPackage3));
        c.close();

        c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
                new String[]{LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
                        LauncherSettings.Favorites.INTENT},
                "container=" + CONTAINER_DESKTOP, null, null, null);
        assertEquals(c.getCount(), 2);
        intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
        int cellXIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLX);
        int cellYIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLY);

        c.moveToNext();
        assertTrue(c.getString(intentIndex).contains(testPackage7));
        c.moveToNext();
        assertTrue(c.getString(intentIndex).contains(testPackage5));
        assertEquals(c.getInt(cellXIndex), 0);
        assertEquals(c.getInt(cellYIndex), 2);
    }
}
+26 −5
Original line number Diff line number Diff line
@@ -230,7 +230,21 @@ public class LauncherModelHelper {
    }

    public int addItem(int type, int screen, int container, int x, int y) {
        return addItem(type, screen, container, x, y, mDefaultProfileId);
        return addItem(type, screen, container, x, y, mDefaultProfileId, TEST_PACKAGE);
    }

    public int addItem(int type, int screen, int container, int x, int y, long profileId) {
        return addItem(type, screen, container, x, y, profileId, TEST_PACKAGE);
    }

    public int addItem(int type, int screen, int container, int x, int y, String packageName) {
        return addItem(type, screen, container, x, y, mDefaultProfileId, packageName);
    }

    public int addItem(int type, int screen, int container, int x, int y, String packageName,
            int id, Uri contentUri) {
        addItem(type, screen, container, x, y, mDefaultProfileId, packageName, id, contentUri);
        return id;
    }

    /**
@@ -238,11 +252,19 @@ public class LauncherModelHelper {
     * @param type {@link #APP_ICON} or {@link #SHORTCUT} or >= 2 for
     *             folder (where the type represents the number of items in the folder).
     */
    public int addItem(int type, int screen, int container, int x, int y, long profileId) {
    public int addItem(int type, int screen, int container, int x, int y, long profileId,
            String packageName) {
        Context context = RuntimeEnvironment.application;
        int id = LauncherSettings.Settings.call(context.getContentResolver(),
                LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
                .getInt(LauncherSettings.Settings.EXTRA_VALUE);
        addItem(type, screen, container, x, y, profileId, packageName, id, CONTENT_URI);
        return id;
    }

    public void addItem(int type, int screen, int container, int x, int y, long profileId,
            String packageName, int id, Uri contentUri) {
        Context context = RuntimeEnvironment.application;

        ContentValues values = new ContentValues();
        values.put(LauncherSettings.Favorites._ID, id);
@@ -257,7 +279,7 @@ public class LauncherModelHelper {
        if (type == APP_ICON || type == SHORTCUT) {
            values.put(LauncherSettings.Favorites.ITEM_TYPE, type);
            values.put(LauncherSettings.Favorites.INTENT,
                    new Intent(Intent.ACTION_MAIN).setPackage(TEST_PACKAGE).toUri(0));
                    new Intent(Intent.ACTION_MAIN).setPackage(packageName).toUri(0));
        } else {
            values.put(LauncherSettings.Favorites.ITEM_TYPE,
                    LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
@@ -267,8 +289,7 @@ public class LauncherModelHelper {
            }
        }

        context.getContentResolver().insert(CONTENT_URI, values);
        return id;
        context.getContentResolver().insert(contentUri, values);
    }

    public int[][][] createGrid(int[][][] typeArray) {
+5 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.launcher3;

import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -164,8 +165,11 @@ public class LauncherProvider extends ContentProvider {
            return false;
        }

        mOpenHelper.close();
        DatabaseHelper oldHelper = mOpenHelper;
        mOpenHelper = new DatabaseHelper(getContext());
        copyTable(oldHelper.getReadableDatabase(), Favorites.TABLE_NAME,
                mOpenHelper.getWritableDatabase(), Favorites.TMP_TABLE, getContext());
        oldHelper.close();
        return true;
    }

+11 −0
Original line number Diff line number Diff line
@@ -102,6 +102,11 @@ public class LauncherSettings {
         */
        public static final String PREVIEW_TABLE_NAME = "favorites_preview";

        /**
         * Temporary table used specifically for multi-db grid migrations
         */
        public static final String TMP_TABLE = "favorites_tmp";

        /**
         * The content:// style URL for "favorites" table
         */
@@ -114,6 +119,12 @@ public class LauncherSettings {
        public static final Uri PREVIEW_CONTENT_URI = Uri.parse("content://"
                + LauncherProvider.AUTHORITY + "/" + PREVIEW_TABLE_NAME);

        /**
         * The content:// style URL for "favorites_tmp" table
         */
        public static final Uri TMP_CONTENT_URI = Uri.parse("content://"
                + LauncherProvider.AUTHORITY + "/" + TMP_TABLE);

        /**
         * The content:// style URL for a given row, identified by its id.
         *
+7 −6
Original line number Diff line number Diff line
@@ -936,8 +936,8 @@ public class GridSizeMigrationTask {

            boolean dbChanged = false;
            if (migrateForPreview) {
                copyTable(transaction.getDb(), Favorites.TABLE_NAME, Favorites.PREVIEW_TABLE_NAME,
                        context);
                copyTable(transaction.getDb(), Favorites.TABLE_NAME, transaction.getDb(),
                        Favorites.PREVIEW_TABLE_NAME, context);
            }

            GridBackupTable backupTable = new GridBackupTable(context, transaction.getDb(),
@@ -950,10 +950,11 @@ public class GridSizeMigrationTask {

            HashSet<String> validPackages = getValidPackages(context);
            // Hotseat.
            if (srcHotseatCount != idp.numHotseatIcons) {
                // Migrate hotseat.
                dbChanged = new GridSizeMigrationTask(context, transaction.getDb(), validPackages,
                        migrateForPreview, srcHotseatCount, idp.numHotseatIcons).migrateHotseat();
            if (srcHotseatCount != idp.numHotseatIcons
                    && new GridSizeMigrationTask(context, transaction.getDb(), validPackages,
                            migrateForPreview, srcHotseatCount,
                            idp.numHotseatIcons).migrateHotseat()) {
                dbChanged = true;
            }

            // Grid size
Loading