blob: 161c2875bf496f89a4a96192125ef9711874242c [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.server.am;
import android.app.ActivityOptions;
import android.content.pm.ActivityInfo.WindowLayout;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import com.android.server.am.LaunchParamsController.LaunchParams;
import org.junit.runner.RunWith;
import org.junit.Before;
import org.junit.Test;
import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
/**
* Tests for exercising {@link LaunchParamsController}.
*
* Build/Install/Run:
* atest FrameworksServicesTests:LaunchParamsControllerTests
*/
@MediumTest
@Presubmit
@RunWith(AndroidJUnit4.class)
public class LaunchParamsControllerTests extends ActivityTestsBase {
private ActivityManagerService mService;
private LaunchParamsController mController;
@Before
@Override
public void setUp() throws Exception {
super.setUp();
mService = createActivityManagerService();
mController = new LaunchParamsController(mService);
}
/**
* Makes sure positioners get values passed to controller.
*/
@Test
public void testArgumentPropagation() {
final LaunchParamsModifier
positioner = mock(LaunchParamsModifier.class);
mController.registerModifier(positioner);
final ActivityRecord record = new ActivityBuilder(mService).build();
final ActivityRecord source = new ActivityBuilder(mService).build();
final WindowLayout layout = new WindowLayout(0, 0, 0, 0, 0, 0, 0);
final ActivityOptions options = mock(ActivityOptions.class);
mController.calculate(record.getTask(), layout, record, source, options,
new LaunchParams());
verify(positioner, times(1)).onCalculate(eq(record.getTask()), eq(layout), eq(record),
eq(source), eq(options), any(), any());
}
/**
* Ensures positioners further down the chain are not called when RESULT_DONE is returned.
*/
@Test
public void testEarlyExit() {
final LaunchParamsModifier
ignoredPositioner = mock(LaunchParamsModifier.class);
final LaunchParamsModifier earlyExitPositioner =
(task, layout, activity, source, options, currentParams, outParams) -> RESULT_DONE;
mController.registerModifier(ignoredPositioner);
mController.registerModifier(earlyExitPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
null /*source*/, null /*options*/, new LaunchParams());
verify(ignoredPositioner, never()).onCalculate(any(), any(), any(), any(), any(),
any(), any());
}
/**
* Ensures that positioners are called in the correct order.
*/
@Test
public void testRegistration() {
LaunchParamsModifier earlyExitPositioner =
new InstrumentedPositioner(RESULT_DONE, new LaunchParams());
final LaunchParamsModifier firstPositioner = spy(earlyExitPositioner);
mController.registerModifier(firstPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
null /*source*/, null /*options*/, new LaunchParams());
verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(),
any());
final LaunchParamsModifier secondPositioner = spy(earlyExitPositioner);
mController.registerModifier(secondPositioner);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/,
null /*source*/, null /*options*/, new LaunchParams());
verify(firstPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(),
any());
verify(secondPositioner, times(1)).onCalculate(any(), any(), any(), any(), any(), any(),
any());
}
/**
* Makes sure positioners further down the registration chain are called.
*/
@Test
public void testPassThrough() {
final LaunchParamsModifier
positioner1 = mock(LaunchParamsModifier.class);
final LaunchParams params = new LaunchParams();
params.mWindowingMode = WINDOWING_MODE_FREEFORM;
params.mBounds.set(0, 0, 30, 20);
params.mPreferredDisplayId = 3;
final InstrumentedPositioner positioner2 = new InstrumentedPositioner(RESULT_CONTINUE,
params);
mController.registerModifier(positioner1);
mController.registerModifier(positioner2);
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
null /*options*/, new LaunchParams());
verify(positioner1, times(1)).onCalculate(any(), any(), any(), any(), any(),
eq(positioner2.getLaunchParams()), any());
}
/**
* Ensures skipped results are not propagated.
*/
@Test
public void testSkip() {
final LaunchParams params1 = new LaunchParams();
params1.mBounds.set(0, 0, 10, 10);
final InstrumentedPositioner positioner1 = new InstrumentedPositioner(RESULT_SKIP, params1);
final LaunchParams params2 = new LaunchParams();
params2.mBounds.set(0, 0, 20, 30);
final InstrumentedPositioner positioner2 =
new InstrumentedPositioner(RESULT_CONTINUE, params2);
mController.registerModifier(positioner1);
mController.registerModifier(positioner2);
final LaunchParams
result = new LaunchParams();
mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
null /*options*/, result);
assertEquals(result, positioner2.getLaunchParams());
}
/**
* Ensures that {@link LaunchParamsModifier} requests specifying display id during
* layout are honored.
*/
@Test
public void testLayoutTaskPreferredDisplayChange() {
final LaunchParams params = new LaunchParams();
params.mPreferredDisplayId = 2;
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
final TaskRecord task = new TaskBuilder(mService.mStackSupervisor).build();
mController.registerModifier(positioner);
doNothing().when(mService).moveStackToDisplay(anyInt(), anyInt());
mController.layoutTask(task, null /* windowLayout */);
verify(mService, times(1)).moveStackToDisplay(eq(task.getStackId()),
eq(params.mPreferredDisplayId));
}
/**
* Ensures that {@link LaunchParamsModifier} requests specifying windowingMode during
* layout are honored.
*/
@Test
public void testLayoutTaskWindowingModeChange() {
final LaunchParams params = new LaunchParams();
final int windowingMode = WINDOWING_MODE_FREEFORM;
params.mWindowingMode = windowingMode;
final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
final TaskRecord task = new TaskBuilder(mService.mStackSupervisor).build();
mController.registerModifier(positioner);
final int beforeWindowMode = task.getStack().getWindowingMode();
assertNotEquals(beforeWindowMode, windowingMode);
mController.layoutTask(task, null /* windowLayout */);
final int afterWindowMode = task.getStack().getWindowingMode();
assertEquals(afterWindowMode, windowingMode);
}
public static class InstrumentedPositioner implements
LaunchParamsModifier {
final private int mReturnVal;
final private LaunchParams mParams;
InstrumentedPositioner(int returnVal, LaunchParams params) {
mReturnVal = returnVal;
mParams = params;
}
@Override
public int onCalculate(TaskRecord task, WindowLayout layout, ActivityRecord activity,
ActivityRecord source, ActivityOptions options,
LaunchParams currentParams, LaunchParams outParams) {
outParams.set(mParams);
return mReturnVal;
}
LaunchParams getLaunchParams() {
return mParams;
}
}
}