Send TaskFragmentParentInfo for visibility changes

This CL propagates visibility from Activity to Task, and dispatch
 #onTaskFragmentParentInfoChanged is there's a task visiblity
update. This CL also send the callback when the associated Display
of Task changes.

Test: atest TaskFragmentOrganizerControllerTest
fixes: 243609832

Change-Id: I3b0198cfd11a3ec4917f92d0a1e540cf16827d08
This commit is contained in:
Charles Chen
2022-09-14 01:00:04 +08:00
parent a13ffe82ff
commit 6012e9b748
6 changed files with 129 additions and 5 deletions

View File

@@ -97,6 +97,34 @@ public class TaskFragmentParentInfo implements Parcelable {
+ "}";
}
/**
* Indicates that whether this {@link TaskFragmentParentInfo} equals to {@code obj}.
* Note that {@link #equalsForTaskFragmentOrganizer(TaskFragmentParentInfo)} should be used
* for most cases because not all {@link Configuration} properties are interested for
* {@link TaskFragmentOrganizer}.
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof TaskFragmentParentInfo)) {
return false;
}
final TaskFragmentParentInfo that = (TaskFragmentParentInfo) obj;
return mConfiguration.equals(that.mConfiguration)
&& mDisplayId == that.mDisplayId
&& mVisibleRequested == that.mVisibleRequested;
}
@Override
public int hashCode() {
int result = mConfiguration.hashCode();
result = 31 * result + mDisplayId;
result = 31 * result + (mVisibleRequested ? 1 : 0);
return result;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
mConfiguration.writeToParcel(dest, flags);

View File

@@ -1586,11 +1586,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (oldParent != null) {
oldParent.cleanUpActivityReferences(this);
// Update isVisibleRequested value of parent TaskFragment and send the callback to the
// client side if needed.
oldParent.onActivityVisibleRequestedChanged();
}
if (newParent != null && isState(RESUMED)) {
newParent.setResumedActivity(this, "onParentChanged");
mImeInsetsFrozenUntilStartInput = false;
if (newParent != null) {
// Update isVisibleRequested value of parent TaskFragment and send the callback to the
// client side if needed.
newParent.onActivityVisibleRequestedChanged();
if (isState(RESUMED)) {
newParent.setResumedActivity(this, "onParentChanged");
mImeInsetsFrozenUntilStartInput = false;
}
}
if (rootTask != null && rootTask.topRunningActivity() == this) {
@@ -5090,6 +5098,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return;
}
mVisibleRequested = visible;
final TaskFragment taskFragment = getTaskFragment();
if (taskFragment != null) {
taskFragment.onActivityVisibleRequestedChanged();
}
setInsetsFrozen(!visible);
if (app != null) {
mTaskSupervisor.onProcessActivityStateChanged(app, false /* forceBatch */);

View File

