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 17package com.android.setupwizardlib.test; 18 19import android.annotation.SuppressLint; 20import android.app.Dialog; 21import android.content.Context; 22import android.os.Build.VERSION; 23import android.os.Build.VERSION_CODES; 24import android.os.Handler; 25import android.os.HandlerThread; 26import android.os.SystemClock; 27import android.test.AndroidTestCase; 28import android.test.suitebuilder.annotation.SmallTest; 29import android.view.View; 30import android.view.Window; 31import android.view.WindowManager; 32 33import com.android.setupwizardlib.test.util.MockWindow; 34import com.android.setupwizardlib.util.SystemBarHelper; 35 36public class SystemBarHelperTest extends AndroidTestCase { 37 38 private static final int STATUS_BAR_DISABLE_BACK = 0x00400000; 39 40 @SuppressLint("InlinedApi") 41 private static final int DEFAULT_IMMERSIVE_FLAGS = 42 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 43 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 44 | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 45 | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; 46 47 @SuppressLint("InlinedApi") 48 private static final int DIALOG_IMMERSIVE_FLAGS = 49 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 50 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; 51 52 @SmallTest 53 public void testAddVisibilityFlagView() { 54 final View view = createViewWithSystemUiVisibility(0x456); 55 SystemBarHelper.addVisibilityFlag(view, 0x1400); 56 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 57 // Check that result is 0x1456, because 0x1400 | 0x456 = 0x1456. 58 assertEquals("View visibility should be 0x1456", 0x1456, view.getSystemUiVisibility()); 59 } 60 } 61 62 @SmallTest 63 public void testRemoveVisibilityFlagView() { 64 final View view = createViewWithSystemUiVisibility(0x456); 65 SystemBarHelper.removeVisibilityFlag(view, 0x1400); 66 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 67 // Check that result is 0x56, because 0x456 & ~0x1400 = 0x56. 68 assertEquals("View visibility should be 0x56", 0x56, view.getSystemUiVisibility()); 69 } 70 } 71 72 @SmallTest 73 public void testAddVisibilityFlagWindow() { 74 final Window window = createWindowWithSystemUiVisibility(0x456); 75 SystemBarHelper.addVisibilityFlag(window, 0x1400); 76 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 77 // Check that result is 0x1456 = 0x1400 | 0x456. 78 assertEquals("View visibility should be 0x1456", 0x1456, 79 window.getAttributes().systemUiVisibility); 80 } 81 } 82 83 @SmallTest 84 public void testRemoveVisibilityFlagWindow() { 85 final Window window = createWindowWithSystemUiVisibility(0x456); 86 SystemBarHelper.removeVisibilityFlag(window, 0x1400); 87 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 88 // Check that result is 0x56 = 0x456 & ~0x1400. 89 assertEquals("View visibility should be 0x56", 0x56, 90 window.getAttributes().systemUiVisibility); 91 } 92 } 93 94 @SmallTest 95 public void testHideSystemBarsWindow() { 96 final Window window = createWindowWithSystemUiVisibility(0x456); 97 SystemBarHelper.hideSystemBars(window); 98 if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { 99 assertEquals("DEFAULT_IMMERSIVE_FLAGS should be added to window's systemUiVisibility", 100 DEFAULT_IMMERSIVE_FLAGS | 0x456, 101 window.getAttributes().systemUiVisibility); 102 assertEquals( 103 "DEFAULT_IMMERSIVE_FLAGS should be added to decorView's systemUiVisibility", 104 DEFAULT_IMMERSIVE_FLAGS | 0x456, 105 window.getDecorView().getSystemUiVisibility()); 106 assertEquals("Navigation bar should be transparent", window.getNavigationBarColor(), 0); 107 assertEquals("Status bar should be transparent", window.getStatusBarColor(), 0); 108 } 109 } 110 111 @SmallTest 112 public void testShowSystemBarsWindow() { 113 final Window window = createWindowWithSystemUiVisibility(0x456); 114 SystemBarHelper.showSystemBars(window, getContext()); 115 if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { 116 assertEquals( 117 "DEFAULT_IMMERSIVE_FLAGS should be removed from window's systemUiVisibility", 118 0x456 & ~DEFAULT_IMMERSIVE_FLAGS, 119 window.getAttributes().systemUiVisibility); 120 assertEquals( 121 "DEFAULT_IMMERSIVE_FLAGS should be removed from decorView's systemUiVisibility", 122 0x456 & ~DEFAULT_IMMERSIVE_FLAGS, 123 window.getDecorView().getSystemUiVisibility()); 124 assertEquals("Navigation bar should not be transparent", 125 window.getNavigationBarColor(), 0xff000000); 126 assertEquals("Status bar should not be transparent", 127 window.getStatusBarColor(), 0xff000000); 128 } 129 } 130 131 @SmallTest 132 public void testHideSystemBarsNoInfiniteLoop() throws InterruptedException { 133 final TestWindow window = new TestWindow(getContext(), null); 134 final HandlerThread thread = new HandlerThread("SystemBarHelperTest"); 135 thread.start(); 136 final Handler handler = new Handler(thread.getLooper()); 137 handler.post(new Runnable() { 138 @Override 139 public void run() { 140 SystemBarHelper.hideSystemBars(window); 141 } 142 }); 143 SystemClock.sleep(500); // Wait for the looper to drain all the messages 144 thread.quit(); 145 // Initial peek + 3 retries = 4 tries total 146 if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { 147 assertEquals("Peek decor view should give up after 4 tries", 4, 148 window.peekDecorViewCount); 149 } 150 } 151 152 @SmallTest 153 public void testHideSystemBarsDialog() { 154 final Dialog dialog = new Dialog(mContext); 155 if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { 156 final WindowManager.LayoutParams attrs = dialog.getWindow().getAttributes(); 157 attrs.systemUiVisibility = 0x456; 158 dialog.getWindow().setAttributes(attrs); 159 } 160 161 SystemBarHelper.hideSystemBars(dialog); 162 if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { 163 assertEquals("DIALOG_IMMERSIVE_FLAGS should be added to window's systemUiVisibility", 164 DIALOG_IMMERSIVE_FLAGS | 0x456, 165 dialog.getWindow().getAttributes().systemUiVisibility); 166 } 167 } 168 169 @SmallTest 170 public void testSetBackButtonVisibleTrue() { 171 final Window window = createWindowWithSystemUiVisibility(0x456); 172 SystemBarHelper.setBackButtonVisible(window, true); 173 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 174 assertEquals("View visibility should be 0x456", 0x456, 175 window.getAttributes().systemUiVisibility); 176 } 177 } 178 179 @SmallTest 180 public void testSetBackButtonVisibleFalse() { 181 final Window window = createWindowWithSystemUiVisibility(0x456); 182 SystemBarHelper.setBackButtonVisible(window, false); 183 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 184 assertEquals("STATUS_BAR_DISABLE_BACK should be added to systemUiVisibility", 185 0x456 | STATUS_BAR_DISABLE_BACK, window.getAttributes().systemUiVisibility); 186 } 187 } 188 189 private View createViewWithSystemUiVisibility(int vis) { 190 final View view = new View(getContext()); 191 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 192 view.setSystemUiVisibility(vis); 193 } 194 return view; 195 } 196 197 private Window createWindowWithSystemUiVisibility(int vis) { 198 final Window window = new TestWindow(getContext(), createViewWithSystemUiVisibility(vis)); 199 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 200 WindowManager.LayoutParams attrs = window.getAttributes(); 201 attrs.systemUiVisibility = vis; 202 window.setAttributes(attrs); 203 } 204 return window; 205 } 206 207 private static class TestWindow extends MockWindow { 208 209 private View mDecorView; 210 public int peekDecorViewCount = 0; 211 212 private int mNavigationBarColor = -1; 213 private int mStatusBarColor = -1; 214 215 public TestWindow(Context context, View decorView) { 216 super(context); 217 mDecorView = decorView; 218 } 219 220 @Override 221 public View getDecorView() { 222 return mDecorView; 223 } 224 225 @Override 226 public View peekDecorView() { 227 peekDecorViewCount++; 228 return mDecorView; 229 } 230 231 @Override 232 public void setNavigationBarColor(int i) { 233 mNavigationBarColor = i; 234 } 235 236 @Override 237 public int getNavigationBarColor() { 238 return mNavigationBarColor; 239 } 240 241 @Override 242 public void setStatusBarColor(int i) { 243 mStatusBarColor = i; 244 } 245 246 @Override 247 public int getStatusBarColor() { 248 return mStatusBarColor; 249 } 250 } 251} 252