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