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 com.android.quickstep; 18 19 import static androidx.test.InstrumentationRegistry.getInstrumentation; 20 21 import static com.android.quickstep.TaskbarModeSwitchRule.Mode.ALL; 22 import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; 23 import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT; 24 25 import android.content.Context; 26 import android.util.Log; 27 28 import com.android.launcher3.tapl.LauncherInstrumentation; 29 import com.android.launcher3.tapl.TestHelpers; 30 import com.android.launcher3.ui.AbstractLauncherUiTest; 31 import com.android.launcher3.util.DisplayController; 32 import com.android.launcher3.util.rule.FailureWatcher; 33 34 import org.junit.rules.TestRule; 35 import org.junit.runner.Description; 36 import org.junit.runners.model.Statement; 37 38 import java.lang.annotation.ElementType; 39 import java.lang.annotation.Retention; 40 import java.lang.annotation.RetentionPolicy; 41 import java.lang.annotation.Target; 42 43 /** 44 * Test rule that allows executing a test multiple times with different conditions 45 * ie. with transient taskbar enabled and disabled. 46 * The test should be annotated with @TaskbarModeSwitch. 47 */ 48 public class TaskbarModeSwitchRule implements TestRule { 49 50 static final String TAG = "TaskbarModeSwitchRule"; 51 52 public static final int WAIT_TIME_MS = 10000; 53 54 public enum Mode { 55 TRANSIENT, PERSISTENT, ALL 56 } 57 58 // Annotation for tests that need to be run with quickstep enabled and disabled. 59 @Retention(RetentionPolicy.RUNTIME) 60 @Target(ElementType.METHOD) 61 public @interface TaskbarModeSwitch { mode()62 Mode mode() default ALL; 63 } 64 65 private final LauncherInstrumentation mLauncher; 66 TaskbarModeSwitchRule(LauncherInstrumentation launcher)67 public TaskbarModeSwitchRule(LauncherInstrumentation launcher) { 68 mLauncher = launcher; 69 } 70 71 @Override apply(Statement base, Description description)72 public Statement apply(Statement base, Description description) { 73 if (TestHelpers.isInLauncherProcess() 74 && description.getAnnotation(TaskbarModeSwitch.class) != null) { 75 Mode mode = description.getAnnotation(TaskbarModeSwitch.class).mode(); 76 return new Statement() { 77 @Override 78 public void evaluate() throws Throwable { 79 mLauncher.enableDebugTracing(); 80 final boolean wasTransientTaskbarMode = 81 isTaskbarTransientMode(getInstrumentation().getTargetContext()); 82 try { 83 if (mode == TRANSIENT || mode == ALL) { 84 evaluateWithTransientTaskbar(); 85 } 86 if (mode == PERSISTENT || mode == ALL) { 87 evaluateWithPersistentTaskbar(); 88 } 89 } catch (Throwable e) { 90 Log.e(TAG, "Error", e); 91 throw e; 92 } finally { 93 Log.d(TAG, "In Finally block"); 94 setTaskbarMode(mLauncher, wasTransientTaskbarMode, description); 95 } 96 } 97 98 private void evaluateWithPersistentTaskbar() throws Throwable { 99 setTaskbarMode(mLauncher, false, description); 100 base.evaluate(); 101 } 102 103 private void evaluateWithTransientTaskbar() throws Throwable { 104 setTaskbarMode(mLauncher, true, description); 105 base.evaluate(); 106 } 107 }; 108 } else { 109 return base; 110 } 111 } 112 113 private static boolean isTaskbarTransientMode(Context context) { 114 return DisplayController.isTransientTaskbar(context); 115 } 116 117 public static void setTaskbarMode(LauncherInstrumentation launcher, 118 boolean expectTransientTaskbar, Description description) throws Exception { 119 launcher.enableTransientTaskbar(expectTransientTaskbar); 120 launcher.recreateTaskbar(); 121 122 Context context = getInstrumentation().getTargetContext(); 123 assertTrue(launcher, "Couldn't set taskbar=" + expectTransientTaskbar, 124 isTaskbarTransientMode(context) == expectTransientTaskbar, description); 125 126 AbstractLauncherUiTest.checkDetectedLeaks(launcher, true); 127 } 128 129 private static void assertTrue(LauncherInstrumentation launcher, String message, 130 boolean condition, Description description) { 131 launcher.checkForAnomaly(true, true); 132 if (!condition) { 133 if (description != null) { 134 FailureWatcher.onError(launcher, description); 135 } 136 throw new AssertionError(message); 137 } 138 } 139 } 140