Merge changes from topic "remove-intermediate-callbacks" into sc-v2-dev
* changes: Adds Test that verifies an Activity is Still Reported... Do not send split info update when TaskFragmentContainer Include Activities That Have Not Been Assigned... Update toString methods for various Embedding...
This commit is contained in:
committed by
Android (Google) Code Review
commit
152b410194
@@ -213,6 +213,7 @@ public final class TaskFragmentInfo implements Parcelable {
|
||||
+ " isEmpty=" + mIsEmpty
|
||||
+ " runningActivityCount=" + mRunningActivityCount
|
||||
+ " isVisible=" + mIsVisible
|
||||
+ " activities=" + mActivities
|
||||
+ " positionInParent=" + mPositionInParent
|
||||
+ " isTaskClearedForReuse=" + mIsTaskClearedForReuse
|
||||
+ "}";
|
||||
|
||||
@@ -83,4 +83,13 @@ class SplitContainer {
|
||||
&& ((SplitPairRule) splitRule).shouldFinishSecondaryWithPrimary();
|
||||
return shouldFinishSecondaryWithPrimary || isPlaceholderContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SplitContainer{"
|
||||
+ " primaryContainer=" + mPrimaryContainer
|
||||
+ " secondaryContainer=" + mSecondaryContainer
|
||||
+ " splitRule=" + mSplitRule
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,7 +497,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
return;
|
||||
}
|
||||
List<SplitInfo> currentSplitStates = getActiveSplitStates();
|
||||
if (mLastReportedSplitStates.equals(currentSplitStates)) {
|
||||
if (currentSplitStates == null || mLastReportedSplitStates.equals(currentSplitStates)) {
|
||||
return;
|
||||
}
|
||||
mLastReportedSplitStates.clear();
|
||||
@@ -506,15 +506,19 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of descriptors for currently active split states.
|
||||
* @return a list of descriptors for currently active split states. If the value returned is
|
||||
* null, that indicates that the active split states are in an intermediate state and should
|
||||
* not be reported.
|
||||
*/
|
||||
@Nullable
|
||||
private List<SplitInfo> getActiveSplitStates() {
|
||||
List<SplitInfo> splitStates = new ArrayList<>();
|
||||
for (SplitContainer container : mSplitContainers) {
|
||||
if (container.getPrimaryContainer().isEmpty()
|
||||
|| container.getSecondaryContainer().isEmpty()) {
|
||||
// Skipping containers that do not have any activities to report.
|
||||
continue;
|
||||
// We are in an intermediate state because either the split container is about to be
|
||||
// removed or the primary or secondary container are about to receive an activity.
|
||||
return null;
|
||||
}
|
||||
ActivityStack primaryContainer = container.getPrimaryContainer().toActivityStack();
|
||||
ActivityStack secondaryContainer = container.getSecondaryContainer().toActivityStack();
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.window.TaskFragmentInfo;
|
||||
import android.window.WindowContainerTransaction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -267,4 +268,42 @@ class TaskFragmentContainer {
|
||||
mLastRequestedBounds.set(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(true /* includeContainersToFinishOnExit */);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string for this TaskFragmentContainer and includes containers to finish on exit
|
||||
* based on {@code includeContainersToFinishOnExit}. If containers to finish on exit are always
|
||||
* included in the string, then calling {@link #toString()} on a container that mutually
|
||||
* finishes with another container would cause a stack overflow.
|
||||
*/
|
||||
private String toString(boolean includeContainersToFinishOnExit) {
|
||||
return "TaskFragmentContainer{"
|
||||
+ " token=" + mToken
|
||||
+ " info=" + mInfo
|
||||
+ " topNonFinishingActivity=" + getTopNonFinishingActivity()
|
||||
+ " pendingAppearedActivities=" + mPendingAppearedActivities
|
||||
+ (includeContainersToFinishOnExit ? " containersToFinishOnExit="
|
||||
+ containersToFinishOnExitToString() : "")
|
||||
+ " activitiesToFinishOnExit=" + mActivitiesToFinishOnExit
|
||||
+ " isFinished=" + mIsFinished
|
||||
+ " lastRequestedBounds=" + mLastRequestedBounds
|
||||
+ "}";
|
||||
}
|
||||
|
||||
private String containersToFinishOnExitToString() {
|
||||
StringBuilder sb = new StringBuilder("[");
|
||||
Iterator<TaskFragmentContainer> containerIterator = mContainersToFinishOnExit.iterator();
|
||||
while (containerIterator.hasNext()) {
|
||||
sb.append(containerIterator.next().toString(
|
||||
false /* includeContainersToFinishOnExit */));
|
||||
if (containerIterator.hasNext()) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
return sb.append("]").toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
|
||||
import static android.os.Process.INVALID_UID;
|
||||
import static android.os.UserHandle.USER_NULL;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.WindowManager.TRANSIT_CLOSE;
|
||||
@@ -221,6 +222,8 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
/** Organizer that organizing this TaskFragment. */
|
||||
@Nullable
|
||||
private ITaskFragmentOrganizer mTaskFragmentOrganizer;
|
||||
private int mTaskFragmentOrganizerUid = INVALID_UID;
|
||||
private @Nullable String mTaskFragmentOrganizerProcessName;
|
||||
|
||||
/** Client assigned unique token for this TaskFragment if this is created by an organizer. */
|
||||
@Nullable
|
||||
@@ -233,13 +236,6 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
*/
|
||||
private boolean mDelayLastActivityRemoval;
|
||||
|
||||
/**
|
||||
* The PID of the organizer that created this TaskFragment. It should be the same as the PID
|
||||
* of {@link android.window.TaskFragmentCreationParams#getOwnerToken()}.
|
||||
* {@link ActivityRecord#INVALID_PID} if this is not an organizer-created TaskFragment.
|
||||
*/
|
||||
private int mTaskFragmentOrganizerPid = ActivityRecord.INVALID_PID;
|
||||
|
||||
final Point mLastSurfaceSize = new Point();
|
||||
|
||||
private final Rect mTmpInsets = new Rect();
|
||||
@@ -338,9 +334,11 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
mDelayLastActivityRemoval = false;
|
||||
}
|
||||
|
||||
void setTaskFragmentOrganizer(TaskFragmentOrganizerToken organizer, int pid) {
|
||||
void setTaskFragmentOrganizer(@NonNull TaskFragmentOrganizerToken organizer, int uid,
|
||||
@NonNull String processName) {
|
||||
mTaskFragmentOrganizer = ITaskFragmentOrganizer.Stub.asInterface(organizer.asBinder());
|
||||
mTaskFragmentOrganizerPid = pid;
|
||||
mTaskFragmentOrganizerUid = uid;
|
||||
mTaskFragmentOrganizerProcessName = processName;
|
||||
}
|
||||
|
||||
/** Whether this TaskFragment is organized by the given {@code organizer}. */
|
||||
@@ -2180,9 +2178,11 @@ class TaskFragment extends WindowContainer<WindowContainer> {
|
||||
List<IBinder> childActivities = new ArrayList<>();
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
WindowContainer wc = getChildAt(i);
|
||||
if (mTaskFragmentOrganizerPid != ActivityRecord.INVALID_PID
|
||||
if (mTaskFragmentOrganizerUid != INVALID_UID
|
||||
&& wc.asActivityRecord() != null
|
||||
&& wc.asActivityRecord().getPid() == mTaskFragmentOrganizerPid) {
|
||||
&& wc.asActivityRecord().info.processName.equals(
|
||||
mTaskFragmentOrganizerProcessName)
|
||||
&& wc.asActivityRecord().getUid() == mTaskFragmentOrganizerUid) {
|
||||
// Only includes Activities that belong to the organizer process for security.
|
||||
childActivities.add(wc.asActivityRecord().appToken);
|
||||
}
|
||||
|
||||
@@ -1205,8 +1205,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
||||
creationParams.getFragmentToken(), true /* createdByOrganizer */);
|
||||
// Set task fragment organizer immediately, since it might have to be notified about further
|
||||
// actions.
|
||||
taskFragment.setTaskFragmentOrganizer(
|
||||
creationParams.getOrganizer(), ownerActivity.getPid());
|
||||
taskFragment.setTaskFragmentOrganizer(creationParams.getOrganizer(),
|
||||
ownerActivity.getUid(), ownerActivity.info.processName);
|
||||
ownerActivity.getTask().addChild(taskFragment, POSITION_TOP);
|
||||
taskFragment.setWindowingMode(creationParams.getWindowingMode());
|
||||
taskFragment.setBounds(creationParams.getInitialBounds());
|
||||
|
||||
@@ -254,7 +254,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
});
|
||||
|
||||
// Allow transaction to change a TaskFragment created by the organizer.
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
|
||||
"Test:TaskFragmentOrganizer" /* processName */);
|
||||
|
||||
mAtm.getWindowOrganizerController().applyTransaction(mTransaction);
|
||||
}
|
||||
@@ -276,7 +277,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
});
|
||||
|
||||
// Allow transaction to change a TaskFragment created by the organizer.
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
|
||||
"Test:TaskFragmentOrganizer" /* processName */);
|
||||
|
||||
mAtm.getWindowOrganizerController().applyTransaction(mTransaction);
|
||||
}
|
||||
@@ -301,7 +303,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
});
|
||||
|
||||
// Allow transaction to change a TaskFragment created by the organizer.
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
|
||||
"Test:TaskFragmentOrganizer" /* processName */);
|
||||
clearInvocations(mAtm.mRootWindowContainer);
|
||||
|
||||
mAtm.getWindowOrganizerController().applyTransaction(mTransaction);
|
||||
@@ -337,8 +340,10 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
});
|
||||
|
||||
// Allow transaction to change a TaskFragment created by the organizer.
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
|
||||
taskFragment2.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
|
||||
"Test:TaskFragmentOrganizer" /* processName */);
|
||||
taskFragment2.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
|
||||
"Test:TaskFragmentOrganizer" /* processName */);
|
||||
clearInvocations(mAtm.mRootWindowContainer);
|
||||
|
||||
mAtm.getWindowOrganizerController().applyTransaction(mTransaction);
|
||||
@@ -391,7 +396,8 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase {
|
||||
});
|
||||
|
||||
// Allow transaction to change a TaskFragment created by the organizer.
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* pid */);
|
||||
mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */,
|
||||
"Test:TaskFragmentOrganizer" /* processName */);
|
||||
clearInvocations(mAtm.mRootWindowContainer);
|
||||
|
||||
mAtm.getWindowOrganizerController().applyTransaction(mTransaction);
|
||||
|
||||
@@ -20,12 +20,15 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||
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.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;
|
||||
@@ -64,6 +67,7 @@ public class TaskFragmentTest extends WindowTestsBase {
|
||||
mTaskFragment = new TaskFragmentBuilder(mAtm)
|
||||
.setCreateParentTask()
|
||||
.setOrganizer(mOrganizer)
|
||||
.setFragmentToken(new Binder())
|
||||
.build();
|
||||
mLeash = mTaskFragment.getSurfaceControl();
|
||||
spyOn(mTaskFragment);
|
||||
@@ -103,4 +107,23 @@ public class TaskFragmentTest extends WindowTestsBase {
|
||||
verify(mTransaction).setPosition(mLeash, 500, 500);
|
||||
verify(mTransaction).setWindowCrop(mLeash, 500, 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +128,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
// Default package name
|
||||
static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
|
||||
|
||||
static final int DEFAULT_TASK_FRAGMENT_ORGANIZER_UID = 10000;
|
||||
static final String DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME = "Test:TaskFragmentOrganizer";
|
||||
|
||||
// Default base activity name
|
||||
private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
|
||||
|
||||
@@ -1243,7 +1246,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
|
||||
}
|
||||
if (mOrganizer != null) {
|
||||
taskFragment.setTaskFragmentOrganizer(
|
||||
mOrganizer.getOrganizerToken(), 10000 /* pid */);
|
||||
mOrganizer.getOrganizerToken(), DEFAULT_TASK_FRAGMENT_ORGANIZER_UID,
|
||||
DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
|
||||
}
|
||||
return taskFragment;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user