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.systemui.communal.smartspace 18 19 import android.app.PendingIntent 20 import android.content.Intent 21 import android.view.View 22 import android.widget.FrameLayout 23 import android.widget.RemoteViews.RemoteResponse 24 import androidx.core.util.component1 25 import androidx.core.util.component2 26 import androidx.test.ext.junit.runners.AndroidJUnit4 27 import androidx.test.filters.SmallTest 28 import com.android.systemui.SysuiTestCase 29 import com.android.systemui.communal.domain.interactor.communalSceneInteractor 30 import com.android.systemui.communal.widgets.CommunalTransitionAnimatorController 31 import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView 32 import com.android.systemui.coroutines.collectLastValue 33 import com.android.systemui.kosmos.testScope 34 import com.android.systemui.log.logcatLogBuffer 35 import com.android.systemui.plugins.ActivityStarter 36 import com.android.systemui.testKosmos 37 import kotlinx.coroutines.test.runTest 38 import org.junit.Assert.assertFalse 39 import org.junit.Assert.assertTrue 40 import org.junit.Before 41 import org.junit.Test 42 import org.junit.runner.RunWith 43 import org.mockito.kotlin.any 44 import org.mockito.kotlin.eq 45 import org.mockito.kotlin.isNull 46 import org.mockito.kotlin.mock 47 import org.mockito.kotlin.refEq 48 import org.mockito.kotlin.verify 49 50 @SmallTest 51 @RunWith(AndroidJUnit4::class) 52 class SmartspaceInteractionHandlerTest : SysuiTestCase() { 53 private val activityStarter = mock<ActivityStarter>() 54 private val kosmos = testKosmos() 55 56 private val testIntent = 57 PendingIntent.getActivity( 58 context, 59 /* requestCode= */ 0, 60 Intent("action"), 61 PendingIntent.FLAG_IMMUTABLE 62 ) 63 private val testResponse = RemoteResponse.fromPendingIntent(testIntent) 64 65 private lateinit var underTest: SmartspaceInteractionHandler 66 67 @Before setUpnull68 fun setUp() { 69 with(kosmos) { 70 underTest = 71 SmartspaceInteractionHandler( 72 activityStarter = activityStarter, 73 communalSceneInteractor = communalSceneInteractor, 74 logBuffer = logcatLogBuffer(), 75 ) 76 } 77 } 78 79 @Test launchAnimatorIsUsedForSmartspaceViewnull80 fun launchAnimatorIsUsedForSmartspaceView() { 81 with(kosmos) { 82 testScope.runTest { 83 val launching by collectLastValue(communalSceneInteractor.isLaunchingWidget) 84 assertFalse(launching!!) 85 86 val parent = FrameLayout(context) 87 val view = SmartspaceAppWidgetHostView(context) 88 parent.addView(view) 89 val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view) 90 91 underTest.onInteraction(view, testIntent, testResponse) 92 93 // Verify that we set the state correctly 94 assertTrue(launching!!) 95 // Verify that we pass in a non-null Communal animation controller 96 verify(activityStarter) 97 .startPendingIntentWithoutDismissing( 98 /* intent = */ eq(testIntent), 99 /* dismissShade = */ eq(false), 100 /* intentSentUiThreadCallback = */ isNull(), 101 /* animationController = */ any<CommunalTransitionAnimatorController>(), 102 /* fillInIntent = */ refEq(fillInIntent), 103 /* extraOptions = */ refEq(activityOptions.toBundle()), 104 ) 105 } 106 } 107 } 108 109 @Test launchAnimatorIsNotUsedForRegularViewnull110 fun launchAnimatorIsNotUsedForRegularView() { 111 val parent = FrameLayout(context) 112 val view = View(context) 113 parent.addView(view) 114 val (fillInIntent, activityOptions) = testResponse.getLaunchOptions(view) 115 116 underTest.onInteraction(view, testIntent, testResponse) 117 118 // Verify null is used as the animation controller 119 verify(activityStarter) 120 .startPendingIntentWithoutDismissing( 121 /* intent = */ eq(testIntent), 122 /* dismissShade = */ eq(false), 123 /* intentSentUiThreadCallback = */ isNull(), 124 /* animationController = */ isNull(), 125 /* fillInIntent = */ refEq(fillInIntent), 126 /* extraOptions = */ refEq(activityOptions.toBundle()), 127 ) 128 } 129 } 130