1 /* 2 * Copyright (C) 2021 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.bedstead.nene.activities; 18 19 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; 20 21 import android.content.Intent; 22 import android.util.Log; 23 24 import com.android.bedstead.nene.TestApis; 25 import com.android.bedstead.nene.annotations.Experimental; 26 import com.android.bedstead.nene.packages.ComponentReference; 27 import com.android.bedstead.nene.utils.Poll; 28 29 /** 30 * A wrapper around a specific Activity instance. 31 */ 32 @Experimental 33 public class Activity<E> { 34 35 private static final String TAG = "BedsteadActivityWrapper"; 36 37 /* 38 * Note that methods in this class must not rely on the activity existing within the current 39 * process. These APIs must support activities which exist in any process (and they can be 40 * interacted with using the {@link NeneActivity} interface. 41 * 42 * If an API is only suitable for activies in the current process, that API should be added to 43 * {@link LocalActivity}. 44 */ 45 46 private final E mActivityInstance; 47 private final NeneActivity mActivity; 48 Activity(E activityInstance, NeneActivity activity)49 Activity(E activityInstance, NeneActivity activity) { 50 mActivityInstance = activityInstance; 51 mActivity = activity; 52 } 53 54 /** 55 * Calls {@link android.app.Activity#startLockTask()} and blocks until the activity has entered 56 * lock task mode. 57 */ 58 @Experimental startLockTask()59 public void startLockTask() { 60 Log.d(TAG, "startLockTask() on " + mActivity); 61 mActivity.startLockTask(); 62 63 // TODO(scottjonathan): What if we're already in lock task mode when we start it here? 64 // find another thing to poll on 65 Poll.forValue("Lock task mode state", () -> TestApis.activities().getLockTaskModeState()) 66 .toNotBeEqualTo(LOCK_TASK_MODE_NONE) 67 .errorOnFail() 68 .await(); 69 } 70 71 /** 72 * Calls {@link android.app.Activity#stopLockTask()} and blocks until the activity has exited 73 * lock task mode. 74 */ 75 @Experimental stopLockTask()76 public void stopLockTask() { 77 Log.d(TAG, "stopLockTask() on " + mActivity); 78 mActivity.stopLockTask(); 79 80 // TODO(scottjonathan): What if we're already in lock task mode when we start it here? 81 // find another thing to poll 82 Poll.forValue("Lock task mode state", () -> TestApis.activities().getLockTaskModeState()) 83 .toBeEqualTo(LOCK_TASK_MODE_NONE) 84 .errorOnFail() 85 .await(); 86 } 87 88 /** 89 * Calls {@link android.app.Activity#startActivity(Intent)} and blocks until the activity has 90 * started. 91 * 92 * <p>If a specific component is specified, this will block until that component is in the 93 * foreground. Otherwise, it will block only until the foreground activity has changed. 94 */ 95 @Experimental startActivity(Intent intent)96 public void startActivity(Intent intent) { 97 Log.d(TAG, "startActivity(): " + intent); 98 if (intent.getComponent() == null) { 99 ComponentReference startActivity = TestApis.activities().foregroundActivity(); 100 mActivity.startActivity(intent); 101 Poll.forValue("Foreground activity", () -> TestApis.activities().foregroundActivity()) 102 .toNotBeEqualTo(startActivity) 103 .errorOnFail() 104 .await(); 105 } else { 106 mActivity.startActivity(intent); 107 ComponentReference component = new ComponentReference(intent.getComponent()); 108 Poll.forValue("Foreground activity", () -> TestApis.activities().foregroundActivity()) 109 .toBeEqualTo(component) 110 .errorOnFail() 111 .await(); 112 } 113 } 114 115 /** 116 * Gets the original activity to make calls on directly. 117 */ activity()118 public E activity() { 119 return mActivityInstance; 120 } 121 } 122