Search in sources :

Example 1 with IntSparseArrayMap

use of com.android.launcher3.util.IntSparseArrayMap in project android_packages_apps_Launcher3 by crdroidandroid.

the class GridSizeMigrationTask method migrateWorkspace.

/**
 * @return true if any DB change was made
 */
protected boolean migrateWorkspace() throws Exception {
    IntArray allScreens = getWorkspaceScreenIds(mDb, mTableName);
    if (allScreens.isEmpty()) {
        throw new Exception("Unable to get workspace screens");
    }
    for (int i = 0; i < allScreens.size(); i++) {
        int screenId = allScreens.get(i);
        if (DEBUG) {
            Log.d(TAG, "Migrating " + screenId);
        }
        migrateScreen(screenId);
    }
    if (!mCarryOver.isEmpty()) {
        IntSparseArrayMap<DbEntry> itemMap = new IntSparseArrayMap<>();
        for (DbEntry e : mCarryOver) {
            itemMap.put(e.id, e);
        }
        do {
            // Some items are still remaining. Try adding a few new screens.
            // At every iteration, make sure that at least one item is removed from
            // {@link #mCarryOver}, to prevent an infinite loop. If no item could be removed,
            // break the loop and abort migration by throwing an exception.
            OptimalPlacementSolution placement = new OptimalPlacementSolution(new GridOccupancy(mTrgX, mTrgY), deepCopy(mCarryOver), 0, true);
            placement.find();
            if (placement.finalPlacedItems.size() > 0) {
                int newScreenId = LauncherSettings.Settings.call(mContext.getContentResolver(), LauncherSettings.Settings.METHOD_NEW_SCREEN_ID).getInt(EXTRA_VALUE);
                for (DbEntry item : placement.finalPlacedItems) {
                    if (!mCarryOver.remove(itemMap.get(item.id))) {
                        throw new Exception("Unable to find matching items");
                    }
                    item.screenId = newScreenId;
                    update(item);
                }
            } else {
                throw new Exception("None of the items can be placed on an empty screen");
            }
        } while (!mCarryOver.isEmpty());
    }
    return applyOperations();
}
Also used : IntArray(com.android.launcher3.util.IntArray) IntSparseArrayMap(com.android.launcher3.util.IntSparseArrayMap) GridOccupancy(com.android.launcher3.util.GridOccupancy) Utilities.parsePoint(com.android.launcher3.Utilities.parsePoint) Point(android.graphics.Point)

Example 2 with IntSparseArrayMap

use of com.android.launcher3.util.IntSparseArrayMap in project android_packages_apps_Launcher3 by crdroidandroid.

the class GridSizeMigrationTask method migrateScreen.

/**
 * Migrate a particular screen id.
 * Strategy:
 *  1) For all possible combinations of row and column, pick the one which causes the least
 *    data loss: {@link #tryRemove(int, int, int, ArrayList, float[])}
 *  2) Maintain a list of all lost items before this screen, and add any new item lost from
 *    this screen to that list as well.
 *  3) If all those items from the above list can be placed on this screen, place them
 *    (otherwise they are placed on a new screen).
 */
