1 /* 2 * Copyright (C) 2022 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 android.nearby.integration.ui 18 19 import android.content.Context 20 import android.os.Bundle 21 import android.platform.test.rule.ScreenRecordRule.ScreenRecord 22 import androidx.test.core.app.ApplicationProvider 23 import androidx.test.ext.junit.runners.AndroidJUnit4 24 import androidx.test.platform.app.InstrumentationRegistry 25 import androidx.test.uiautomator.UiDevice 26 import androidx.test.uiautomator.Until 27 import com.android.server.nearby.common.eventloop.EventLoop 28 import com.android.server.nearby.common.locator.Locator 29 import com.android.server.nearby.common.locator.LocatorContextWrapper 30 import com.android.server.nearby.fastpair.FastPairController 31 import com.android.server.nearby.fastpair.cache.FastPairCacheManager 32 import com.android.server.nearby.fastpair.footprint.FootprintsDeviceManager 33 import com.android.server.nearby.fastpair.halfsheet.FastPairHalfSheetManager 34 import com.google.common.truth.Truth.assertThat 35 import com.google.common.truth.Truth.assertWithMessage 36 import org.junit.AfterClass 37 import org.junit.Before 38 import org.junit.Test 39 import org.junit.runner.RunWith 40 import service.proto.Cache 41 import service.proto.FastPairString.FastPairStrings 42 import java.time.Clock 43 44 /** An instrumented test to check Nearby half sheet UI showed correctly. 45 * 46 * To run this test directly: 47 * am instrument -w -r \ 48 * -e class android.nearby.integration.ui.CheckNearbyHalfSheetUiTest \ 49 * android.nearby.integration.ui/androidx.test.runner.AndroidJUnitRunner 50 */ 51 @RunWith(AndroidJUnit4::class) 52 class CheckNearbyHalfSheetUiTest : BaseUiTest() { 53 private var waitHalfSheetPopupTimeoutMs: Long 54 private var halfSheetTitleText: String 55 private var halfSheetSubtitleText: String 56 57 init { 58 val arguments: Bundle = InstrumentationRegistry.getArguments() 59 waitHalfSheetPopupTimeoutMs = arguments.getLong( 60 WAIT_HALF_SHEET_POPUP_TIMEOUT_KEY, 61 DEFAULT_WAIT_HALF_SHEET_POPUP_TIMEOUT_MS 62 ) 63 halfSheetTitleText = 64 arguments.getString(HALF_SHEET_TITLE_KEY, DEFAULT_HALF_SHEET_TITLE_TEXT) 65 halfSheetSubtitleText = 66 arguments.getString(HALF_SHEET_SUBTITLE_KEY, DEFAULT_HALF_SHEET_SUBTITLE_TEXT) 67 68 device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) 69 } 70 71 /** For multidevice test snippet only. Force overwrites the test arguments. */ updateTestArgumentsnull72 fun updateTestArguments( 73 waitHalfSheetPopupTimeoutSeconds: Int, 74 halfSheetTitleText: String, 75 halfSheetSubtitleText: String 76 ) { 77 this.waitHalfSheetPopupTimeoutMs = waitHalfSheetPopupTimeoutSeconds * 1000L 78 this.halfSheetTitleText = halfSheetTitleText 79 this.halfSheetSubtitleText = halfSheetSubtitleText 80 } 81 82 @Before setUpnull83 fun setUp() { 84 val appContext = ApplicationProvider.getApplicationContext<Context>() 85 val locator = Locator(appContext).apply { 86 overrideBindingForTest(EventLoop::class.java, EventLoop.newInstance("test")) 87 overrideBindingForTest( 88 FastPairCacheManager::class.java, 89 FastPairCacheManager(appContext) 90 ) 91 overrideBindingForTest(FootprintsDeviceManager::class.java, FootprintsDeviceManager()) 92 overrideBindingForTest(Clock::class.java, Clock.systemDefaultZone()) 93 } 94 val locatorContextWrapper = LocatorContextWrapper(appContext, locator) 95 locator.overrideBindingForTest( 96 FastPairController::class.java, 97 FastPairController(locatorContextWrapper) 98 ) 99 val scanFastPairStoreItem = Cache.ScanFastPairStoreItem.newBuilder() 100 .setDeviceName(DEFAULT_HALF_SHEET_TITLE_TEXT) 101 .setFastPairStrings( 102 FastPairStrings.newBuilder() 103 .setInitialPairingDescription(DEFAULT_HALF_SHEET_SUBTITLE_TEXT).build() 104 ) 105 .build() 106 FastPairHalfSheetManager(locatorContextWrapper).showHalfSheet(scanFastPairStoreItem) 107 } 108 109 @Test 110 @ScreenRecord checkNearbyHalfSheetUinull111 fun checkNearbyHalfSheetUi() { 112 // Check Nearby half sheet showed by checking button "Connect" on the DevicePairingFragment. 113 val isConnectButtonShowed = device.wait( 114 Until.hasObject(NearbyHalfSheetUiMap.DevicePairingFragment.connectButton), 115 waitHalfSheetPopupTimeoutMs 116 ) 117 assertWithMessage("Nearby half sheet didn't show within $waitHalfSheetPopupTimeoutMs ms.") 118 .that(isConnectButtonShowed).isTrue() 119 120 val halfSheetTitle = 121 device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.halfSheetTitle) 122 assertThat(halfSheetTitle).isNotNull() 123 assertThat(halfSheetTitle.text).isEqualTo(halfSheetTitleText) 124 125 val halfSheetSubtitle = 126 device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.halfSheetSubtitle) 127 assertThat(halfSheetSubtitle).isNotNull() 128 assertThat(halfSheetSubtitle.text).isEqualTo(halfSheetSubtitleText) 129 130 val deviceImage = device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.deviceImage) 131 assertThat(deviceImage).isNotNull() 132 133 val infoButton = device.findObject(NearbyHalfSheetUiMap.DevicePairingFragment.infoButton) 134 assertThat(infoButton).isNotNull() 135 } 136 137 companion object { 138 private const val DEFAULT_WAIT_HALF_SHEET_POPUP_TIMEOUT_MS = 30 * 1000L 139 private const val DEFAULT_HALF_SHEET_TITLE_TEXT = "Fast Pair Provider Simulator" 140 private const val DEFAULT_HALF_SHEET_SUBTITLE_TEXT = "Fast Pair Provider Simulator will " + 141 "appear on devices linked with nearby-mainline-fpseeker@google.com" 142 private const val WAIT_HALF_SHEET_POPUP_TIMEOUT_KEY = "WAIT_HALF_SHEET_POPUP_TIMEOUT_MS" 143 private const val HALF_SHEET_TITLE_KEY = "HALF_SHEET_TITLE" 144 private const val HALF_SHEET_SUBTITLE_KEY = "HALF_SHEET_SUBTITLE" 145 private lateinit var device: UiDevice 146 147 @AfterClass 148 @JvmStatic teardownClassnull149 fun teardownClass() { 150 // Cleans up after saving screenshot in TestWatcher, leaves nothing dirty behind. 151 DismissNearbyHalfSheetUiTest().dismissHalfSheet() 152 } 153 } 154 }