1 /*
2  * Copyright 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.intentresolver.icons
18 
19 import android.content.ComponentName
20 import android.content.Context
21 import android.content.Intent
22 import android.content.pm.ShortcutInfo
23 import android.graphics.Bitmap
24 import android.graphics.drawable.BitmapDrawable
25 import android.graphics.drawable.Drawable
26 import android.graphics.drawable.Icon
27 import android.os.UserHandle
28 import com.android.intentresolver.chooser.SelectableTargetInfo
29 import java.util.function.Consumer
30 import org.junit.Test
31 import org.mockito.kotlin.any
32 import org.mockito.kotlin.doAnswer
33 import org.mockito.kotlin.doReturn
34 import org.mockito.kotlin.eq
35 import org.mockito.kotlin.mock
36 import org.mockito.kotlin.verify
37 import org.mockito.kotlin.whenever
38 
39 class CachingTargetDataLoaderTest {
40     private val userHandle = UserHandle.of(1)
41 
42     @Test
doNotCacheCallerProvidedShortcutsnull43     fun doNotCacheCallerProvidedShortcuts() {
44         val callerTarget =
45             SelectableTargetInfo.newSelectableTargetInfo(
46                 /* sourceInfo = */ null,
47                 /* backupResolveInfo = */ null,
48                 /* resolvedIntent = */ Intent(),
49                 /* chooserTargetComponentName =*/ ComponentName("package", "Activity"),
50                 "chooserTargetUninitializedTitle",
51                 /* chooserTargetIcon =*/ Icon.createWithContentUri("content://package/icon.png"),
52                 /* chooserTargetIntentExtras =*/ null,
53                 /* modifiedScore =*/ 1f,
54                 /* shortcutInfo = */ null,
55                 /* appTarget = */ null,
56                 /* referrerFillInIntent = */ Intent(),
57             ) as SelectableTargetInfo
58 
59         val targetDataLoader =
60             mock<TargetDataLoader> {
61                 on { getOrLoadDirectShareIcon(eq(callerTarget), eq(userHandle), any()) } doReturn
62                     null
63             }
64         val testSubject = CachingTargetDataLoader(targetDataLoader)
65         val callback = Consumer<Drawable> {}
66 
67         testSubject.getOrLoadDirectShareIcon(callerTarget, userHandle, callback)
68         testSubject.getOrLoadDirectShareIcon(callerTarget, userHandle, callback)
69 
70         verify(targetDataLoader) {
71             2 * { getOrLoadDirectShareIcon(eq(callerTarget), eq(userHandle), any()) }
72         }
73     }
74 
75     @Test
serviceShortcutsAreCachednull76     fun serviceShortcutsAreCached() {
77         val context =
78             mock<Context> {
79                 on { userId } doReturn 1
80                 on { packageName } doReturn "package"
81             }
82         val targetInfo =
83             SelectableTargetInfo.newSelectableTargetInfo(
84                 /* sourceInfo = */ null,
85                 /* backupResolveInfo = */ null,
86                 /* resolvedIntent = */ Intent(),
87                 /* chooserTargetComponentName =*/ ComponentName("package", "Activity"),
88                 "chooserTargetUninitializedTitle",
89                 /* chooserTargetIcon =*/ null,
90                 /* chooserTargetIntentExtras =*/ null,
91                 /* modifiedScore =*/ 1f,
92                 /* shortcutInfo = */ ShortcutInfo.Builder(context, "1").build(),
93                 /* appTarget = */ null,
94                 /* referrerFillInIntent = */ Intent(),
95             ) as SelectableTargetInfo
96 
97         val targetDataLoader = mock<TargetDataLoader>()
98         doAnswer {
99                 val callback = it.arguments[2] as Consumer<Drawable>
100                 callback.accept(BitmapDrawable(createBitmap()))
101                 null
102             }
103             .whenever(targetDataLoader)
104             .getOrLoadDirectShareIcon(eq(targetInfo), eq(userHandle), any())
105         val testSubject = CachingTargetDataLoader(targetDataLoader)
106         val callback = Consumer<Drawable> {}
107 
108         testSubject.getOrLoadDirectShareIcon(targetInfo, userHandle, callback)
109         testSubject.getOrLoadDirectShareIcon(targetInfo, userHandle, callback)
110 
111         verify(targetDataLoader) {
112             1 * { getOrLoadDirectShareIcon(eq(targetInfo), eq(userHandle), any()) }
113         }
114     }
115 }
116 
createBitmapnull117 private fun createBitmap() = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
118