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();
}
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();
}
}
}
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();
}
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();
}
}
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;
}
}
Aggregations