1 /* 2 * Copyright (C) 2018 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.internal.policy; 18 19 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 20 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; 21 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; 22 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; 23 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 24 import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY; 25 26 import static org.hamcrest.Matchers.is; 27 import static org.junit.Assert.assertFalse; 28 import static org.junit.Assert.assertThat; 29 import static org.junit.Assert.assertTrue; 30 31 import android.app.Instrumentation; 32 import android.content.Context; 33 import android.graphics.Color; 34 import android.graphics.drawable.ColorDrawable; 35 import android.graphics.drawable.Drawable; 36 import android.os.Binder; 37 import android.platform.test.annotations.Presubmit; 38 import android.platform.test.annotations.RequiresFlagsEnabled; 39 import android.platform.test.flag.junit.CheckFlagsRule; 40 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 41 import android.view.ActionMode; 42 import android.view.ContextThemeWrapper; 43 import android.view.ViewRootImpl; 44 import android.view.WindowManager; 45 46 import androidx.test.InstrumentationRegistry; 47 import androidx.test.filters.SmallTest; 48 import androidx.test.runner.AndroidJUnit4; 49 50 import com.android.frameworks.coretests.R; 51 52 import org.junit.Before; 53 import org.junit.Rule; 54 import org.junit.Test; 55 import org.junit.runner.RunWith; 56 57 /** 58 * Tests {@link PhoneWindow}'s {@link ActionMode} related methods. 59 */ 60 @SmallTest 61 @Presubmit 62 @RunWith(AndroidJUnit4.class) 63 public final class PhoneWindowTest { 64 65 private PhoneWindow mPhoneWindow; 66 private Context mContext; 67 68 private static Instrumentation sInstrumentation = 69 InstrumentationRegistry.getInstrumentation(); 70 71 @Rule 72 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 73 74 @Before setUp()75 public void setUp() throws Exception { 76 mContext = InstrumentationRegistry.getContext(); 77 } 78 79 @Test layoutInDisplayCutoutMode_unset()80 public void layoutInDisplayCutoutMode_unset() throws Exception { 81 createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeUnset); 82 installDecor(); 83 84 assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode, 85 is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT)); 86 } 87 88 @Test layoutInDisplayCutoutMode_default()89 public void layoutInDisplayCutoutMode_default() throws Exception { 90 createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeDefault); 91 installDecor(); 92 93 assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode, 94 is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT)); 95 } 96 97 @Test layoutInDisplayCutoutMode_shortEdges()98 public void layoutInDisplayCutoutMode_shortEdges() throws Exception { 99 createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeShortEdges); 100 installDecor(); 101 102 assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode, 103 is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)); 104 } 105 106 @Test layoutInDisplayCutoutMode_never()107 public void layoutInDisplayCutoutMode_never() throws Exception { 108 createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeNever); 109 installDecor(); 110 111 assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode, 112 is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER)); 113 } 114 115 @Test layoutInDisplayCutoutMode_always()116 public void layoutInDisplayCutoutMode_always() throws Exception { 117 createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeAlways); 118 installDecor(); 119 120 assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode, 121 is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS)); 122 } 123 124 @Test testWindowBackground_colorLiteral()125 public void testWindowBackground_colorLiteral() { 126 createPhoneWindowWithTheme(R.style.WindowBackgroundColorLiteral); 127 installDecor(); 128 129 Drawable backgroundDrawable = mPhoneWindow.getDecorView().getBackground(); 130 assertThat(backgroundDrawable instanceof ColorDrawable, is(true)); 131 132 ColorDrawable colorDrawable = (ColorDrawable) backgroundDrawable; 133 assertThat(colorDrawable.getColor(), is(Color.GREEN)); 134 } 135 136 @Test testWindowBackgroundFallback_colorLiteral()137 public void testWindowBackgroundFallback_colorLiteral() { 138 createPhoneWindowWithTheme(R.style.WindowBackgroundFallbackColorLiteral); 139 installDecor(); 140 141 DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); 142 Drawable fallbackDrawable = decorView.getBackgroundFallback(); 143 144 assertThat(fallbackDrawable instanceof ColorDrawable, is(true)); 145 146 ColorDrawable colorDrawable = (ColorDrawable) fallbackDrawable; 147 assertThat(colorDrawable.getColor(), is(Color.BLUE)); 148 } 149 150 @Test testWindowBackgroundFallbackWithExplicitBackgroundSet_colorLiteral()151 public void testWindowBackgroundFallbackWithExplicitBackgroundSet_colorLiteral() { 152 createPhoneWindowWithTheme(R.style.WindowBackgroundFallbackColorLiteral); 153 // set background before decorView is created 154 mPhoneWindow.setBackgroundDrawable(new ColorDrawable(Color.CYAN)); 155 installDecor(); 156 // clear background so that fallback is used 157 mPhoneWindow.setBackgroundDrawable(null); 158 159 DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); 160 Drawable fallbackDrawable = decorView.getBackgroundFallback(); 161 162 assertThat(fallbackDrawable instanceof ColorDrawable, is(true)); 163 164 ColorDrawable colorDrawable = (ColorDrawable) fallbackDrawable; 165 assertThat(colorDrawable.getColor(), is(Color.BLUE)); 166 } 167 168 @Test 169 @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) testWindowFrameRateHint_disabled()170 public void testWindowFrameRateHint_disabled() { 171 createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedDisabled); 172 installDecor(); 173 174 DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); 175 176 WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY); 177 wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check 178 wmlp.setFrameRatePowerSavingsBalanced( 179 mPhoneWindow.getAttributes().isFrameRatePowerSavingsBalanced()); 180 sInstrumentation.runOnMainSync(() -> { 181 WindowManager wm = mContext.getSystemService(WindowManager.class); 182 wm.addView(decorView, wmlp); 183 }); 184 sInstrumentation.waitForIdleSync(); 185 186 ViewRootImpl viewRootImpl = decorView.getViewRootImpl(); 187 assertFalse(viewRootImpl.isFrameRatePowerSavingsBalanced()); 188 } 189 190 @Test 191 @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) testWindowFrameRateHint_enabled()192 public void testWindowFrameRateHint_enabled() { 193 createPhoneWindowWithTheme(R.style.IsFrameRatePowerSavingsBalancedEnabled); 194 installDecor(); 195 196 DecorView decorView = (DecorView) mPhoneWindow.getDecorView(); 197 198 WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY); 199 wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check 200 wmlp.setFrameRatePowerSavingsBalanced( 201 mPhoneWindow.getAttributes().isFrameRatePowerSavingsBalanced()); 202 sInstrumentation.runOnMainSync(() -> { 203 WindowManager wm = mContext.getSystemService(WindowManager.class); 204 wm.addView(decorView, wmlp); 205 }); 206 sInstrumentation.waitForIdleSync(); 207 208 ViewRootImpl viewRootImpl = decorView.getViewRootImpl(); 209 assertTrue(viewRootImpl.isFrameRatePowerSavingsBalanced()); 210 } 211 createPhoneWindowWithTheme(int theme)212 private void createPhoneWindowWithTheme(int theme) { 213 mPhoneWindow = new PhoneWindow(new ContextThemeWrapper(mContext, theme)); 214 } 215 installDecor()216 private void installDecor() { 217 mPhoneWindow.getDecorView(); 218 } 219 }