protected void migrateScreen(int screenId) {
    // If we are migrating the first screen, do not touch the first row.
    int startY = (FeatureFlags.QSB_ON_FIRST_SCREEN && screenId == Workspace.FIRST_SCREEN_ID) ? 1 : 0;
    ArrayList<DbEntry> items = loadWorkspaceEntries(screenId);
    int removedCol = Integer.MAX_VALUE;
    int removedRow = Integer.MAX_VALUE;
    // removeWt represents the cost function for loss of items during migration, and moveWt
    // represents the cost function for repositioning the items. moveWt is only considered if
    // removeWt is same for two different configurations.
    // Start with Float.MAX_VALUE (assuming full data) and pick the configuration with least
    // cost.
    float removeWt = Float.MAX_VALUE;
    float moveWt = Float.MAX_VALUE;
    float[] outLoss = new float[2];
    ArrayList<DbEntry> finalItems = null;
    // Try removing all possible combinations
    for (int x = 0; x < mSrcX; x++) {
        // nicely aligned with hotseat.
        for (int y = mSrcY - 1; y >= startY; y--) {
            // Use a deep copy when trying out a particular combination as it can change
            // the underlying object.
            ArrayList<DbEntry> itemsOnScreen = tryRemove(x, y, startY, deepCopy(items), outLoss);
            if ((outLoss[0] < removeWt) || ((outLoss[0] == removeWt) && (outLoss[1] < moveWt))) {
                removeWt = outLoss[0];
                moveWt = outLoss[1];
                removedCol = mShouldRemoveX ? x : removedCol;
                removedRow = mShouldRemoveY ? y : removedRow;
                finalItems = itemsOnScreen;
            }
            // No need to loop over all rows, if a row removal is not needed.
            if (!mShouldRemoveY) {
                break;
            }
        }
        if (!mShouldRemoveX) {
            break;
        }
    }
    if (DEBUG) {
        Log.d(TAG, String.format("Removing row %d, column %d on screen %d", removedRow, removedCol, screenId));
    }
    IntSparseArrayMap<DbEntry> itemMap = new IntSparseArrayMap<>();
    for (DbEntry e : deepCopy(items)) {
        itemMap.put(e.id, e);
    }
    for (DbEntry item : finalItems) {
        DbEntry org = itemMap.get(item.id);
        itemMap.remove(item.id);
        // Check if update is required
        if (!item.columnsSame(org)) {
            update(item);
        }
    }
    // The remaining items in {@link #itemMap} are those which didn't get placed.
    for (DbEntry item : itemMap) {
        mCarryOver.add(item);
    }
    if (!mCarryOver.isEmpty() && removeWt == 0) {
        // No new items were removed in this step. Try placing all the items on this screen.
        GridOccupancy occupied = new GridOccupancy(mTrgX, mTrgY);
        occupied.markCells(0, 0, mTrgX, startY, true);
        for (DbEntry item : finalItems) {
            occupied.markCells(item, true);
        }
        OptimalPlacementSolution placement = new OptimalPlacementSolution(occupied, deepCopy(mCarryOver), startY, true);
        placement.find();
        if (placement.lowestWeightLoss == 0) {
            for (DbEntry item : placement.finalPlacedItems) {
                item.screenId = screenId;
                update(item);
            }
            mCarryOver.clear();
        }
    }
}
Also used : IntSparseArrayMap(com.android.launcher3.util.IntSparseArrayMap) GridOccupancy(com.android.launcher3.util.GridOccupancy) Utilities.parsePoint(com.android.launcher3.Utilities.parsePoint) Point(android.graphics.Point)

Example 3 with IntSparseArrayMap

use of com.android.launcher3.util.IntSparseArrayMap in project android_packages_apps_Launcher3 by crdroidandroid.

the class AddWorkspaceItemsTaskTest method setup.

@Before
public void setup() {
    mModelHelper = new LauncherModelHelper();
    mTargetContext = RuntimeEnvironment.application;
    mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
    mIdp.numColumns = mIdp.numRows = 5;
    mAppState = LauncherAppState.getInstance(mTargetContext);
    mExistingScreens = new IntArray();
    mScreenOccupancy = new IntSparseArrayMap<>();
    mNewScreens = new IntArray();
}
Also used : IntArray(com.android.launcher3.util.IntArray) LauncherModelHelper(com.android.launcher3.util.LauncherModelHelper) Before(org.junit.Before)

Example 4 with IntSparseArrayMap

use of com.android.launcher3.util.IntSparseArrayMap in project android_packages_apps_Launcher3 by crdroidandroid.

the class QuickstepModelDelegate method modelLoadComplete.

