blob: 730275cde40b88978275d6bd96602f9bf52c9d9e [file] [log] [blame]
/*
* Copyright (C) 2021 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.wm;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.clearInvocations;
import android.graphics.Rect;
import android.os.Binder;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl;
import android.window.ITaskFragmentOrganizer;
import android.window.TaskFragmentInfo;
import android.window.TaskFragmentOrganizer;
import androidx.test.filters.MediumTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Test class for {@link TaskFragment}.
*
* Build/Install/Run:
* atest WmTests:TaskFragmentTest
*/
@MediumTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class TaskFragmentTest extends WindowTestsBase {
private TaskFragmentOrganizer mOrganizer;
private TaskFragment mTaskFragment;
private SurfaceControl mLeash;
@Mock
private SurfaceControl.Transaction mTransaction;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mOrganizer = new TaskFragmentOrganizer(Runnable::run);
final ITaskFragmentOrganizer iOrganizer =
ITaskFragmentOrganizer.Stub.asInterface(mOrganizer.getOrganizerToken().asBinder());
mAtm.mWindowOrganizerController.mTaskFragmentOrganizerController
.registerOrganizer(iOrganizer);
mTaskFragment = new TaskFragmentBuilder(mAtm)
.setCreateParentTask()
.setOrganizer(mOrganizer)
.setFragmentToken(new Binder())
.build();
mLeash = mTaskFragment.getSurfaceControl();
spyOn(mTaskFragment);
doReturn(mTransaction).when(mTaskFragment).getSyncTransaction();
doReturn(mTransaction).when(mTaskFragment).getPendingTransaction();
}
@Test
public void testOnConfigurationChanged_updateSurface() {
final Rect bounds = new Rect(100, 100, 1100, 1100);
mTaskFragment.setBounds(bounds);
verify(mTransaction).setPosition(mLeash, 100, 100);
verify(mTransaction).setWindowCrop(mLeash, 1000, 1000);
}
@Test
public void testStartChangeTransition_resetSurface() {
mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
final Rect startBounds = new Rect(0, 0, 1000, 1000);
final Rect endBounds = new Rect(500, 500, 1000, 1000);
mTaskFragment.setBounds(startBounds);
doReturn(true).when(mTaskFragment).isVisible();
doReturn(true).when(mTaskFragment).isVisibleRequested();
clearInvocations(mTransaction);
mTaskFragment.setBounds(endBounds);
// Surface reset when prepare transition.
verify(mTaskFragment).initializeChangeTransition(startBounds);
verify(mTransaction).setPosition(mLeash, 0, 0);
verify(mTransaction).setWindowCrop(mLeash, 0, 0);
clearInvocations(mTransaction);
mTaskFragment.mSurfaceFreezer.unfreeze(mTransaction);
// Update surface after animation.
verify(mTransaction).setPosition(mLeash, 500, 500);
verify(mTransaction).setWindowCrop(mLeash, 500, 500);
}
@Test
public void testNotOkToAnimate_doNotStartChangeTransition() {
mockSurfaceFreezerSnapshot(mTaskFragment.mSurfaceFreezer);
final Rect startBounds = new Rect(0, 0, 1000, 1000);
final Rect endBounds = new Rect(500, 500, 1000, 1000);
mTaskFragment.setBounds(startBounds);
doReturn(true).when(mTaskFragment).isVisible();
doReturn(true).when(mTaskFragment).isVisibleRequested();
final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
displayPolicy.screenTurnedOff();
assertFalse(mTaskFragment.okToAnimate());
mTaskFragment.setBounds(endBounds);
verify(mTaskFragment, never()).initializeChangeTransition(any());
}
/**
* Tests that when a {@link TaskFragmentInfo} is generated from a {@link TaskFragment}, an
* activity that has not yet been attached to a process because it is being initialized but
* belongs to the TaskFragmentOrganizer process is still reported in the TaskFragmentInfo.
*/
@Test
public void testActivityStillReported_NotYetAssignedToProcess() {
mTaskFragment.addChild(new ActivityBuilder(mAtm).setUid(DEFAULT_TASK_FRAGMENT_ORGANIZER_UID)
.setProcessName(DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME).build());
final ActivityRecord activity = mTaskFragment.getTopMostActivity();
// Remove the process to simulate an activity that has not yet been attached to a process
activity.app = null;
final TaskFragmentInfo info = activity.getTaskFragment().getTaskFragmentInfo();
assertEquals(1, info.getRunningActivityCount());
assertEquals(1, info.getActivities().size());
assertEquals(false, info.isEmpty());
assertEquals(activity.token, info.getActivities().get(0));
}
}