1 /* 2 * Copyright (C) 2020 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.server.wm; 18 19 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 20 import static android.server.wm.WindowManagerState.STATE_STOPPED; 21 import static android.server.wm.app.Components.TEST_ACTIVITY; 22 import static android.server.wm.app.Components.TEST_DREAM_SERVICE; 23 import static android.server.wm.app.Components.TEST_STUBBORN_DREAM_SERVICE; 24 import static android.server.wm.ComponentNameUtils.getWindowName; 25 26 import static org.junit.Assert.assertFalse; 27 import static org.junit.Assert.assertTrue; 28 import static android.view.Display.DEFAULT_DISPLAY; 29 30 import static org.junit.Assume.assumeTrue; 31 32 import android.app.DreamManager; 33 import android.content.ComponentName; 34 import android.platform.test.annotations.Presubmit; 35 import android.provider.Settings; 36 import android.server.wm.app.Components; 37 import android.view.Surface; 38 import android.content.res.Resources; 39 40 import androidx.test.filters.FlakyTest; 41 42 import com.android.compatibility.common.util.SystemUtil; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.Test; 47 48 @Presubmit 49 @FlakyTest(detail = "Promote once confirmed non-flaky") 50 public class DreamManagerServiceTests extends ActivityManagerTestBase { 51 52 // Timeout after which the dream should have finished willingly 53 private static final long ACTIVITY_STOP_TIMEOUT = 3000; 54 55 // Timeout after which the dream should have been forcefully stopped 56 private static final long ACTIVITY_FORCE_STOP_TIMEOUT = 6500; 57 58 private ComponentName mDreamActivityName; 59 60 private boolean mDefaultDreamServiceEnabled = true; 61 getDreamActivityName(ComponentName dream)62 private static final ComponentName getDreamActivityName(ComponentName dream) { 63 return new ComponentName(dream.getPackageName(), 64 "android.service.dreams.DreamActivity"); 65 } 66 67 @Before setup()68 public void setup() { 69 assumeTrue("Skipping test: no dream support", supportsDream()); 70 71 mDefaultDreamServiceEnabled = 72 Settings.Secure.getInt(mContext.getContentResolver(), 73 "screensaver_enabled", 1) != 0; 74 if (!mDefaultDreamServiceEnabled) { 75 SystemUtil.runWithShellPermissionIdentity(() -> { 76 Settings.Secure.putInt(mContext.getContentResolver(), "screensaver_enabled", 1); 77 }); 78 } 79 } 80 81 @After reset()82 public void reset() { 83 if (!mDefaultDreamServiceEnabled) { 84 SystemUtil.runWithShellPermissionIdentity(() -> { 85 Settings.Secure.putInt(mContext.getContentResolver(), "screensaver_enabled", 0); 86 }); 87 } 88 } 89 startDream(ComponentName name)90 private void startDream(ComponentName name) { 91 DreamManager dreamer = mContext.getSystemService(DreamManager.class); 92 SystemUtil.runWithShellPermissionIdentity(() -> { 93 dreamer.startDream(name); 94 }); 95 } 96 stopDream()97 private void stopDream() { 98 DreamManager dreamer = mContext.getSystemService(DreamManager.class); 99 SystemUtil.runWithShellPermissionIdentity(() -> { 100 dreamer.stopDream(); 101 }); 102 } 103 setActiveDream(ComponentName dream)104 private void setActiveDream(ComponentName dream) { 105 DreamManager dreamer = mContext.getSystemService(DreamManager.class); 106 SystemUtil.runWithShellPermissionIdentity(() -> { 107 dreamer.setActiveDream(dream); 108 }); 109 mDreamActivityName = getDreamActivityName(dream); 110 } 111 getIsDreaming()112 private boolean getIsDreaming() { 113 DreamManager dreamer = mContext.getSystemService(DreamManager.class); 114 return SystemUtil.runWithShellPermissionIdentity(() -> { 115 return dreamer.isDreaming(); 116 }); 117 } 118 supportsDream()119 private boolean supportsDream() { 120 return mContext.getResources().getBoolean( 121 Resources.getSystem().getIdentifier("config_dreamsSupported", "bool", "android")); 122 } 123 assertDreamActivityGone()124 private void assertDreamActivityGone() { 125 mWmState.computeState(); 126 assertTrue(!mWmState.containsWindow(getWindowName(mDreamActivityName)) 127 && !mWmState.containsActivity(mDreamActivityName)); 128 } 129 startFullscreenTestActivity()130 private void startFullscreenTestActivity() { 131 launchActivity(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN); 132 waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY, 133 "Test activity should be the top resumed activity"); 134 mWmState.assertVisibility(TEST_ACTIVITY, true); 135 } 136 137 @Test testStartAndStopDream()138 public void testStartAndStopDream() throws Exception { 139 startFullscreenTestActivity(); 140 setActiveDream(TEST_DREAM_SERVICE); 141 142 startDream(TEST_DREAM_SERVICE); 143 waitAndAssertTopResumedActivity(mDreamActivityName, DEFAULT_DISPLAY, 144 "Dream activity should be the top resumed activity"); 145 mWmState.waitForValidState(mWmState.getHomeActivityName()); 146 mWmState.assertVisibility(mWmState.getHomeActivityName(), false); 147 mWmState.waitForValidState(TEST_ACTIVITY); 148 mWmState.assertVisibility(TEST_ACTIVITY, false); 149 150 assertTrue(getIsDreaming()); 151 152 stopDream(); 153 mWmState.waitAndAssertActivityRemoved(mDreamActivityName); 154 155 waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY, 156 "Previous top activity should show when dream is stopped"); 157 } 158 159 @Test testDreamServiceStopsTimely()160 public void testDreamServiceStopsTimely() throws Exception { 161 setActiveDream(TEST_DREAM_SERVICE); 162 163 startDream(TEST_DREAM_SERVICE); 164 waitAndAssertTopResumedActivity(mDreamActivityName, DEFAULT_DISPLAY, 165 "Dream activity should be the top resumed activity"); 166 mWmState.waitForValidState(mWmState.getHomeActivityName()); 167 mWmState.assertVisibility(mWmState.getHomeActivityName(), false); 168 assertTrue(getIsDreaming()); 169 170 stopDream(); 171 172 Thread.sleep(ACTIVITY_STOP_TIMEOUT); 173 174 assertDreamActivityGone(); 175 assertFalse(getIsDreaming()); 176 } 177 178 @Test testForceStopStubbornDream()179 public void testForceStopStubbornDream() throws Exception { 180 startFullscreenTestActivity(); 181 setActiveDream(TEST_STUBBORN_DREAM_SERVICE); 182 183 startDream(TEST_STUBBORN_DREAM_SERVICE); 184 waitAndAssertTopResumedActivity(mDreamActivityName, DEFAULT_DISPLAY, 185 "Dream activity should be the top resumed activity"); 186 mWmState.waitForValidState(mWmState.getHomeActivityName()); 187 mWmState.assertVisibility(mWmState.getHomeActivityName(), false); 188 mWmState.waitForValidState(TEST_ACTIVITY); 189 mWmState.assertVisibility(TEST_ACTIVITY, false); 190 191 stopDream(); 192 193 Thread.sleep(ACTIVITY_FORCE_STOP_TIMEOUT); 194 195 assertDreamActivityGone(); 196 assertFalse(getIsDreaming()); 197 waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY, 198 "Previous top activity should show when dream is stopped"); 199 } 200 201 @Test testDreamNotFinishAfterRotation()202 public void testDreamNotFinishAfterRotation() { 203 assumeTrue("Skipping test: no rotation support", supportsRotation()); 204 205 final RotationSession rotationSession = createManagedRotationSession(); 206 rotationSession.set(Surface.ROTATION_0); 207 setActiveDream(TEST_DREAM_SERVICE); 208 startDream(TEST_DREAM_SERVICE); 209 rotationSession.set(Surface.ROTATION_90); 210 211 waitAndAssertTopResumedActivity(mDreamActivityName, DEFAULT_DISPLAY, 212 "Dream activity should be the top resumed activity"); 213 } 214 215 @Test testStartActivityDoesNotWakeAndIsNotResumed()216 public void testStartActivityDoesNotWakeAndIsNotResumed() { 217 try (DreamingState state = new DreamingState(TEST_DREAM_SERVICE)) { 218 launchActivity(Components.TEST_ACTIVITY); 219 mWmState.waitForActivityState(Components.TEST_ACTIVITY, STATE_STOPPED); 220 assertTrue(getIsDreaming()); 221 } 222 } 223 224 @Test testStartTurnScreenOnActivityDoesWake()225 public void testStartTurnScreenOnActivityDoesWake() { 226 try (DreamingState state = new DreamingState(TEST_DREAM_SERVICE)) { 227 launchActivity(Components.TURN_SCREEN_ON_ACTIVITY); 228 229 state.waitForDreamGone(); 230 waitAndAssertTopResumedActivity(Components.TURN_SCREEN_ON_ACTIVITY, 231 DEFAULT_DISPLAY, "TurnScreenOnActivity should resume through dream"); 232 } 233 } 234 235 @Test testStartTurnScreenOnAttrActivityDoesWake()236 public void testStartTurnScreenOnAttrActivityDoesWake() { 237 try (DreamingState state = new DreamingState(TEST_DREAM_SERVICE)) { 238 launchActivity(Components.TURN_SCREEN_ON_ATTR_ACTIVITY); 239 240 state.waitForDreamGone(); 241 waitAndAssertTopResumedActivity(Components.TURN_SCREEN_ON_ATTR_ACTIVITY, 242 DEFAULT_DISPLAY, "TurnScreenOnAttrActivity should resume through dream"); 243 } 244 } 245 246 @Test testStartActivityOnKeyguardLocked()247 public void testStartActivityOnKeyguardLocked() { 248 assumeTrue(supportsLockScreen()); 249 250 final LockScreenSession lockScreenSession = createManagedLockScreenSession(); 251 lockScreenSession.setLockCredential(); 252 try (DreamingState state = new DreamingState(TEST_DREAM_SERVICE)) { 253 launchActivityNoWait(Components.TEST_ACTIVITY); 254 waitAndAssertActivityState(Components.TEST_ACTIVITY, STATE_STOPPED, 255 "Activity must be started and stopped"); 256 assertTrue(getIsDreaming()); 257 258 launchActivity(Components.TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY); 259 state.waitForDreamGone(); 260 waitAndAssertTopResumedActivity(Components.TURN_SCREEN_ON_SHOW_ON_LOCK_ACTIVITY, 261 DEFAULT_DISPLAY, "TurnScreenOnShowOnLockActivity should resume through dream"); 262 assertFalse(getIsDreaming()); 263 } 264 } 265 266 private class DreamingState implements AutoCloseable { DreamingState(ComponentName dream)267 public DreamingState(ComponentName dream) { 268 setActiveDream(dream); 269 startDream(dream); 270 waitAndAssertDreaming(); 271 } 272 273 @Override close()274 public void close() { 275 stopDream(); 276 } 277 waitAndAssertDreaming()278 public void waitAndAssertDreaming() { 279 waitAndAssertTopResumedActivity(mDreamActivityName, DEFAULT_DISPLAY, 280 "Dream activity should be the top resumed activity"); 281 mWmState.waitForValidState(mWmState.getHomeActivityName()); 282 mWmState.assertVisibility(mWmState.getHomeActivityName(), false); 283 assertTrue(getIsDreaming()); 284 } 285 waitForDreamGone()286 public void waitForDreamGone() { 287 mWmState.waitForDreamGone(); 288 assertFalse(getIsDreaming()); 289 } 290 } 291 } 292