1 /*
2  * Copyright (C) 2019 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 androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
20 
21 import static org.junit.Assume.assumeFalse;
22 import static org.junit.Assume.assumeTrue;
23 
24 import android.app.Activity;
25 import android.app.ActivityManager;
26 import android.content.Context;
27 import android.content.pm.PackageManager;
28 import android.content.res.Configuration;
29 import android.graphics.Insets;
30 import android.util.Log;
31 import android.view.WindowInsets;
32 import android.view.WindowMetrics;
33 
34 import androidx.test.InstrumentationRegistry;
35 import androidx.test.rule.ActivityTestRule;
36 
37 import org.junit.AssumptionViolatedException;
38 
39 /**
40  * Common assumptions for system bar tests.
41  *
42  * TODO: Unify with copy in systemui tests.
43  */
44 public final class BarTestUtils {
45 
BarTestUtils()46     private BarTestUtils() {
47     }
48 
assumeStatusBarContainsCutout(ActivityTestRule<?> rule)49     public static void assumeStatusBarContainsCutout(ActivityTestRule<?> rule) {
50         final boolean[] statusBarContainsCutout = {false};
51         getInstrumentation().runOnMainSync(() -> {
52             final WindowMetrics metrics =
53                     rule.getActivity().getWindowManager().getCurrentWindowMetrics();
54             final WindowInsets windowInsets = metrics.getWindowInsets();
55             final Insets insetsCutout = windowInsets.getInsets(WindowInsets.Type.displayCutout());
56             final Insets insetsStatusBar = windowInsets.getInsets(WindowInsets.Type.statusBars());
57             final Insets min = Insets.min(insetsCutout, insetsStatusBar);
58             statusBarContainsCutout[0] = !Insets.NONE.equals(min);
59         });
60         assumeTrue(statusBarContainsCutout[0]);
61     }
62 
assumeHasColoredStatusBar(ActivityTestRule<?> rule)63     public static void assumeHasColoredStatusBar(ActivityTestRule<?> rule) {
64         assumeHasColoredBars();
65         assumeHasStatusBar(rule);
66     }
67 
assumeHasStatusBar(ActivityTestRule<?> rule)68     public static void assumeHasStatusBar(ActivityTestRule<?> rule) {
69         assumeFalse("No status bar when running in VR", isRunningInVr());
70 
71         assumeTrue("Top stable inset is non-positive, no status bar.",
72                 getInsets(rule).getStableInsetTop() > 0);
73     }
74 
assumeHasColoredNavigationBar(ActivityTestRule<?> rule)75     public static void assumeHasColoredNavigationBar(ActivityTestRule<?> rule) {
76         assumeHasColoredBars();
77 
78         assumeTrue("Bottom stable inset is non-positive, no navigation bar",
79                 getInsets(rule).getStableInsetBottom() > 0);
80     }
81 
assumeHasColoredBars()82     public static void assumeHasColoredBars() {
83         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
84 
85         assumeHasBars();
86 
87         assumeFalse("Automotive navigation bar is opaque",
88                 pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
89 
90         assumeTrue("Only highEndGfx devices have colored system bars",
91                 ActivityManager.isHighEndGfx());
92     }
93 
assumeHasBars()94     public static void assumeHasBars() {
95         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
96 
97         assumeFalse("Embedded devices don't have system bars",
98                 getInstrumentation().getContext().getPackageManager().hasSystemFeature(
99                         PackageManager.FEATURE_EMBEDDED));
100 
101         assumeFalse("No bars on watches and TVs", pm.hasSystemFeature(PackageManager.FEATURE_WATCH)
102                 || pm.hasSystemFeature(PackageManager.FEATURE_TELEVISION)
103                 || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK));
104 
105         assumeFalse("No bars on PCs", pm.hasSystemFeature(PackageManager.FEATURE_PC));
106     }
107 
isRunningInVr()108     private static boolean isRunningInVr() {
109         final Context context = InstrumentationRegistry.getContext();
110         final Configuration config = context.getResources().getConfiguration();
111         return (config.uiMode & Configuration.UI_MODE_TYPE_MASK)
112                 == Configuration.UI_MODE_TYPE_VR_HEADSET;
113     }
114 
getInsets(ActivityTestRule<?> rule)115     private static WindowInsets getInsets(ActivityTestRule<?> rule) {
116         final WindowInsets[] insets = new WindowInsets[1];
117         try {
118             rule.runOnUiThread(() -> {
119                 insets[0] = rule.getActivity().getWindow().getDecorView().getRootWindowInsets();
120             });
121         } catch (Throwable t) {
122             throw new RuntimeException(t);
123         }
124         return insets[0];
125     }
126 
isAssumptionViolated(Runnable assumption)127     public static boolean isAssumptionViolated(Runnable assumption) {
128         try {
129             assumption.run();
130             return false;
131         } catch (AssumptionViolatedException e) {
132             Log.i("BarTestUtils", "Assumption violated", e);
133             return true;
134         }
135     }
136 }
137