@@ -2685,6 +2685,7 @@ class Task extends TaskFragment {
if (isRootTask()) {
updateSurfaceBounds();
}
sendTaskFragmentParentInfoChangedIfNeeded();
}
boolean isResizeable() {
@@ -3527,6 +3528,25 @@ class Task extends TaskFragment {
return new TaskFragmentParentInfo(getConfiguration(), getDisplayId(), isVisibleRequested());
}
@Override
void onActivityVisibleRequestedChanged() {
if (mVisibleRequested != isVisibleRequested()) {
sendTaskFragmentParentInfoChangedIfNeeded();
}
}
void sendTaskFragmentParentInfoChangedIfNeeded() {
if (!isLeafTask()) {
// Only send parent info changed event for leaf task.
return;
}
final TaskFragment childOrganizedTf =
getTaskFragment(TaskFragment::isOrganizedTaskFragment);
if (childOrganizedTf != null) {
childOrganizedTf.sendTaskFragmentParentInfoChanged();
}
}
boolean isTaskId(int taskId) {
return mTaskId == taskId;
}

View File

@@ -297,6 +297,9 @@ class TaskFragment extends WindowContainer<WindowContainer> {
final Point mLastSurfaceSize = new Point();
/** The latest updated value when there's a child {@link #onActivityVisibleRequestedChanged} */
boolean mVisibleRequested;
private final Rect mTmpBounds = new Rect();
private final Rect mTmpFullBounds = new Rect();
/** For calculating screenWidthDp and screenWidthDp, i.e. the area without the system bars. */
@@ -2379,6 +2382,14 @@ class TaskFragment extends WindowContainer<WindowContainer> {
}
}
void sendTaskFragmentParentInfoChanged() {
final Task parentTask = getParent().asTask();
if (mTaskFragmentOrganizer != null && parentTask != null) {
mTaskFragmentOrganizerController
.onTaskFragmentParentInfoChanged(mTaskFragmentOrganizer, parentTask);
}
}
private void sendTaskFragmentAppeared() {
if (mTaskFragmentOrganizer != null) {
mTaskFragmentOrganizerController.onTaskFragmentAppeared(mTaskFragmentOrganizer, this);
@@ -2414,7 +2425,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
mRemoteToken.toWindowContainerToken(),
getConfiguration(),
getNonFinishingActivityCount(),
isVisible(),
isVisibleRequested(),
childActivities,
positionInParent,
mClearedTaskForReuse,
@@ -2671,6 +2682,18 @@ class TaskFragment extends WindowContainer<WindowContainer> {
return getWindowingMode() == WINDOWING_MODE_FULLSCREEN || matchParentBounds();
}
void onActivityVisibleRequestedChanged() {
final boolean isVisibleRequested = isVisibleRequested();
if (mVisibleRequested == isVisibleRequested) {
return;
}
mVisibleRequested = isVisibleRequested;
final TaskFragment parentTf = getParent().asTaskFragment();
if (parentTf != null) {
parentTf.onActivityVisibleRequestedChanged();
}
}
String toFullString() {
final StringBuilder sb = new StringBuilder(128);
sb.append(this);

View File

@@ -649,6 +649,34 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
.build());
}
void onTaskFragmentParentInfoChanged(@NonNull ITaskFragmentOrganizer organizer,
@NonNull Task task) {
validateAndGetState(organizer);
final PendingTaskFragmentEvent pendingEvent = getLastPendingParentInfoChangedEvent(
organizer, task);
if (pendingEvent == null) {
addPendingEvent(new PendingTaskFragmentEvent.Builder(
PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED, organizer)
.setTask(task)
.build());
}
}
@Nullable
private PendingTaskFragmentEvent getLastPendingParentInfoChangedEvent(
@NonNull ITaskFragmentOrganizer organizer, @NonNull Task task) {
final List<PendingTaskFragmentEvent> events = mPendingTaskFragmentEvents
.get(organizer.asBinder());
for (int i = events.size() - 1; i >= 0; i--) {
final PendingTaskFragmentEvent event = events.get(i);
if (task == event.mTask
&& event.mEventType == PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED) {
return event;
}
}
return null;
}
private void addPendingEvent(@NonNull PendingTaskFragmentEvent event) {
mPendingTaskFragmentEvents.get(event.mTaskFragmentOrg.asBinder()).add(event);
}
@@ -851,7 +879,9 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
}
private boolean shouldSendEventWhenTaskInvisible(@NonNull PendingTaskFragmentEvent event) {
if (event.mEventType == PendingTaskFragmentEvent.EVENT_ERROR) {
if (event.mEventType == PendingTaskFragmentEvent.EVENT_ERROR
// Always send parent info changed to update task visibility
|| event.mEventType == PendingTaskFragmentEvent.EVENT_PARENT_INFO_CHANGED) {
return true;
}

View File

@@ -2192,6 +2192,17 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
callback, boundary, includeBoundary, traverseTopToBottom, boundaryFound);
}
@Nullable
TaskFragment getTaskFragment(Predicate<TaskFragment> callback) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final TaskFragment tf = mChildren.get(i).getTaskFragment(callback);
if (tf != null) {
return tf;
}
}
return null;
}
WindowState getWindow(Predicate<WindowState> callback) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState w = mChildren.get(i).getWindow(callback);