1 /* 2 * Copyright (C) 2015 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.assist.cts; 18 19 import android.assist.common.Utils; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.util.Log; 25 26 import java.util.concurrent.CountDownLatch; 27 import java.util.concurrent.TimeUnit; 28 29 /** Test we receive proper assist data when context is disabled or enabled */ 30 31 public class LifecycleTest extends AssistTestBase { 32 private static final String TAG = "LifecycleTest"; 33 private static final String action_hasResumed = Utils.LIFECYCLE_HASRESUMED; 34 private static final String action_hasFocus = Utils.LIFECYCLE_HASFOCUS; 35 private static final String action_lostFocus = Utils.LIFECYCLE_LOSTFOCUS; 36 private static final String action_onPause = Utils.LIFECYCLE_ONPAUSE; 37 private static final String action_onStop = Utils.LIFECYCLE_ONSTOP; 38 private static final String action_onDestroy = Utils.LIFECYCLE_ONDESTROY; 39 40 private static final String TEST_CASE_TYPE = Utils.LIFECYCLE; 41 42 private BroadcastReceiver mLifecycleTestBroadcastReceiver; 43 private CountDownLatch mHasResumedLatch; 44 private CountDownLatch mHasFocusLatch; 45 private CountDownLatch mLostFocusLatch; 46 private CountDownLatch mActivityLifecycleLatch; 47 private CountDownLatch mDestroyLatch; 48 private CountDownLatch mReadyLatch; 49 private boolean mLostFocusIsLifecycle; 50 51 @Override 52 public void setUp() throws Exception { 53 super.setUp(); 54 mLifecycleTestBroadcastReceiver = new LifecycleTestReceiver(); 55 IntentFilter filter = new IntentFilter(); 56 filter.addAction(action_hasResumed); 57 filter.addAction(action_hasFocus); 58 filter.addAction(action_lostFocus); 59 filter.addAction(action_onPause); 60 filter.addAction(action_onStop); 61 filter.addAction(action_onDestroy); 62 filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED); 63 mContext.registerReceiver(mLifecycleTestBroadcastReceiver, filter); 64 mHasResumedLatch = new CountDownLatch(1); 65 mHasFocusLatch = new CountDownLatch(1); 66 mLostFocusLatch = new CountDownLatch(1); 67 mActivityLifecycleLatch = new CountDownLatch(1); 68 mDestroyLatch = new CountDownLatch(1); 69 mReadyLatch = new CountDownLatch(1); 70 mLostFocusIsLifecycle = false; 71 startTestActivity(TEST_CASE_TYPE); 72 } 73 74 @Override 75 public void tearDown() throws Exception { 76 super.tearDown(); 77 if (mLifecycleTestBroadcastReceiver != null) { 78 mContext.unregisterReceiver(mLifecycleTestBroadcastReceiver); 79 mLifecycleTestBroadcastReceiver = null; 80 } 81 mHasResumedLatch = null; 82 mHasFocusLatch = null; 83 mLostFocusLatch = null; 84 mActivityLifecycleLatch = null; 85 mDestroyLatch = null; 86 mReadyLatch = null; 87 } 88 89 private void waitForOnResume() throws Exception { 90 Log.i(TAG, "waiting for onResume() before continuing"); 91 if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { 92 fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec"); 93 } 94 } 95 96 private void waitForHasFocus() throws Exception { 97 Log.i(TAG, "waiting for window focus gain before continuing"); 98 if (!mHasFocusLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { 99 fail("Activity failed to get focus in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec"); 100 } 101 } 102 103 private void waitForLostFocus() throws Exception { 104 Log.i(TAG, "waiting for window focus lost before continuing"); 105 if (!mLostFocusLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { 106 fail("Activity failed to lose focus in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec"); 107 } 108 } 109 110 private void waitAndSeeIfLifecycleMethodsAreTriggered() throws Exception { 111 if (mActivityLifecycleLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) { 112 fail("One or more lifecycle methods were called after triggering assist"); 113 } 114 } 115 116 private void waitForDestroy() throws Exception { 117 Log.i(TAG, "waiting for activity destroy before continuing"); 118 if (!mDestroyLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { 119 fail("Activity failed to destroy in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec"); 120 } 121 } 122 123 public void testLayerDoesNotTriggerLifecycleMethods() throws Exception { 124 if (mActivityManager.isLowRamDevice()) { 125 Log.d(TAG, "Not running assist tests on low-RAM device."); 126 return; 127 } 128 mTestActivity.startTest(Utils.LIFECYCLE); 129 waitForAssistantToBeReady(mReadyLatch); 130 mTestActivity.start3pApp(Utils.LIFECYCLE); 131 waitForOnResume(); 132 waitForHasFocus(); 133 startSession(); 134 waitForContext(); 135 // Since there is no UI, focus should not be lost. We are counting focus lost as 136 // a lifecycle event in this case. 137 // Do this after waitForContext(), since we don't start looking for context until 138 // calling the above (RACY!!!). 139 waitForLostFocus(); 140 waitAndSeeIfLifecycleMethodsAreTriggered(); 141 mContext.sendBroadcast(new Intent(Utils.HIDE_LIFECYCLE_ACTIVITY)); 142 waitForDestroy(); 143 } 144 145 public void testNoUiLayerDoesNotTriggerLifecycleMethods() throws Exception { 146 if (mActivityManager.isLowRamDevice()) { 147 Log.d(TAG, "Not running assist tests on low-RAM device."); 148 return; 149 } 150 mLostFocusIsLifecycle = true; 151 mTestActivity.startTest(Utils.LIFECYCLE_NOUI); 152 waitForAssistantToBeReady(mReadyLatch); 153 mTestActivity.start3pApp(Utils.LIFECYCLE_NOUI); 154 waitForOnResume(); 155 waitForHasFocus(); 156 startSession(); 157 waitForContext(); 158 // Do this after waitForContext(), since we don't start looking for context until 159 // calling the above (RACY!!!). 160 waitAndSeeIfLifecycleMethodsAreTriggered(); 161 mContext.sendBroadcast(new Intent(Utils.HIDE_LIFECYCLE_ACTIVITY)); 162 waitForDestroy(); 163 } 164 165 private class LifecycleTestReceiver extends BroadcastReceiver { 166 @Override 167 public void onReceive(Context context, Intent intent) { 168 String action = intent.getAction(); 169 if (action.equals(action_hasResumed) && mHasResumedLatch != null) { 170 mHasResumedLatch.countDown(); 171 } else if (action.equals(action_hasFocus) && mHasFocusLatch != null) { 172 mHasFocusLatch.countDown(); 173 } else if (action.equals(action_lostFocus) && mLostFocusLatch != null) { 174 if (mLostFocusIsLifecycle) { 175 mActivityLifecycleLatch.countDown(); 176 } else { 177 mLostFocusLatch.countDown(); 178 } 179 } else if (action.equals(action_onPause) && mActivityLifecycleLatch != null) { 180 mActivityLifecycleLatch.countDown(); 181 } else if (action.equals(action_onStop) && mActivityLifecycleLatch != null) { 182 mActivityLifecycleLatch.countDown(); 183 } else if (action.equals(action_onDestroy) && mActivityLifecycleLatch != null) { 184 mActivityLifecycleLatch.countDown(); 185 mDestroyLatch.countDown(); 186 } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) { 187 if (mReadyLatch != null) { 188 mReadyLatch.countDown(); 189 } 190 } 191 } 192 } 193 } 194