1 /* 2 * Copyright (C) 2025 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.wallpaper.module 18 19 import android.app.wallpaper.WallpaperDescription 20 import android.content.ContentProvider 21 import android.content.ContentValues 22 import android.content.Context 23 import android.database.Cursor 24 import android.database.MatrixCursor 25 import android.net.Uri 26 import android.os.Bundle 27 import android.os.Parcel 28 import android.os.Parcelable 29 import com.android.wallpaper.model.CreativeCategory 30 import com.android.wallpaper.model.WallpaperInfoContract 31 import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination 32 import com.android.wallpaper.testing.ShadowWallpaperInfo 33 import com.android.wallpaper.testing.WallpaperInfoUtils.Companion.createWallpaperInfo 34 import com.google.common.truth.Truth.assertThat 35 import dagger.hilt.android.qualifiers.ApplicationContext 36 import dagger.hilt.android.testing.HiltAndroidRule 37 import dagger.hilt.android.testing.HiltAndroidTest 38 import javax.inject.Inject 39 import org.junit.Before 40 import org.junit.Rule 41 import org.junit.Test 42 import org.junit.runner.RunWith 43 import org.robolectric.RobolectricTestRunner 44 import org.robolectric.annotation.Config 45 import org.robolectric.shadows.ShadowContentResolver 46 47 @HiltAndroidTest 48 @Config(shadows = [ShadowWallpaperInfo::class, ShadowContentResolver::class]) 49 @RunWith(RobolectricTestRunner::class) 50 class DefaultCreativeHelperTest { 51 @get:Rule(order = 0) var hiltRule = HiltAndroidRule(this) 52 @Inject @ApplicationContext lateinit var context: Context 53 @Inject lateinit var creativeHelper: DefaultCreativeHelper 54 55 @Before setUpnull56 fun setUp() { 57 hiltRule.inject() 58 59 ShadowContentResolver.registerProviderInternal( 60 "com.example.fake", 61 CurrentWallpapersContentProvider(), 62 ) 63 } 64 65 @Test getCreativePreviewUri_homeScreen_succeedsnull66 fun getCreativePreviewUri_homeScreen_succeeds() { 67 val metaData = 68 Bundle().apply { 69 putString( 70 CreativeCategory.KEY_WALLPAPER_SAVE_CREATIVE_WALLPAPER_CURRENT, 71 "content://com.example.fake/currentwallpapers", 72 ) 73 } 74 val info = createWallpaperInfo(context, metaData = metaData) 75 76 val uri = creativeHelper.getCreativePreviewUri(context, info, WallpaperDestination.HOME) 77 78 assertThat(uri).isEqualTo(CurrentWallpapersContentProvider.PREVIEW_URI_HOME) 79 } 80 81 @Test getCreativePreviewUri_lockScreen_succeedsnull82 fun getCreativePreviewUri_lockScreen_succeeds() { 83 val metaData = 84 Bundle().apply { 85 putString( 86 CreativeCategory.KEY_WALLPAPER_SAVE_CREATIVE_WALLPAPER_CURRENT, 87 "content://com.example.fake/currentwallpapers", 88 ) 89 } 90 val info = createWallpaperInfo(context, metaData = metaData) 91 92 val uri = creativeHelper.getCreativePreviewUri(context, info, WallpaperDestination.LOCK) 93 94 assertThat(uri).isEqualTo(CurrentWallpapersContentProvider.PREVIEW_URI_LOCK) 95 } 96 97 @Test getCreativeDescription_homeScreen_succeedsnull98 fun getCreativeDescription_homeScreen_succeeds() { 99 val metaData = 100 Bundle().apply { 101 putString( 102 CreativeCategory.KEY_WALLPAPER_SAVE_CREATIVE_WALLPAPER_CURRENT, 103 "content://com.example.fake/currentwallpapers", 104 ) 105 } 106 val info = createWallpaperInfo(context, metaData = metaData) 107 val expectedDescription = 108 CurrentWallpapersContentProvider.DESCRIPTION_HOME.toBuilder() 109 .setComponent(info.component) 110 .build() 111 112 val description = 113 creativeHelper.getCreativeDescription(context, info, WallpaperDestination.HOME) 114 115 assertThat(description).isEqualTo(expectedDescription) 116 } 117 118 @Test getCreativeDescription_lockScreen_succeedsnull119 fun getCreativeDescription_lockScreen_succeeds() { 120 val metaData = 121 Bundle().apply { 122 putString( 123 CreativeCategory.KEY_WALLPAPER_SAVE_CREATIVE_WALLPAPER_CURRENT, 124 "content://com.example.fake/currentwallpapers", 125 ) 126 } 127 val info = createWallpaperInfo(context, metaData = metaData) 128 val expectedDescription = 129 CurrentWallpapersContentProvider.DESCRIPTION_LOCK.toBuilder() 130 .setComponent(info.component) 131 .build() 132 133 val description = 134 creativeHelper.getCreativeDescription(context, info, WallpaperDestination.LOCK) 135 136 assertThat(description).isEqualTo(expectedDescription) 137 } 138 139 private class CurrentWallpapersContentProvider : ContentProvider() { onCreatenull140 override fun onCreate(): Boolean { 141 TODO("Not yet implemented") 142 } 143 querynull144 override fun query( 145 uri: Uri, 146 projection: Array<out String>?, 147 selection: String?, 148 selectionArgs: Array<out String>?, 149 sortOrder: String?, 150 ): Cursor { 151 val cursor = 152 MatrixCursor( 153 arrayOf( 154 WallpaperInfoContract.CURRENT_DESTINATION, 155 WallpaperInfoContract.CURRENT_CONFIG_PREVIEW_URI, 156 WallpaperInfoContract.CURRENT_DESCRIPITION, 157 ) 158 ) 159 cursor 160 .newRow() 161 .add(WallpaperInfoContract.CURRENT_DESTINATION, "home") 162 .add(WallpaperInfoContract.CURRENT_CONFIG_PREVIEW_URI, PREVIEW_URI_HOME) 163 .add(WallpaperInfoContract.CURRENT_DESCRIPITION, marshall(DESCRIPTION_HOME)) 164 cursor 165 .newRow() 166 .add(WallpaperInfoContract.CURRENT_DESTINATION, "lock") 167 .add(WallpaperInfoContract.CURRENT_CONFIG_PREVIEW_URI, PREVIEW_URI_LOCK) 168 .add(WallpaperInfoContract.CURRENT_DESCRIPITION, marshall(DESCRIPTION_LOCK)) 169 return cursor 170 } 171 getTypenull172 override fun getType(uri: Uri): String? { 173 TODO("Not yet implemented") 174 } 175 insertnull176 override fun insert(uri: Uri, values: ContentValues?): Uri? { 177 TODO("Not yet implemented") 178 } 179 updatenull180 override fun update( 181 uri: Uri, 182 values: ContentValues?, 183 selection: String?, 184 selectionArgs: Array<out String>?, 185 ): Int { 186 TODO("Not yet implemented") 187 } 188 deletenull189 override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int { 190 TODO("Not yet implemented") 191 } 192 193 companion object { 194 val PREVIEW_URI_HOME = Uri.parse("www.bogus.com/reallybogus/home") 195 val PREVIEW_URI_LOCK = Uri.parse("www.bogus.com/reallybogus/lock") 196 val DESCRIPTION_HOME = WallpaperDescription.Builder().setId("id_1").build() 197 val DESCRIPTION_LOCK = WallpaperDescription.Builder().setId("id_1").build() 198 marshallnull199 private fun marshall(parcelable: Parcelable): ByteArray { 200 val parcel = Parcel.obtain() 201 parcelable.writeToParcel(parcel, 0) 202 val bytes = parcel.marshall() 203 parcel.recycle() 204 return bytes 205 } 206 } 207 } 208 } 209