1 /* 2 * Copyright (C) 2024 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.widget.picker; 18 19 import static android.content.pm.ApplicationInfo.CATEGORY_AUDIO; 20 import static android.content.pm.ApplicationInfo.CATEGORY_IMAGE; 21 import static android.content.pm.ApplicationInfo.CATEGORY_NEWS; 22 import static android.content.pm.ApplicationInfo.CATEGORY_PRODUCTIVITY; 23 import static android.content.pm.ApplicationInfo.CATEGORY_SOCIAL; 24 import static android.content.pm.ApplicationInfo.CATEGORY_UNDEFINED; 25 import static android.content.pm.ApplicationInfo.CATEGORY_VIDEO; 26 import static android.content.pm.ApplicationInfo.FLAG_INSTALLED; 27 28 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 29 30 import static com.google.common.truth.Truth.assertThat; 31 32 import static org.mockito.ArgumentMatchers.any; 33 import static org.mockito.ArgumentMatchers.eq; 34 import static org.mockito.Mockito.doAnswer; 35 import static org.mockito.Mockito.when; 36 37 import android.appwidget.AppWidgetProviderInfo; 38 import android.content.ComponentName; 39 import android.content.Context; 40 import android.content.ContextWrapper; 41 import android.content.pm.ApplicationInfo; 42 import android.content.pm.LauncherApps; 43 import android.os.Process; 44 45 import androidx.test.core.content.pm.ApplicationInfoBuilder; 46 import androidx.test.ext.junit.runners.AndroidJUnit4; 47 import androidx.test.filters.SmallTest; 48 49 import com.android.launcher3.InvariantDeviceProfile; 50 import com.android.launcher3.R; 51 import com.android.launcher3.icons.IconCache; 52 import com.android.launcher3.model.WidgetItem; 53 import com.android.launcher3.util.Executors; 54 import com.android.launcher3.util.WidgetUtils; 55 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; 56 57 import com.google.common.collect.ImmutableMap; 58 59 import org.junit.Before; 60 import org.junit.Test; 61 import org.junit.runner.RunWith; 62 import org.mockito.Mock; 63 import org.mockito.MockitoAnnotations; 64 65 import java.util.Map; 66 67 @SmallTest 68 @RunWith(AndroidJUnit4.class) 69 public class WidgetRecommendationCategoryProviderTest { 70 private static final String TEST_PACKAGE = "com.foo.test"; 71 private static final String TEST_APP_NAME = "foo"; 72 private static final WidgetRecommendationCategory PRODUCTIVITY = 73 new WidgetRecommendationCategory( 74 R.string.productivity_widget_recommendation_category_label, 75 /*order=*/0); 76 private static final WidgetRecommendationCategory NEWS = 77 new WidgetRecommendationCategory( 78 R.string.news_widget_recommendation_category_label, /*order=*/1); 79 private static final WidgetRecommendationCategory SUGGESTED_FOR_YOU = 80 new WidgetRecommendationCategory( 81 R.string.others_widget_recommendation_category_label, /*order=*/2); 82 private static final WidgetRecommendationCategory SOCIAL = 83 new WidgetRecommendationCategory( 84 R.string.social_widget_recommendation_category_label, 85 /*order=*/3); 86 private static final WidgetRecommendationCategory ENTERTAINMENT = 87 new WidgetRecommendationCategory( 88 R.string.entertainment_widget_recommendation_category_label, 89 /*order=*/4); 90 91 private final ApplicationInfo mTestAppInfo = ApplicationInfoBuilder.newBuilder().setPackageName( 92 TEST_PACKAGE).setName(TEST_APP_NAME).build(); 93 private Context mContext; 94 @Mock 95 private IconCache mIconCache; 96 97 private WidgetItem mTestWidgetItem; 98 @Mock 99 private LauncherApps mLauncherApps; 100 private InvariantDeviceProfile mTestProfile; 101 102 @Before setUp()103 public void setUp() { 104 MockitoAnnotations.initMocks(this); 105 mContext = new ContextWrapper(getInstrumentation().getTargetContext()) { 106 @Override 107 public Object getSystemService(String name) { 108 return LAUNCHER_APPS_SERVICE.equals(name) ? mLauncherApps : super.getSystemService( 109 name); 110 } 111 }; 112 mTestAppInfo.flags = FLAG_INSTALLED; 113 mTestProfile = new InvariantDeviceProfile(); 114 mTestProfile.numRows = 5; 115 mTestProfile.numColumns = 5; 116 createTestWidgetItem(); 117 } 118 119 @Test getWidgetRecommendationCategory_returnsMappedCategory()120 public void getWidgetRecommendationCategory_returnsMappedCategory() throws Exception { 121 ImmutableMap<Integer, WidgetRecommendationCategory> testCategories = ImmutableMap.of( 122 CATEGORY_PRODUCTIVITY, PRODUCTIVITY, 123 CATEGORY_NEWS, NEWS, 124 CATEGORY_SOCIAL, SOCIAL, 125 CATEGORY_AUDIO, ENTERTAINMENT, 126 CATEGORY_IMAGE, ENTERTAINMENT, 127 CATEGORY_VIDEO, ENTERTAINMENT, 128 CATEGORY_UNDEFINED, SUGGESTED_FOR_YOU); 129 130 for (Map.Entry<Integer, WidgetRecommendationCategory> testCategory : 131 testCategories.entrySet()) { 132 133 mTestAppInfo.category = testCategory.getKey(); 134 when(mLauncherApps.getApplicationInfo(/*packageName=*/ eq(TEST_PACKAGE), 135 /*flags=*/ eq(0), 136 /*user=*/ eq(Process.myUserHandle()))) 137 .thenReturn(mTestAppInfo); 138 139 WidgetRecommendationCategory category = Executors.MODEL_EXECUTOR.submit(() -> 140 new WidgetRecommendationCategoryProvider().getWidgetRecommendationCategory( 141 mContext, 142 mTestWidgetItem)).get(); 143 144 assertThat(category).isEqualTo(testCategory.getValue()); 145 } 146 } 147 createTestWidgetItem()148 private void createTestWidgetItem() { 149 String widgetLabel = "Foo Widget"; 150 String widgetClassName = ".mWidget"; 151 152 doAnswer(invocation -> widgetLabel).when(mIconCache).getTitleNoCache(any()); 153 154 AppWidgetProviderInfo providerInfo = WidgetUtils.createAppWidgetProviderInfo(ComponentName 155 .createRelative(TEST_PACKAGE, widgetClassName)); 156 157 LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo = 158 LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, providerInfo); 159 launcherAppWidgetProviderInfo.spanX = 2; 160 launcherAppWidgetProviderInfo.spanY = 2; 161 launcherAppWidgetProviderInfo.label = widgetLabel; 162 mTestWidgetItem = new WidgetItem(launcherAppWidgetProviderInfo, mTestProfile, mIconCache, 163 mContext 164 ); 165 } 166 } 167