1 package com.android.launcher3.widget 2 3 import android.appwidget.AppWidgetProviderInfo 4 import android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN 5 import android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD 6 import android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX 7 import android.content.ComponentName 8 import android.content.Context 9 import android.content.pm.ActivityInfo 10 import android.content.pm.ApplicationInfo 11 import android.platform.test.annotations.RequiresFlagsDisabled 12 import android.platform.test.annotations.RequiresFlagsEnabled 13 import android.platform.test.flag.junit.CheckFlagsRule 14 import android.platform.test.flag.junit.DeviceFlagsValueProvider 15 import android.view.ContextThemeWrapper 16 import android.view.LayoutInflater 17 import android.widget.RemoteViews 18 import androidx.test.core.app.ApplicationProvider.getApplicationContext 19 import androidx.test.ext.junit.runners.AndroidJUnit4 20 import androidx.test.filters.SmallTest 21 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation 22 import com.android.launcher3.Flags.FLAG_ENABLE_GENERATED_PREVIEWS 23 import com.android.launcher3.InvariantDeviceProfile 24 import com.android.launcher3.icons.IconCache 25 import com.android.launcher3.icons.IconProvider 26 import com.android.launcher3.model.WidgetItem 27 import com.android.launcher3.util.ActivityContextWrapper 28 import com.android.launcher3.util.Executors 29 import com.google.common.truth.Truth.assertThat 30 import org.junit.Before 31 import org.junit.Rule 32 import org.junit.Test 33 import org.junit.runner.RunWith 34 35 @SmallTest 36 @RunWith(AndroidJUnit4::class) 37 class GeneratedPreviewTest { 38 @get:Rule val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() 39 private val providerName = 40 ComponentName( 41 "com.android.launcher3.tests", 42 "com.android.launcher3.testcomponent.AppWidgetNoConfig" 43 ) 44 private val generatedPreviewLayout = <lambda>null45 getInstrumentation().context.run { 46 resources.getIdentifier("test_layout_appwidget_blue", "layout", packageName) 47 } 48 private lateinit var context: Context 49 private lateinit var generatedPreview: RemoteViews 50 private lateinit var widgetCell: WidgetCell 51 private lateinit var helper: WidgetManagerHelper 52 private lateinit var appWidgetProviderInfo: LauncherAppWidgetProviderInfo 53 private lateinit var widgetItem: WidgetItem 54 55 @Before setupnull56 fun setup() { 57 context = getApplicationContext() 58 generatedPreview = RemoteViews(context.packageName, generatedPreviewLayout) 59 widgetCell = 60 LayoutInflater.from( 61 ActivityContextWrapper( 62 ContextThemeWrapper( 63 context, 64 com.android.launcher3.R.style.WidgetContainerTheme 65 ) 66 ) 67 ) 68 .inflate(com.android.launcher3.R.layout.widget_cell, null) as WidgetCell 69 appWidgetProviderInfo = 70 AppWidgetProviderInfo() 71 .apply { 72 generatedPreviewCategories = WIDGET_CATEGORY_HOME_SCREEN 73 provider = providerName 74 providerInfo = ActivityInfo().apply { applicationInfo = ApplicationInfo() } 75 } 76 .let { LauncherAppWidgetProviderInfo.fromProviderInfo(context, it) } 77 helper = 78 object : WidgetManagerHelper(context) { 79 override fun loadGeneratedPreview( 80 info: AppWidgetProviderInfo, 81 widgetCategory: Int 82 ) = 83 generatedPreview.takeIf { 84 info === appWidgetProviderInfo && 85 widgetCategory == WIDGET_CATEGORY_HOME_SCREEN 86 } 87 } 88 createWidgetItem() 89 } 90 createWidgetItemnull91 private fun createWidgetItem() { 92 Executors.MODEL_EXECUTOR.submit { 93 val idp = InvariantDeviceProfile() 94 widgetItem = 95 WidgetItem( 96 appWidgetProviderInfo, 97 idp, 98 IconCache(context, idp, null, IconProvider(context)), 99 context, 100 helper, 101 ) 102 } 103 .get() 104 } 105 106 @Test 107 @RequiresFlagsEnabled(FLAG_ENABLE_GENERATED_PREVIEWS) widgetItem_hasGeneratedPreviewnull108 fun widgetItem_hasGeneratedPreview() { 109 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_HOME_SCREEN)).isTrue() 110 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_KEYGUARD)).isFalse() 111 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_SEARCHBOX)).isFalse() 112 } 113 114 @Test 115 @RequiresFlagsEnabled(FLAG_ENABLE_GENERATED_PREVIEWS) widgetItem_hasGeneratedPreview_noPreviewnull116 fun widgetItem_hasGeneratedPreview_noPreview() { 117 appWidgetProviderInfo.generatedPreviewCategories = 0 118 createWidgetItem() 119 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_HOME_SCREEN)).isFalse() 120 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_KEYGUARD)).isFalse() 121 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_SEARCHBOX)).isFalse() 122 } 123 124 @Test 125 @RequiresFlagsEnabled(FLAG_ENABLE_GENERATED_PREVIEWS) widgetItem_hasGeneratedPreview_nullPreviewnull126 fun widgetItem_hasGeneratedPreview_nullPreview() { 127 appWidgetProviderInfo.generatedPreviewCategories = 128 WIDGET_CATEGORY_HOME_SCREEN or WIDGET_CATEGORY_KEYGUARD 129 createWidgetItem() 130 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_HOME_SCREEN)).isTrue() 131 // loadGeneratedPreview returns null for KEYGUARD, so this should still be false. 132 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_KEYGUARD)).isFalse() 133 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_SEARCHBOX)).isFalse() 134 } 135 136 @Test 137 @RequiresFlagsDisabled(FLAG_ENABLE_GENERATED_PREVIEWS) widgetItem_hasGeneratedPreview_flagDisablednull138 fun widgetItem_hasGeneratedPreview_flagDisabled() { 139 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_HOME_SCREEN)).isFalse() 140 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_KEYGUARD)).isFalse() 141 assertThat(widgetItem.hasGeneratedPreview(WIDGET_CATEGORY_SEARCHBOX)).isFalse() 142 } 143 144 @Test 145 @RequiresFlagsEnabled(FLAG_ENABLE_GENERATED_PREVIEWS) widgetItem_getGeneratedPreviewnull146 fun widgetItem_getGeneratedPreview() { 147 val preview = widgetItem.generatedPreviews.get(WIDGET_CATEGORY_HOME_SCREEN) 148 assertThat(preview).isEqualTo(generatedPreview) 149 } 150 151 @Test 152 @RequiresFlagsEnabled(FLAG_ENABLE_GENERATED_PREVIEWS) widgetCell_showGeneratedPreviewnull153 fun widgetCell_showGeneratedPreview() { 154 widgetCell.applyFromCellItem(widgetItem) 155 DatabaseWidgetPreviewLoader.getLoaderExecutor().submit {}.get() 156 assertThat(widgetCell.appWidgetHostViewPreview).isNotNull() 157 assertThat(widgetCell.appWidgetHostViewPreview?.appWidgetInfo) 158 .isEqualTo(appWidgetProviderInfo) 159 } 160 161 @Test 162 @RequiresFlagsDisabled(FLAG_ENABLE_GENERATED_PREVIEWS) widgetCell_showGeneratedPreview_flagDisablednull163 fun widgetCell_showGeneratedPreview_flagDisabled() { 164 widgetCell.applyFromCellItem(widgetItem) 165 DatabaseWidgetPreviewLoader.getLoaderExecutor().submit {}.get() 166 assertThat(widgetCell.appWidgetHostViewPreview).isNull() 167 } 168 } 169