1 /*
2  * Copyright (C) 2019 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 
17 package com.android.launcher3.model;
18 
19 import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
20 
21 import static org.junit.Assert.assertEquals;
22 import static org.robolectric.Shadows.shadowOf;
23 import static org.robolectric.util.ReflectionHelpers.setField;
24 
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.pm.PackageInstaller;
28 import android.content.pm.PackageInstaller.SessionInfo;
29 import android.content.pm.PackageInstaller.SessionParams;
30 
31 import com.android.launcher3.LauncherSettings;
32 import com.android.launcher3.icons.BitmapInfo;
33 import com.android.launcher3.model.data.FolderInfo;
34 import com.android.launcher3.model.data.ItemInfo;
35 import com.android.launcher3.util.LauncherLayoutBuilder;
36 import com.android.launcher3.util.LauncherModelHelper;
37 
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.robolectric.RobolectricTestRunner;
42 import org.robolectric.RuntimeEnvironment;
43 import org.robolectric.annotation.LooperMode;
44 import org.robolectric.annotation.LooperMode.Mode;
45 
46 /**
47  * Tests for layout parser for remote layout
48  */
49 @RunWith(RobolectricTestRunner.class)
50 @LooperMode(Mode.PAUSED)
51 public class DefaultLayoutProviderTest {
52 
53     private LauncherModelHelper mModelHelper;
54     private Context mTargetContext;
55 
56     @Before
setUp()57     public void setUp() {
58         mModelHelper = new LauncherModelHelper();
59         mTargetContext = RuntimeEnvironment.application;
60 
61         shadowOf(mTargetContext.getPackageManager())
62                 .addActivityIfNotPresent(new ComponentName(TEST_PACKAGE, TEST_PACKAGE));
63     }
64 
65     @Test
testCustomProfileLoaded_with_icon_on_hotseat()66     public void testCustomProfileLoaded_with_icon_on_hotseat() throws Exception {
67         writeLayoutAndLoad(new LauncherLayoutBuilder().atHotseat(0)
68                 .putApp(TEST_PACKAGE, TEST_PACKAGE));
69 
70         // Verify one item in hotseat
71         assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
72         ItemInfo info = mModelHelper.getBgDataModel().workspaceItems.get(0);
73         assertEquals(LauncherSettings.Favorites.CONTAINER_HOTSEAT, info.container);
74         assertEquals(LauncherSettings.Favorites.ITEM_TYPE_APPLICATION, info.itemType);
75     }
76 
77     @Test
testCustomProfileLoaded_with_folder()78     public void testCustomProfileLoaded_with_folder() throws Exception {
79         writeLayoutAndLoad(new LauncherLayoutBuilder().atHotseat(0).putFolder(android.R.string.copy)
80                 .addApp(TEST_PACKAGE, TEST_PACKAGE)
81                 .addApp(TEST_PACKAGE, TEST_PACKAGE)
82                 .addApp(TEST_PACKAGE, TEST_PACKAGE)
83                 .build());
84 
85         // Verify folder
86         assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
87         ItemInfo info = mModelHelper.getBgDataModel().workspaceItems.get(0);
88         assertEquals(LauncherSettings.Favorites.ITEM_TYPE_FOLDER, info.itemType);
89         assertEquals(3, ((FolderInfo) info).contents.size());
90     }
91 
92     @Test
testCustomProfileLoaded_with_folder_custom_title()93     public void testCustomProfileLoaded_with_folder_custom_title() throws Exception {
94         writeLayoutAndLoad(new LauncherLayoutBuilder().atHotseat(0).putFolder("CustomFolder")
95                 .addApp(TEST_PACKAGE, TEST_PACKAGE)
96                 .addApp(TEST_PACKAGE, TEST_PACKAGE)
97                 .addApp(TEST_PACKAGE, TEST_PACKAGE)
98                 .build());
99 
100         // Verify folder
101         assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
102         ItemInfo info = mModelHelper.getBgDataModel().workspaceItems.get(0);
103         assertEquals(LauncherSettings.Favorites.ITEM_TYPE_FOLDER, info.itemType);
104         assertEquals(3, ((FolderInfo) info).contents.size());
105         assertEquals("CustomFolder", info.title.toString());
106     }
107 
108     @Test
testCustomProfileLoaded_with_widget()109     public void testCustomProfileLoaded_with_widget() throws Exception {
110         String pendingAppPkg = "com.test.pending";
111 
112         // Add a dummy session info so that the widget exists
113         SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
114         params.setAppPackageName(pendingAppPkg);
115 
116         PackageInstaller installer = mTargetContext.getPackageManager().getPackageInstaller();
117         int sessionId = installer.createSession(params);
118         SessionInfo sessionInfo = installer.getSessionInfo(sessionId);
119         setField(sessionInfo, "installerPackageName", "com.test");
120         setField(sessionInfo, "appIcon", BitmapInfo.LOW_RES_ICON);
121 
122         writeLayoutAndLoad(new LauncherLayoutBuilder().atWorkspace(0, 1, 0)
123                 .putWidget(pendingAppPkg, "DummyWidget", 2, 2));
124 
125         // Verify widget
126         assertEquals(1, mModelHelper.getBgDataModel().appWidgets.size());
127         ItemInfo info = mModelHelper.getBgDataModel().appWidgets.get(0);
128         assertEquals(LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET, info.itemType);
129         assertEquals(2, info.spanX);
130         assertEquals(2, info.spanY);
131     }
132 
writeLayoutAndLoad(LauncherLayoutBuilder builder)133     private void writeLayoutAndLoad(LauncherLayoutBuilder builder) throws Exception {
134         mModelHelper.setupDefaultLayoutProvider(builder).loadModelSync();
135     }
136 }
137