• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.server.wm.ActivityManagerTestBase.createFullscreenActivityScenarioRule;
20 import static android.server.wm.ActivityManagerTestBase.wakeUpAndUnlock;
21 
22 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 
27 import android.app.Instrumentation;
28 import android.graphics.Insets;
29 import android.util.DisplayMetrics;
30 import android.view.MotionEvent;
31 import android.view.WindowInsets;
32 import android.view.WindowMetrics;
33 
34 import androidx.test.InstrumentationRegistry;
35 import androidx.test.ext.junit.rules.ActivityScenarioRule;
36 import androidx.test.runner.AndroidJUnit4;
37 
38 import org.junit.Before;
39 import org.junit.Rule;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 /**
44  * Tests {@link android.view.Window#setCloseOnTouchOutside(boolean)} through exposed Activity API.
45  */
46 @RunWith(AndroidJUnit4.class)
47 public class CloseOnOutsideTests {
48 
49     @Rule
50     public final ActivityScenarioRule<CloseOnOutsideTestActivity> mScenarioRule =
51             createFullscreenActivityScenarioRule(CloseOnOutsideTestActivity.class);
52 
53     private CloseOnOutsideTestActivity mTestActivity;
54 
55     @Before
setup()56     public void setup() {
57         wakeUpAndUnlock(getInstrumentation().getContext());
58         mScenarioRule.getScenario().onActivity(activity -> mTestActivity = activity);
59     }
60 
61     @Test
withDefaults()62     public void withDefaults() {
63         touchAndAssert(false /* shouldBeFinishing */);
64     }
65 
66     @Test
finishTrue()67     public void finishTrue() {
68         mTestActivity.setFinishOnTouchOutside(true);
69         touchAndAssert(true /* shouldBeFinishing */);
70     }
71 
72     @Test
finishFalse()73     public void finishFalse() {
74         mTestActivity.setFinishOnTouchOutside(false);
75         touchAndAssert(false /* shouldBeFinishing */);
76     }
77 
78     // Tap the bottom right and check the Activity is finishing
touchAndAssert(boolean shouldBeFinishing)79     private void touchAndAssert(boolean shouldBeFinishing) {
80         DisplayMetrics displayMetrics =
81                 mTestActivity.getResources().getDisplayMetrics();
82         WindowMetrics windowMetrics =
83                 mTestActivity.getWindowManager().getCurrentWindowMetrics();
84         Insets systemBarInsets =
85                 windowMetrics.getWindowInsets().getInsets(WindowInsets.Type.systemBars());
86         Insets statusBarInsets =
87                 windowMetrics.getWindowInsets().getInsets(WindowInsets.Type.statusBars());
88 
89         // DisplayMetrics.widthPixels and DisplayMetrics.heightPixels
90         // do not include the navigation bar size, so subtract the status bar size.
91         int appAreaWidth =
92                 displayMetrics.widthPixels - statusBarInsets.left - statusBarInsets.right;
93         int appAreaHeight =
94                 displayMetrics.heightPixels - statusBarInsets.top - statusBarInsets.bottom;
95 
96         int width = (int) (systemBarInsets.left + (appAreaWidth * 0.875f));
97         int height = (int) (systemBarInsets.top + (appAreaHeight * 0.875f));
98 
99         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
100 
101         // First setup the new window size to be smaller than the entire activity, "revealing" a
102         // clickable area outside the window.
103         instrumentation.runOnMainSync(() -> mTestActivity.setupWindowSize());
104 
105         // After that call is complete, run the test on the activity by simulating a touch outside
106         // the Window.
107         instrumentation.runOnMainSync(() -> {
108             // To be safe, make sure nothing else is finishing the Activity
109             assertFalse(mTestActivity.isFinishing());
110             mTestActivity.dispatchTouchEvent(
111                     MotionEvent.obtain(1, 1, MotionEvent.ACTION_DOWN, width, height, 0));
112             mTestActivity.dispatchTouchEvent(
113                     MotionEvent.obtain(1, 1, MotionEvent.ACTION_UP, width, height, 0));
114             assertEquals(shouldBeFinishing, mTestActivity.isFinishing());
115         });
116     }
117 }
118