1 /*
2  * Copyright (C) 2022 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.server.wm;
18 
19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
21 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
22 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
23 import static android.util.DisplayMetrics.DENSITY_DEFAULT;
24 
25 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
26 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY;
27 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
28 import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
29 
30 import static org.junit.Assert.assertEquals;
31 import static org.mockito.Mockito.mock;
32 
33 import android.platform.test.annotations.Presubmit;
34 
35 import androidx.test.filters.SmallTest;
36 
37 import com.android.server.wm.LaunchParamsController.LaunchParamsModifier.Result;
38 
39 import org.junit.Before;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 /**
44  * Tests for desktop mode task bounds.
45  *
46  * Build/Install/Run:
47  * atest WmTests:DesktopModeLaunchParamsModifierTests
48  */
49 @SmallTest
50 @Presubmit
51 @RunWith(WindowTestRunner.class)
52 public class DesktopModeLaunchParamsModifierTests extends WindowTestsBase {
53 
54     private ActivityRecord mActivity;
55 
56     private DesktopModeLaunchParamsModifier mTarget;
57 
58     private LaunchParamsController.LaunchParams mCurrent;
59     private LaunchParamsController.LaunchParams mResult;
60 
61     @Before
setUp()62     public void setUp() throws Exception {
63         mActivity = new ActivityBuilder(mAtm).build();
64         mTarget = new DesktopModeLaunchParamsModifier();
65         mCurrent = new LaunchParamsController.LaunchParams();
66         mCurrent.reset();
67         mResult = new LaunchParamsController.LaunchParams();
68         mResult.reset();
69     }
70 
71     @Test
testReturnsSkipIfTaskIsNull()72     public void testReturnsSkipIfTaskIsNull() {
73         assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(null).calculate());
74     }
75 
76     @Test
testReturnsSkipIfNotBoundsPhase()77     public void testReturnsSkipIfNotBoundsPhase() {
78         final Task task = new TaskBuilder(mSupervisor).build();
79         assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).setPhase(
80                 PHASE_DISPLAY).calculate());
81     }
82 
83     @Test
testReturnsSkipIfTaskNotUsingActivityTypeStandardOrUndefined()84     public void testReturnsSkipIfTaskNotUsingActivityTypeStandardOrUndefined() {
85         final Task task = new TaskBuilder(mSupervisor).setActivityType(
86                 ACTIVITY_TYPE_ASSISTANT).build();
87         assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).calculate());
88     }
89 
90     @Test
testReturnsDoneIfTaskUsingActivityTypeStandard()91     public void testReturnsDoneIfTaskUsingActivityTypeStandard() {
92         final Task task = new TaskBuilder(mSupervisor).setActivityType(
93                 ACTIVITY_TYPE_STANDARD).build();
94         assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
95     }
96 
97     @Test
testReturnsDoneIfTaskUsingActivityTypeUndefined()98     public void testReturnsDoneIfTaskUsingActivityTypeUndefined() {
99         final Task task = new TaskBuilder(mSupervisor).setActivityType(
100                 ACTIVITY_TYPE_UNDEFINED).build();
101         assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
102     }
103 
104     @Test
testReturnsSkipIfCurrentParamsHasBounds()105     public void testReturnsSkipIfCurrentParamsHasBounds() {
106         final Task task = new TaskBuilder(mSupervisor).setActivityType(
107                 ACTIVITY_TYPE_STANDARD).build();
108         mCurrent.mBounds.set(/* left */ 0, /* top */ 0, /* right */ 100, /* bottom */ 100);
109         assertEquals(RESULT_SKIP, new CalculateRequestBuilder().setTask(task).calculate());
110     }
111 
112     @Test
testUsesDefaultBounds()113     public void testUsesDefaultBounds() {
114         final Task task = new TaskBuilder(mSupervisor).setActivityType(
115                 ACTIVITY_TYPE_STANDARD).build();
116         assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
117         assertEquals(dpiToPx(task, 840), mResult.mBounds.width());
118         assertEquals(dpiToPx(task, 630), mResult.mBounds.height());
119     }
120 
121     @Test
testUsesDisplayAreaAndWindowingModeFromSource()122     public void testUsesDisplayAreaAndWindowingModeFromSource() {
123         final Task task = new TaskBuilder(mSupervisor).setActivityType(
124                 ACTIVITY_TYPE_STANDARD).build();
125         TaskDisplayArea mockTaskDisplayArea = mock(TaskDisplayArea.class);
126         mCurrent.mPreferredTaskDisplayArea = mockTaskDisplayArea;
127         mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
128 
129         assertEquals(RESULT_DONE, new CalculateRequestBuilder().setTask(task).calculate());
130         assertEquals(mockTaskDisplayArea, mResult.mPreferredTaskDisplayArea);
131         assertEquals(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode);
132     }
133 
dpiToPx(Task task, int dpi)134     private int dpiToPx(Task task, int dpi) {
135         float density = (float) task.getConfiguration().densityDpi / DENSITY_DEFAULT;
136         return (int) (dpi * density + 0.5f);
137     }
138 
139     private class CalculateRequestBuilder {
140         private Task mTask;
141         private int mPhase = PHASE_BOUNDS;
142         private final ActivityRecord mActivity =
143                 DesktopModeLaunchParamsModifierTests.this.mActivity;
144         private final LaunchParamsController.LaunchParams mCurrentParams = mCurrent;
145         private final LaunchParamsController.LaunchParams mOutParams = mResult;
146 
setTask(Task task)147         private CalculateRequestBuilder setTask(Task task) {
148             mTask = task;
149             return this;
150         }
151 
setPhase(int phase)152         private CalculateRequestBuilder setPhase(int phase) {
153             mPhase = phase;
154             return this;
155         }
156 
157         @Result
calculate()158         private int calculate() {
159             return mTarget.onCalculate(mTask, /* layout*/ null, mActivity, /* source */
160                     null, /* options */ null, /* request */ null, mPhase, mCurrentParams,
161                     mOutParams);
162         }
163     }
164 }
165