Add logs and prevent collissions when adding items

-AddWorkspaceItemsTask can add multiple items to the same position, we
avoid that here by adding each item to the database before processing
the next item.
-We add more logs to InstallSessionHelper to be able to check who the
installer is

Bug: 432237485, 425754534
Test: AddWorkspaceItemsTaskTest
Flag: EXEMPT bugfix
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4b439e999734852a017ce662543b4789b36e0e3b)
Merged-In: I2d238f3eb27734ab9cb723e2fe9d6752c5921dd1
Change-Id: I2d238f3eb27734ab9cb723e2fe9d6752c5921dd1
This commit is contained in:
Federico Baron
2025-07-22 20:32:17 +00:00
committed by Android Build Coastguard Worker
parent 02aa11510d
commit df328e5dfa
6 changed files with 71 additions and 15 deletions

View File

@@ -125,8 +125,8 @@ public class AddWorkspaceItemsTask implements ModelUpdateTask {
ModelWriter writer = taskController.getModelWriter();
for (ItemInfo item : filteredItems) {
// Find appropriate space for the item.
int[] coords = mItemSpaceFinder.findSpaceForItem(
workspaceScreens, addedWorkspaceScreensFinal, item.spanX, item.spanY);
int[] coords = mItemSpaceFinder.findSpaceForItem(workspaceScreens,
addedWorkspaceScreensFinal, addedItemsFinal, item.spanX, item.spanY);
int screenId = coords[0];
ItemInfo itemInfo;

View File

@@ -54,8 +54,8 @@ public class WorkspaceItemSpaceFinder {
*
* @return screenId and the coordinates for the item in an int array of size 3.
*/
public int[] findSpaceForItem(
IntArray workspaceScreens, IntArray addedWorkspaceScreensFinal, int spanX, int spanY) {
public int[] findSpaceForItem(IntArray workspaceScreens, IntArray addedWorkspaceScreensFinal,
ArrayList<ItemInfo> addItemsFinal, int spanX, int spanY) {
LongSparseArray<ArrayList<ItemInfo>> screenItems = new LongSparseArray<>();
// Use sBgItemsIdMap as all the items are already loaded.
@@ -72,6 +72,18 @@ public class WorkspaceItemSpaceFinder {
}
}
// Add items that are due to be added to the database from AddWorkspaceItemsTask#execute.
for (ItemInfo info : addItemsFinal) {
if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
ArrayList<ItemInfo> items = screenItems.get(info.screenId);
if (items == null) {
items = new ArrayList<>();
screenItems.put(info.screenId, items);
}
items.add(info);
}
}
// Find appropriate space for the item.
int screenId = 0;
int[] coordinates = new int[2];

View File

@@ -225,8 +225,11 @@ public class InstallSessionHelper {
// not already present. For general app installations however, we do support it.
if (!Flags.enableSupportForArchiving() || !sessionInfo.isUnarchival()) {
FileLog.d(LOG, "Adding package name to install queue: "
+ sessionInfo.getAppPackageName());
+ sessionInfo.getAppPackageName()
+ "Package installer: "
+ sessionInfo.getInstallerPackageName()
+ "Session id: "
+ sessionInfo.getSessionId());
ItemInstallQueue.INSTANCE.get(mAppContext)
.queueItem(sessionInfo.getAppPackageName(), getUserHandle(sessionInfo));
}

View File

@@ -21,6 +21,7 @@ import com.android.launcher3.InvariantDeviceProfile
import com.android.launcher3.LauncherAppState
import com.android.launcher3.LauncherModel
import com.android.launcher3.model.data.AppInfo
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.model.data.WorkspaceItemInfo
import com.android.launcher3.util.GridOccupancy
import com.android.launcher3.util.IntArray
@@ -50,6 +51,7 @@ abstract class AbstractWorkspaceModelTest {
protected lateinit var mAppState: LauncherAppState
protected lateinit var mExistingScreens: IntArray
protected lateinit var mNewScreens: IntArray
protected lateinit var mAddedWorkspaceItems: ArrayList<ItemInfo>
protected lateinit var mScreenOccupancy: IntSparseArrayMap<GridOccupancy>
val model: LauncherModel
@@ -64,6 +66,7 @@ abstract class AbstractWorkspaceModelTest {
mExistingScreens = IntArray()
mScreenOccupancy = IntSparseArrayMap()
mNewScreens = IntArray()
mAddedWorkspaceItems = ArrayList()
}
/** Sets up workspaces with the given screen IDs with some items and a 2x2 space. */

View File

@@ -25,6 +25,7 @@ import com.android.launcher3.util.Executors
import com.android.launcher3.util.IntArray
import com.android.launcher3.util.TestUtil.runOnExecutorSync
import com.google.common.truth.Truth.assertThat
import java.util.ArrayList
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -62,7 +63,7 @@ class AddWorkspaceItemsTaskTest : AbstractWorkspaceModelTest() {
assertThat(addedItems.size).isEqualTo(1)
assertThat(addedItems.first().screenId).isEqualTo(1)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1, addedItems)
}
@Test
@@ -75,7 +76,7 @@ class AddWorkspaceItemsTaskTest : AbstractWorkspaceModelTest() {
assertThat(addedItems.size).isEqualTo(1)
assertThat(addedItems.first().screenId).isEqualTo(1)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1, addedItems)
}
@Test
@@ -101,7 +102,7 @@ class AddWorkspaceItemsTaskTest : AbstractWorkspaceModelTest() {
assertThat(addedItems.size).isEqualTo(1)
assertThat(addedItems.first().screenId).isEqualTo(2)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1, addedItems)
}
@Test
@@ -123,26 +124,30 @@ class AddWorkspaceItemsTaskTest : AbstractWorkspaceModelTest() {
// Items that are added to the second screen should be animated
val itemsAddedToSecondScreen = addedItems.filter { it.screenId == 2 }
assertThat(itemsAddedToSecondScreen.size).isEqualTo(2)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 3)
verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 3, addedItems)
}
/** Sets up the item space data that will be returned from WorkspaceItemSpaceFinder. */
private fun givenNewItemSpaces(vararg newItemSpaces: NewItemSpace) {
val spaceStack = newItemSpaces.toMutableList()
whenever(mWorkspaceItemSpaceFinder.findSpaceForItem(any(), any(), any(), any())).then {
spaceStack.removeFirst().toIntArray()
}
whenever(mWorkspaceItemSpaceFinder.findSpaceForItem(any(), any(), any(), any(), any()))
.then { spaceStack.removeFirst().toIntArray() }
}
/**
* Verifies if WorkspaceItemSpaceFinder was called with proper arguments and how many times was
* it called.
*/
private fun verifyItemSpaceFinderCall(nonEmptyScreenIds: List<Int>, numberOfExpectedCall: Int) {
private fun verifyItemSpaceFinderCall(
nonEmptyScreenIds: List<Int>,
numberOfExpectedCall: Int,
items: List<ItemInfo>,
) {
verify(mWorkspaceItemSpaceFinder, times(numberOfExpectedCall))
.findSpaceForItem(
eq(IntArray.wrap(*nonEmptyScreenIds.toIntArray())),
eq(IntArray()),
eq(ArrayList(items)),
eq(1),
eq(1),
)

View File

@@ -18,6 +18,8 @@ package com.android.launcher3.model
import android.graphics.Rect
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP
import com.android.launcher3.model.data.ItemInfo
import com.android.launcher3.util.ModelTestExtensions.bgDataModel
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -36,7 +38,7 @@ class WorkspaceItemSpaceFinderTest : AbstractWorkspaceModelTest() {
private fun findSpace(spanX: Int, spanY: Int): NewItemSpace =
WorkspaceItemSpaceFinder(model.bgDataModel, mAppState.invariantDeviceProfile, model)
.findSpaceForItem(mExistingScreens, mNewScreens, spanX, spanY)
.findSpaceForItem(mExistingScreens, mNewScreens, mAddedWorkspaceItems, spanX, spanY)
.let { NewItemSpace.fromIntArray(it) }
private fun assertRegionVacant(newItemSpace: NewItemSpace, spanX: Int, spanY: Int) {
@@ -67,6 +69,37 @@ class WorkspaceItemSpaceFinderTest : AbstractWorkspaceModelTest() {
assertRegionVacant(spaceFound, 1, 1)
}
@Test
fun workspaceItemsAddedButNotYetCommittedToDbShouldBeTakenIntoAccountInFindSpaceForItem() {
setupWorkspacesWithSpaces(
// 3x2 space on screen 0, but it should be skipped
screen0 = listOf(Rect(2, 0, 5, 2)),
screen1 = listOf(Rect(2, 2, 4, 4)), // 2x2 space
)
val itemInfo = ItemInfo()
itemInfo.cellX = 2
itemInfo.cellY = 2
itemInfo.screenId = 1
itemInfo.container = CONTAINER_DESKTOP
mAddedWorkspaceItems.add(itemInfo)
val itemInfo2 = ItemInfo()
itemInfo2.cellX = 3
itemInfo2.cellY = 2
itemInfo2.screenId = 1
itemInfo2.container = CONTAINER_DESKTOP
mAddedWorkspaceItems.add(itemInfo2)
val spaceFound = findSpace(1, 1)
assertThat(spaceFound.screenId).isEqualTo(1)
assertThat(spaceFound.cellX).isEqualTo(2)
assertThat(spaceFound.cellY).isEqualTo(3)
assertRegionVacant(spaceFound, 1, 1)
mAddedWorkspaceItems.clear()
}
@Test
fun notEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnSecondScreenId() {
setupWorkspacesWithSpaces(