1/*
2 * Copyright (C) 2017 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
17package com.android.server.am;
18
19import android.app.ActivityOptions;
20import android.content.pm.ActivityInfo;
21import android.graphics.Rect;
22import android.platform.test.annotations.Presubmit;
23import android.support.test.filters.MediumTest;
24import android.support.test.runner.AndroidJUnit4;
25
26import com.android.server.am.LaunchParamsController.LaunchParams;
27import org.junit.runner.RunWith;
28import org.junit.Before;
29import org.junit.Test;
30
31import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
32import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
33import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
34import static org.junit.Assert.assertEquals;
35import static org.junit.Assert.assertFalse;
36import static org.junit.Assert.assertTrue;
37import static org.mockito.Mockito.spy;
38import static org.mockito.Mockito.doAnswer;
39
40import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
41
42/**
43 * Tests for exercising resizing bounds due to activity options.
44 *
45 * Build/Install/Run:
46 *  atest FrameworksServicesTests:ActivityLaunchParamsModifierTests
47 */
48@MediumTest
49@Presubmit
50@RunWith(AndroidJUnit4.class)
51public class ActivityLaunchParamsModifierTests extends ActivityTestsBase {
52    private ActivityLaunchParamsModifier mModifier;
53    private ActivityManagerService mService;
54    private ActivityStack mStack;
55    private TaskRecord mTask;
56    private ActivityRecord mActivity;
57
58    private LaunchParams mCurrent;
59    private LaunchParams mResult;
60
61    @Before
62    @Override
63    public void setUp() throws Exception {
64        super.setUp();
65        mService = createActivityManagerService();
66        mModifier = new ActivityLaunchParamsModifier(mService.mStackSupervisor);
67        mCurrent = new LaunchParams();
68        mResult = new LaunchParams();
69
70
71        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
72                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
73        mTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
74        mActivity = new ActivityBuilder(mService).setTask(mTask).build();
75    }
76
77
78    @Test
79    public void testSkippedInvocations() throws Exception {
80        // No specified activity should be ignored
81        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
82                null /*activity*/, null /*source*/, null /*options*/, mCurrent, mResult));
83
84        // No specified activity options should be ignored
85        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
86                mActivity, null /*source*/, null /*options*/, mCurrent, mResult));
87
88        // launch bounds specified should be ignored.
89        final ActivityOptions options = ActivityOptions.makeBasic();
90        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
91                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
92
93        // Non-resizeable records should be ignored
94        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
95        assertFalse(mActivity.isResizeable());
96        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
97                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
98
99        // make record resizeable
100        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
101        assertTrue(mActivity.isResizeable());
102
103        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
104                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
105
106        // Does not support freeform
107        mService.mSupportsFreeformWindowManagement = false;
108        assertFalse(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
109        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
110                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
111
112        mService.mSupportsFreeformWindowManagement = true;
113        options.setLaunchBounds(new Rect());
114        assertTrue(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
115
116        // Invalid bounds
117        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
118                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
119        options.setLaunchBounds(new Rect(0, 0, -1, -1));
120        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
121                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
122
123        // Valid bounds should cause the positioner to be applied.
124        options.setLaunchBounds(new Rect(0, 0, 100, 100));
125        assertEquals(RESULT_DONE, mModifier.onCalculate(null /*task*/, null /*layout*/,
126                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
127    }
128
129    @Test
130    public void testBoundsExtraction() throws Exception {
131        // Make activity resizeable and enable freeform mode.
132        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
133        mService.mSupportsFreeformWindowManagement = true;
134
135        ActivityOptions options = ActivityOptions.makeBasic();
136        final Rect proposedBounds = new Rect(20, 30, 45, 40);
137        options.setLaunchBounds(proposedBounds);
138
139        assertEquals(RESULT_DONE, mModifier.onCalculate(null /*task*/, null /*layout*/,
140                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
141        assertEquals(mResult.mBounds, proposedBounds);
142    }
143}
144