1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.launcher3.celllayout; 17 18 import static com.android.launcher3.util.WidgetUtils.createWidgetInfo; 19 20 import android.content.ComponentName; 21 import android.content.ContentResolver; 22 import android.content.Context; 23 import android.graphics.Rect; 24 import android.os.Process; 25 import android.os.UserHandle; 26 import android.util.Log; 27 28 import androidx.test.core.app.ApplicationProvider; 29 30 import com.android.launcher3.InvariantDeviceProfile; 31 import com.android.launcher3.LauncherSettings; 32 import com.android.launcher3.model.data.AppInfo; 33 import com.android.launcher3.model.data.ItemInfo; 34 import com.android.launcher3.model.data.LauncherAppWidgetInfo; 35 import com.android.launcher3.model.data.WorkspaceItemInfo; 36 import com.android.launcher3.ui.AbstractLauncherUiTest; 37 import com.android.launcher3.ui.TestViewHelpers; 38 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; 39 40 public class TestWorkspaceBuilder { 41 42 private static final String TAG = "CellLayoutBoardBuilder"; 43 private static final ComponentName APP_COMPONENT_NAME = new ComponentName( 44 "com.google.android.calculator", "com.android.calculator2.Calculator"); 45 46 public AbstractLauncherUiTest mTest; 47 48 private UserHandle mMyUser; 49 50 private Context mContext; 51 private ContentResolver mResolver; 52 TestWorkspaceBuilder(AbstractLauncherUiTest test, Context context)53 public TestWorkspaceBuilder(AbstractLauncherUiTest test, Context context) { 54 mTest = test; 55 mMyUser = Process.myUserHandle(); 56 mContext = context; 57 mResolver = mContext.getContentResolver(); 58 } 59 60 /** 61 * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases. 62 */ fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect, FavoriteItemsTransaction transaction, int screenId)63 private FavoriteItemsTransaction fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect, 64 FavoriteItemsTransaction transaction, int screenId) { 65 int initX = widgetRect.getCellX(); 66 int initY = widgetRect.getCellY(); 67 for (int x = initX; x < initX + widgetRect.getSpanX(); x++) { 68 for (int y = initY; y < initY + widgetRect.getSpanY(); y++) { 69 try { 70 // this widgets are filling, we don't care if we can't place them 71 ItemInfo item = createWidgetInCell( 72 new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE, 73 new Rect(x, y, x, y)), screenId); 74 transaction.addItem(item); 75 } catch (Exception e) { 76 Log.d(TAG, "Unable to place filling widget at " + x + "," + y); 77 } 78 } 79 } 80 return transaction; 81 } 82 getID()83 private int getID() { 84 return LauncherSettings.Settings.call( 85 mResolver, LauncherSettings.Settings.METHOD_NEW_ITEM_ID) 86 .getInt(LauncherSettings.Settings.EXTRA_VALUE); 87 } 88 getApp()89 private AppInfo getApp() { 90 return new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser, 91 AppInfo.makeLaunchIntent(APP_COMPONENT_NAME)); 92 } 93 addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect, FavoriteItemsTransaction transaction, int screenId)94 private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect, 95 FavoriteItemsTransaction transaction, int screenId) { 96 if (widgetRect.mType == 'x') { 97 fillWithWidgets(widgetRect, transaction, screenId); 98 } else { 99 transaction.addItem(createWidgetInCell(widgetRect, screenId)); 100 } 101 } 102 103 /** 104 * Builds the given board into the transaction 105 */ buildFromBoard(CellLayoutBoard board, FavoriteItemsTransaction transaction, final int screenId)106 public FavoriteItemsTransaction buildFromBoard(CellLayoutBoard board, 107 FavoriteItemsTransaction transaction, final int screenId) { 108 board.getWidgets().forEach( 109 (widgetRect) -> addCorrespondingWidgetRect(widgetRect, transaction, screenId)); 110 board.getIcons().forEach((iconPoint) -> 111 transaction.addItem(createIconInCell(iconPoint, screenId)) 112 ); 113 return transaction; 114 } 115 116 /** 117 * Fills the hotseat row with apps instead of suggestions, for this to work the workspace should 118 * be clean otherwise this doesn't overrides the existing icons. 119 */ fillHotseatIcons(FavoriteItemsTransaction transaction)120 public FavoriteItemsTransaction fillHotseatIcons(FavoriteItemsTransaction transaction) { 121 int hotseatCount = InvariantDeviceProfile.INSTANCE.get(mContext).numDatabaseHotseatIcons; 122 for (int i = 0; i < hotseatCount; i++) { 123 transaction.addItem(getHotseatValues(i)); 124 } 125 return transaction; 126 } 127 createWidgetInCell(CellLayoutBoard.WidgetRect widgetRect, int screenId)128 private ItemInfo createWidgetInCell(CellLayoutBoard.WidgetRect widgetRect, int screenId) { 129 LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false); 130 LauncherAppWidgetInfo item = createWidgetInfo(info, 131 ApplicationProvider.getApplicationContext(), true); 132 item.id = getID(); 133 item.cellX = widgetRect.getCellX(); 134 item.cellY = widgetRect.getCellY(); 135 item.spanX = widgetRect.getSpanX(); 136 item.spanY = widgetRect.getSpanY(); 137 item.screenId = screenId; 138 return item; 139 } 140 createIconInCell(CellLayoutBoard.IconPoint iconPoint, int screenId)141 private ItemInfo createIconInCell(CellLayoutBoard.IconPoint iconPoint, int screenId) { 142 WorkspaceItemInfo item = new WorkspaceItemInfo(getApp()); 143 item.id = getID(); 144 item.screenId = screenId; 145 item.cellX = iconPoint.getCoord().x; 146 item.cellY = iconPoint.getCoord().y; 147 item.minSpanY = item.minSpanX = item.spanX = item.spanY = 1; 148 item.container = LauncherSettings.Favorites.CONTAINER_DESKTOP; 149 return item; 150 } 151 getHotseatValues(int x)152 private ItemInfo getHotseatValues(int x) { 153 WorkspaceItemInfo item = new WorkspaceItemInfo(getApp()); 154 item.id = getID(); 155 item.cellX = x; 156 item.cellY = 0; 157 item.minSpanY = item.minSpanX = item.spanX = item.spanY = 1; 158 item.rank = x; 159 item.screenId = x; 160 item.container = LauncherSettings.Favorites.CONTAINER_HOTSEAT; 161 return item; 162 } 163 } 164