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

Commit 953eb804 authored by Andras Kloczl's avatar Andras Kloczl Committed by Alex Chau
Browse files

Fix LauncherProvider newScreenId issue

Remove maxScreenId from LauncherProvider and whenever we need
a new screenId, query the database to calculate a new screenId.
Also converted and refactored AddWorkspaceItemsTaskTest
and added some extra test cases.

Test: manual & AddWorkspaceItemsTaskTest.kt
Bug: 199160559
Change-Id: I185f6823fed171d778af0130497f5ffaf89c0a70
parent f7572583
Loading
Loading
Loading
Loading
+7 −30
Original line number Diff line number Diff line
@@ -383,7 +383,7 @@ public class LauncherProvider extends ContentProvider {
            case LauncherSettings.Settings.METHOD_NEW_SCREEN_ID: {
                Bundle result = new Bundle();
                result.putInt(LauncherSettings.Settings.EXTRA_VALUE,
                        mOpenHelper.generateNewScreenId());
                        mOpenHelper.getNewScreenId());
                return result;
            }
            case LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB: {
@@ -628,7 +628,6 @@ public class LauncherProvider extends ContentProvider {
        private final Context mContext;
        private final boolean mForMigration;
        private int mMaxItemId = -1;
        private int mMaxScreenId = -1;
        private boolean mBackupTableExists;
        private boolean mHotseatRestoreTableExists;

@@ -672,9 +671,6 @@ public class LauncherProvider extends ContentProvider {
            if (mMaxItemId == -1) {
                mMaxItemId = initializeMaxItemId(getWritableDatabase());
            }
            if (mMaxScreenId == -1) {
                mMaxScreenId = initializeMaxScreenId(getWritableDatabase());
            }
        }

        @Override
@@ -682,7 +678,6 @@ public class LauncherProvider extends ContentProvider {
            if (LOGD) Log.d(TAG, "creating new launcher database");

            mMaxItemId = 1;
            mMaxScreenId = 0;

            addFavoritesTable(db, false);

@@ -1043,36 +1038,19 @@ public class LauncherProvider extends ContentProvider {
        public void checkId(ContentValues values) {
            int id = values.getAsInteger(Favorites._ID);
            mMaxItemId = Math.max(id, mMaxItemId);

            Integer screen = values.getAsInteger(Favorites.SCREEN);
            Integer container = values.getAsInteger(Favorites.CONTAINER);
            if (screen != null && container != null
                    && container.intValue() == Favorites.CONTAINER_DESKTOP) {
                mMaxScreenId = Math.max(screen, mMaxScreenId);
            }
        }

        private int initializeMaxItemId(SQLiteDatabase db) {
            return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s", Favorites._ID, Favorites.TABLE_NAME);
        }

        // Generates a new ID to use for an workspace screen in your database. This method
        // should be only called from the main UI thread. As an exception, we do call it when we
        // call the constructor from the worker thread; however, this doesn't extend until after the
        // constructor is called, and we only pass a reference to LauncherProvider to LauncherApp
        // after that point
        public int generateNewScreenId() {
            if (mMaxScreenId < 0) {
                throw new RuntimeException("Error: max screen id was not initialized");
            }
            mMaxScreenId += 1;
            return mMaxScreenId;
        }

        private int initializeMaxScreenId(SQLiteDatabase db) {
            return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s WHERE %3$s = %4$d AND %1$s >= 0",
        // Returns a new ID to use for an workspace screen in your database that is greater than all
        // existing screen IDs.
        private int getNewScreenId() {
            return getMaxId(getWritableDatabase(),
                    "SELECT MAX(%1$s) FROM %2$s WHERE %3$s = %4$d AND %1$s >= 0",
                    Favorites.SCREEN, Favorites.TABLE_NAME, Favorites.CONTAINER,
                    Favorites.CONTAINER_DESKTOP);
                    Favorites.CONTAINER_DESKTOP) + 1;
        }

        @Thunk int loadFavorites(SQLiteDatabase db, AutoInstallsLayout loader) {
@@ -1081,7 +1059,6 @@ public class LauncherProvider extends ContentProvider {

            // Ensure that the max ids are initialized
            mMaxItemId = initializeMaxItemId(db);
            mMaxScreenId = initializeMaxScreenId(db);
            return count;
        }
    }
+5 −5
Original line number Diff line number Diff line
@@ -869,13 +869,13 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
        mWorkspaceScreens.remove(emptyScreenId);
        mScreenOrder.removeValue(emptyScreenId);

        int newScreenId = -1;
        // Launcher database isn't aware of empty pages that are already bound, so we need to
        // skip those IDs manually.
        while (newScreenId == -1 || mWorkspaceScreens.containsKey(newScreenId)) {
            newScreenId = LauncherSettings.Settings.call(getContext().getContentResolver(),
        int newScreenId = LauncherSettings.Settings.call(getContext().getContentResolver(),
                LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
                .getInt(LauncherSettings.Settings.EXTRA_VALUE);
        // Launcher database isn't aware of empty pages that are already bound, so we need to
        // skip those IDs manually.
        while (mWorkspaceScreens.containsKey(newScreenId)) {
            newScreenId++;
        }

        mWorkspaceScreens.put(newScreenId, cl);
+0 −6
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package com.android.launcher3.model;

import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
import static com.android.launcher3.WorkspaceLayoutManager.SECOND_SCREEN_ID;

import android.content.Intent;
import android.content.pm.LauncherActivityInfo;
@@ -300,11 +299,6 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
        IntSet screensToExclude = new IntSet();
        if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
            screensToExclude.add(FIRST_SCREEN_ID);

            // On split display we don't want to add the new items onto the second screen.
            if (app.getInvariantDeviceProfile().isSplitDisplay) {
                screensToExclude.add(SECOND_SCREEN_ID);
            }
        }

        for (int screen = 0; screen < screenCount; screen++) {
+1 −1
Original line number Diff line number Diff line
@@ -292,7 +292,7 @@ public class ModelWriter {
        FileLog.d(TAG, "removing items from db " + items.stream().map(
                (item) -> item.getTargetComponent() == null ? ""
                        : item.getTargetComponent().getPackageName()).collect(
                Collectors.joining(",")), new Exception());
                Collectors.joining(",")));
        notifyDelete(items);
        enqueueDeleteRunnable(() -> {
            for (ItemInfo item : items) {
+0 −20
Original line number Diff line number Diff line
@@ -86,8 +86,6 @@ public class AddWorkspaceItemsTaskTest {

    @Test
    public void testFindSpaceForItem_prefers_second() throws Exception {
        mIdp.isSplitDisplay = false;

        // First screen has only one hole of size 1
        int nextId = setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));

@@ -108,24 +106,6 @@ public class AddWorkspaceItemsTaskTest {
                .isRegionVacant(spaceFound[1], spaceFound[2], 2, 3));
    }

    @Test
    public void testFindSpaceForItem_prefers_third_on_split_display() throws Exception {
        mIdp.isSplitDisplay = true;
        // First screen has only one hole of size 1
        int nextId = setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));

        // Second screen has 2 holes of sizes 3x2 and 2x3
        setupWorkspaceWithHoles(nextId, 2, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));

        int[] spaceFound = newTask().findSpaceForItem(
                mAppState, mModelHelper.getBgDataModel(), mExistingScreens, mNewScreens, 1, 1);
        // For split display, it picks the next screen, even if there is enough space
        // on previous screen
        assertEquals(2, spaceFound[0]);
        assertTrue(mScreenOccupancy.get(spaceFound[0])
                .isRegionVacant(spaceFound[1], spaceFound[2], 1, 1));
    }

    @Test
    public void testFindSpaceForItem_adds_new_screen() throws Exception {
        // First screen has 2 holes of sizes 3x2 and 2x3