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.platform.helpers
18 
19 import android.content.Context
20 import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
21 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
22 import androidx.test.platform.app.InstrumentationRegistry
23 import androidx.test.uiautomator.By
24 import androidx.test.uiautomator.UiDevice
25 import androidx.test.uiautomator.Until
26 import java.time.Duration
27 
28 /** Utilities to launch an [App]. */
29 object LaunchAppUtils {
30 
31     /** Launches an [App]. */
32     @JvmStatic
Contextnull33     fun Context.launchApp(app: App) {
34         val appIntent =
35             packageManager.getLaunchIntentForPackage(app.packageName)?.apply {
36                 flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
37             }
38                 ?: error("Package ${app.packageName} not available")
39 
40         startActivity(appIntent)
41         assertAppInForeground(app)
42     }
43 
44     /** Asserts that a given app is in the foreground. */
45     @JvmStatic
assertAppInForegroundnull46     fun assertAppInForeground(app: App) {
47         assertAppInForeground(app.packageName)
48     }
49 
50     /** Asserts that a given app is in the foreground. */
51     @JvmStatic
assertAppInForegroundnull52     fun assertAppInForeground(packageName: String) {
53         check(device.wait(Until.hasObject(By.pkg(packageName).depth(0)), MAX_TIMEOUT.toMillis())) {
54             "$packageName not in the foreground after ${MAX_TIMEOUT.toSeconds()} seconds"
55         }
56     }
57 
58     private val device: UiDevice
59         get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
60 }
61 
62 /** Describes an app that can be launched with [LaunchAppUtils]. */
63 enum class App(internal val packageName: String) {
64     CALCULATOR("com.google.android.calculator"),
65     MAPS("com.google.android.apps.maps"),
66     CAMERA("com.google.android.GoogleCamera"),
67     SETTINGS("com.android.settings")
68 }
69 
70 private val MAX_TIMEOUT = Duration.ofSeconds(10)
71