@Override
@WorkerThread
public void modelLoadComplete() {
    super.modelLoadComplete();
    // Log snapshot of the model
    SharedPreferences prefs = getDevicePrefs(mApp.getContext());
    long lastSnapshotTimeMillis = prefs.getLong(LAST_SNAPSHOT_TIME_MILLIS, 0);
    // Log snapshot only if previous snapshot was older than a day
    long now = System.currentTimeMillis();
    if (now - lastSnapshotTimeMillis < DAY_IN_MILLIS) {
        if (IS_DEBUG) {
            String elapsedTime = formatElapsedTime((now - lastSnapshotTimeMillis) / 1000);
            Log.d(TAG, String.format("Skipped snapshot logging since previous snapshot was %s old.", elapsedTime));
        }
    } else {
        IntSparseArrayMap<ItemInfo> itemsIdMap;
        synchronized (mDataModel) {
            itemsIdMap = mDataModel.itemsIdMap.clone();
        }
        InstanceId instanceId = new InstanceIdSequence().newInstanceId();
        for (ItemInfo info : itemsIdMap) {
            FolderInfo parent = info.container > 0 ? (FolderInfo) itemsIdMap.get(info.container) : null;
            StatsLogCompatManager.writeSnapshot(info.buildProto(parent), instanceId);
        }
        additionalSnapshotEvents(instanceId);
        prefs.edit().putLong(LAST_SNAPSHOT_TIME_MILLIS, now).apply();
    }
}
Also used : SharedPreferences(android.content.SharedPreferences) ItemInfo(com.android.launcher3.model.data.ItemInfo) WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo) InstanceId(com.android.launcher3.logging.InstanceId) InstanceIdSequence(com.android.launcher3.logging.InstanceIdSequence) FolderInfo(com.android.launcher3.model.data.FolderInfo) WorkerThread(androidx.annotation.WorkerThread)

Example 5 with IntSparseArrayMap

use of com.android.launcher3.util.IntSparseArrayMap in project android_packages_apps_Launcher3 by crdroidandroid.

the class GridSizeMigrationTask method removeBrokenHotseatItems.

/**
 * Removes any broken item from the hotseat.
 *
 * @return a map with occupied hotseat position set to non-null value.
 */
public static IntSparseArrayMap<Object> removeBrokenHotseatItems(Context context) throws Exception {
    try (SQLiteTransaction transaction = (SQLiteTransaction) Settings.call(context.getContentResolver(), Settings.METHOD_NEW_TRANSACTION).getBinder(Settings.EXTRA_VALUE)) {
        GridSizeMigrationTask task = new GridSizeMigrationTask(context, transaction.getDb(), getValidPackages(context), false, /* usePreviewTable */
        Integer.MAX_VALUE, Integer.MAX_VALUE);
        // Load all the valid entries
        ArrayList<DbEntry> items = task.loadHotseatEntries();
        // Delete any entry marked for deletion by above load.
        task.applyOperations();
        IntSparseArrayMap<Object> positions = new IntSparseArrayMap<>();
        for (DbEntry item : items) {
            positions.put(item.screenId, item);
        }
        transaction.commit();
        return positions;
    }
}
Also used : IntSparseArrayMap(com.android.launcher3.util.IntSparseArrayMap) SQLiteTransaction(com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction)

Aggregations

IntArray (com.android.launcher3.util.IntArray)3 IntSparseArrayMap (com.android.launcher3.util.IntSparseArrayMap)3 Point (android.graphics.Point)2 Utilities.parsePoint (com.android.launcher3.Utilities.parsePoint)2 GridOccupancy (com.android.launcher3.util.GridOccupancy)2 ContentProviderOperation (android.content.ContentProviderOperation)1 ContentValues (android.content.ContentValues)1 Intent (android.content.Intent)1 SharedPreferences (android.content.SharedPreferences)1 Cursor (android.database.Cursor)1 SparseBooleanArray (android.util.SparseBooleanArray)1 WorkerThread (androidx.annotation.WorkerThread)1 InstanceId (com.android.launcher3.logging.InstanceId)1 InstanceIdSequence (com.android.launcher3.logging.InstanceIdSequence)1 FolderInfo (com.android.launcher3.model.data.FolderInfo)1 ItemInfo (com.android.launcher3.model.data.ItemInfo)1 WorkspaceItemInfo (com.android.launcher3.model.data.WorkspaceItemInfo)1 SQLiteTransaction (com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction)1 LauncherModelHelper (com.android.launcher3.util.LauncherModelHelper)1 URISyntaxException (java.net.URISyntaxException)1