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.server.wm.WindowMetricsTestHelper.assertMetricsMatchesLayout; 20 import static android.server.wm.WindowMetricsTestHelper.assertMetricsValidity; 21 import static android.view.Display.DEFAULT_DISPLAY; 22 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; 23 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 24 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 25 26 import android.content.Context; 27 import android.graphics.PixelFormat; 28 import android.graphics.Point; 29 import android.graphics.Rect; 30 import android.hardware.display.DisplayManager; 31 import android.os.Bundle; 32 import android.platform.test.annotations.Presubmit; 33 import android.server.wm.WindowMetricsTestHelper.OnLayoutChangeListener; 34 import android.view.Display; 35 import android.view.View; 36 import android.view.WindowManager; 37 import android.view.WindowMetrics; 38 39 import androidx.test.core.app.ApplicationProvider; 40 import androidx.test.platform.app.InstrumentationRegistry; 41 42 import com.android.compatibility.common.util.ApiTest; 43 44 import org.junit.Test; 45 46 /** 47 * Tests that verify the behavior of {@link WindowMetrics} APIs on {@link Context contexts} created 48 * from {@link Context#createWindowContext(Display, int, Bundle)}. 49 * 50 * Build/Install/Run: 51 * atest CtsWindowManagerDeviceTestCases:WindowMetricsWindowContextTests 52 */ 53 @Presubmit 54 @ApiTest(apis = {"android.view.WindowManager#getCurrentWindowMetrics", 55 "android.view.WindowManager#getMaximumWindowMetrics", 56 "android.content.Context#createWindowContext"}) 57 public class WindowMetricsWindowContextTests extends WindowManagerTestBase { 58 @Test testMetricsMatchesLayoutOnWindowContext()59 public void testMetricsMatchesLayoutOnWindowContext() { 60 createAllowSystemAlertWindowAppOpSession(); 61 final WindowContextTestSession mWindowContextSession = 62 mObjectTracker.manage(new WindowContextTestSession()); 63 64 mWindowContextSession.assertWindowContextMetricsMatchesLayout(); 65 } 66 67 @Test testMetricsMatchesDisplayAreaOnWindowContext()68 public void testMetricsMatchesDisplayAreaOnWindowContext() { 69 createAllowSystemAlertWindowAppOpSession(); 70 final WindowContextTestSession mWindowContextSession = 71 mObjectTracker.manage(new WindowContextTestSession()); 72 73 mWindowContextSession.assertWindowContextMetricsMatchesDisplayArea(); 74 } 75 76 private class WindowContextTestSession implements AutoCloseable { 77 private static final String TEST_WINDOW_NAME = "WindowMetricsTests"; 78 private View mView; 79 private final Context mWindowContext; 80 private final WindowManager mWm; 81 private final OnLayoutChangeListener mListener = new OnLayoutChangeListener(); 82 WindowContextTestSession()83 private WindowContextTestSession() { 84 final Context appContext = ApplicationProvider.getApplicationContext(); 85 final Display display = appContext.getSystemService(DisplayManager.class) 86 .getDisplay(DEFAULT_DISPLAY); 87 mWindowContext = appContext.createDisplayContext(display) 88 .createWindowContext(TYPE_APPLICATION_OVERLAY, null /* options */); 89 90 mWm = mWindowContext.getSystemService(WindowManager.class); 91 92 InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { 93 mView = new View(mWindowContext); 94 mView.addOnLayoutChangeListener(mListener); 95 final WindowManager.LayoutParams params = getFullscreenOverlayAttributes(); 96 mWm.addView(mView, params); 97 }); 98 } 99 assertWindowContextMetricsMatchesLayout()100 private void assertWindowContextMetricsMatchesLayout() { 101 mListener.waitForLayout(); 102 103 final WindowMetrics currentMetrics = mWm.getCurrentWindowMetrics(); 104 final WindowMetrics maxMetrics = mWm.getMaximumWindowMetrics(); 105 106 assertMetricsMatchesLayout(currentMetrics, maxMetrics, 107 mListener.getLayoutBounds(), mListener.getLayoutInsets()); 108 } 109 110 /** 111 * Verifies two scenarios for a {@link android.window.WindowContext}. 112 * <ul> 113 * <li>{@link WindowManager#getCurrentWindowMetrics()} matches 114 * {@link Display#getSize(Point)}</li> 115 * <li>{@link WindowManager#getMaximumWindowMetrics()} and 116 * {@link Display#getSize(Point)} either matches DisplayArea bounds, or matches 117 * {@link WindowManager#getCurrentWindowMetrics()} if sandboxing is applied.</li> 118 * </ul> 119 */ assertWindowContextMetricsMatchesDisplayArea()120 private void assertWindowContextMetricsMatchesDisplayArea() { 121 mWmState.computeState(); 122 WindowManagerState.DisplayArea da = mWmState.getDisplayArea(TEST_WINDOW_NAME); 123 final Rect daBounds = da.mFullConfiguration.windowConfiguration.getBounds(); 124 assertMetricsValidity(mWindowContext, daBounds); 125 } 126 127 @Override close()128 public void close() throws Exception { 129 InstrumentationRegistry.getInstrumentation().runOnMainSync(() 130 -> mWm.removeViewImmediate(mView)); 131 mView.removeOnLayoutChangeListener(mListener); 132 } 133 getFullscreenOverlayAttributes()134 private WindowManager.LayoutParams getFullscreenOverlayAttributes() { 135 final WindowManager.LayoutParams params = new WindowManager.LayoutParams( 136 MATCH_PARENT, MATCH_PARENT, TYPE_APPLICATION_OVERLAY, 0, 137 PixelFormat.TRANSLUCENT); 138 // Used for obtain the attached DisplayArea. 139 params.setTitle(TEST_WINDOW_NAME); 140 params.setFitInsetsTypes(0 /* types */); 141 params.setFitInsetsIgnoringVisibility(true); 142 params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 143 return params; 144 } 145 } 146 } 147