Merge "Remove TaskFragments while TaskFragmentOrganizer removed" into sc-v2-dev am: 5a03acb8c8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15182814

Change-Id: I11e6a09e019d1271fa081838b60c463d258bb630
This commit is contained in:
Jeff Chang
2021-07-08 10:30:17 +00:00
committed by Automerger Merge Worker

View File

@@ -24,7 +24,7 @@ import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.ArraySet; import android.util.Slog;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.window.ITaskFragmentOrganizer; import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController; import android.window.ITaskFragmentOrganizerController;
@@ -33,8 +33,8 @@ import android.window.TaskFragmentInfo;
import com.android.internal.protolog.common.ProtoLog; import com.android.internal.protolog.common.ProtoLog;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
/** /**
@@ -45,104 +45,112 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
private final ActivityTaskManagerService mAtmService; private final ActivityTaskManagerService mAtmService;
private final WindowManagerGlobalLock mGlobalLock; private final WindowManagerGlobalLock mGlobalLock;
private final Set<ITaskFragmentOrganizer> mOrganizers = new ArraySet<>();
private final Map<ITaskFragmentOrganizer, DeathRecipient> mDeathRecipients = new ArrayMap<>();
private final Map<TaskFragment, TaskFragmentInfo> mLastSentTaskFragmentInfos = private final Map<TaskFragment, TaskFragmentInfo> mLastSentTaskFragmentInfos =
new WeakHashMap<>(); new WeakHashMap<>();
private final Map<TaskFragment, Configuration> mLastSentTaskFragmentParentConfigs = private final Map<TaskFragment, Configuration> mLastSentTaskFragmentParentConfigs =
new WeakHashMap<>(); new WeakHashMap<>();
/**
private class DeathRecipient implements IBinder.DeathRecipient { * A Map which manages the relationship between
final ITaskFragmentOrganizer mOrganizer; * {@link ITaskFragmentOrganizer} and {@link TaskFragmentOrganizerState}
*/
DeathRecipient(ITaskFragmentOrganizer organizer) { private final ArrayMap<IBinder, TaskFragmentController> mTaskFragmentOrganizerControllers =
mOrganizer = organizer; new ArrayMap<>();
}
@Override
public void binderDied() {
removeOrganizer(mOrganizer);
}
}
TaskFragmentOrganizerController(ActivityTaskManagerService atm) { TaskFragmentOrganizerController(ActivityTaskManagerService atm) {
mAtmService = atm; mAtmService = atm;
mGlobalLock = atm.mGlobalLock; mGlobalLock = atm.mGlobalLock;
} }
/**
* A class to manage {@link ITaskFragmentOrganizer} and its organized
* {@link TaskFragment TaskFragments}.
*/
private class TaskFragmentController implements IBinder.DeathRecipient {
private final ArrayList<TaskFragment> mOrganizedTaskFragments = new ArrayList<>();
private final ITaskFragmentOrganizer mOrganizer;
TaskFragmentController(ITaskFragmentOrganizer organizer) {
mOrganizer = organizer;
try {
mOrganizer.asBinder().linkToDeath(this, 0 /*flags*/);
} catch (RemoteException e) {
Slog.e(TAG, "TaskFragmentOrganizer failed to register death recipient");
}
}
@Override
public void binderDied() {
synchronized (mGlobalLock) {
removeOrganizer(mOrganizer);
}
}
void addTaskFragment(TaskFragment taskFragment) {
if (!mOrganizedTaskFragments.contains(taskFragment)) {
mOrganizedTaskFragments.add(taskFragment);
}
}
void removeTaskFragment(TaskFragment taskFragment) {
mOrganizedTaskFragments.remove(taskFragment);
}
void dispose() {
mOrganizedTaskFragments.forEach(TaskFragment::removeImmediately);
mOrganizedTaskFragments.clear();
mOrganizer.asBinder().unlinkToDeath(this, 0 /*flags*/);
}
}
@Override @Override
public void registerOrganizer(ITaskFragmentOrganizer organizer) { public void registerOrganizer(ITaskFragmentOrganizer organizer) {
final int pid = Binder.getCallingPid(); final int pid = Binder.getCallingPid();
final long uid = Binder.getCallingUid(); final long uid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) { synchronized (mGlobalLock) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
"Register task fragment organizer=%s uid=%d pid=%d", "Register task fragment organizer=%s uid=%d pid=%d",
organizer.asBinder(), uid, pid); organizer.asBinder(), uid, pid);
if (mOrganizers.contains(organizer)) { if (mTaskFragmentOrganizerControllers.containsKey(organizer.asBinder())) {
throw new IllegalStateException( throw new IllegalStateException(
"Replacing existing organizer currently unsupported"); "Replacing existing organizer currently unsupported");
} }
mTaskFragmentOrganizerControllers.put(organizer.asBinder(),
final DeathRecipient dr = new DeathRecipient(organizer); new TaskFragmentController(organizer));
try {
organizer.asBinder().linkToDeath(dr, 0);
} catch (RemoteException e) {
// Oh well...
}
mOrganizers.add(organizer);
mDeathRecipients.put(organizer, dr);
}
} finally {
Binder.restoreCallingIdentity(origId);
} }
} }
@Override @Override
public void unregisterOrganizer(ITaskFragmentOrganizer organizer) { public void unregisterOrganizer(ITaskFragmentOrganizer organizer) {
validateAndGetController(organizer);
final int pid = Binder.getCallingPid(); final int pid = Binder.getCallingPid();
final long uid = Binder.getCallingUid(); final long uid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) { synchronized (mGlobalLock) {
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER,
"Unregister task fragment organizer=%s uid=%d pid=%d", "Unregister task fragment organizer=%s uid=%d pid=%d",
organizer.asBinder(), uid, pid); organizer.asBinder(), uid, pid);
if (!mOrganizers.contains(organizer)) {
throw new IllegalStateException(
"The task fragment organizer hasn't been registered.");
}
final DeathRecipient dr = mDeathRecipients.get(organizer);
organizer.asBinder().unlinkToDeath(dr, 0);
removeOrganizer(organizer); removeOrganizer(organizer);
} }
} finally {
Binder.restoreCallingIdentity(origId);
}
} }
void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) {
validateOrganizer(organizer); final TaskFragmentController controller = validateAndGetController(organizer);
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment appeared name=%s", tf.getName()); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment appeared name=%s", tf.getName());
final TaskFragmentInfo info = tf.getTaskFragmentInfo(); final TaskFragmentInfo info = tf.getTaskFragmentInfo();
final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(), final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(),
"TaskFragmentOrganizerController.onTaskFragmentInfoAppeared"); "TaskFragmentOrganizerController.onTaskFragmentInfoAppeared");
controller.addTaskFragment(tf);
try { try {
organizer.onTaskFragmentAppeared( organizer.onTaskFragmentAppeared(
new TaskFragmentAppearedInfo(info, outSurfaceControl)); new TaskFragmentAppearedInfo(info, outSurfaceControl));
mLastSentTaskFragmentInfos.put(tf, info); mLastSentTaskFragmentInfos.put(tf, info);
} catch (RemoteException e) { } catch (RemoteException e) {
// Oh well... Slog.e(TAG, "Exception sending onTaskFragmentAppeared callback", e);
} }
} }
void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) {
validateOrganizer(organizer); validateAndGetController(organizer);
// Check if the info is different from the last reported info. // Check if the info is different from the last reported info.
final TaskFragmentInfo info = tf.getTaskFragmentInfo(); final TaskFragmentInfo info = tf.getTaskFragmentInfo();
@@ -157,25 +165,26 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo()); organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo());
mLastSentTaskFragmentInfos.put(tf, info); mLastSentTaskFragmentInfos.put(tf, info);
} catch (RemoteException e) { } catch (RemoteException e) {
// Oh well... Slog.e(TAG, "Exception sending onTaskFragmentInfoChanged callback", e);
} }
} }
void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) {
validateOrganizer(organizer); final TaskFragmentController controller = validateAndGetController(organizer);
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment vanished name=%s", tf.getName()); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment vanished name=%s", tf.getName());
try { try {
organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo()); organizer.onTaskFragmentVanished(tf.getTaskFragmentInfo());
} catch (RemoteException e) { } catch (RemoteException e) {
// Oh well... Slog.e(TAG, "Exception sending onTaskFragmentVanished callback", e);
} }
mLastSentTaskFragmentInfos.remove(tf); mLastSentTaskFragmentInfos.remove(tf);
mLastSentTaskFragmentParentConfigs.remove(tf); mLastSentTaskFragmentParentConfigs.remove(tf);
controller.removeTaskFragment(tf);
} }
void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) {
validateOrganizer(organizer); validateAndGetController(organizer);
// Check if the parent info is different from the last reported parent info. // Check if the parent info is different from the last reported parent info.
if (tf.getParent() == null || tf.getParent().asTask() == null) { if (tf.getParent() == null || tf.getParent().asTask() == null) {
@@ -196,16 +205,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig); organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig);
mLastSentTaskFragmentParentConfigs.put(tf, parentConfig); mLastSentTaskFragmentParentConfigs.put(tf, parentConfig);
} catch (RemoteException e) { } catch (RemoteException e) {
// Oh well... Slog.e(TAG, "Exception sending onTaskFragmentParentInfoChanged callback", e);
} }
} }
private void removeOrganizer(ITaskFragmentOrganizer organizer) { private void removeOrganizer(ITaskFragmentOrganizer organizer) {
synchronized (mGlobalLock) { final TaskFragmentController controller = validateAndGetController(organizer);
mOrganizers.remove(organizer); // remove all of the children of the organized TaskFragment
mDeathRecipients.remove(organizer); controller.dispose();
} mTaskFragmentOrganizerControllers.remove(organizer.asBinder());
// TODO(b/190432728) move child activities of organized TaskFragment to leaf Task
} }
/** /**
@@ -214,10 +222,13 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr
* we wouldn't register {@link DeathRecipient} for the organizer, and might not remove the * we wouldn't register {@link DeathRecipient} for the organizer, and might not remove the
* {@link TaskFragment} after the organizer process died. * {@link TaskFragment} after the organizer process died.
*/ */
private void validateOrganizer(ITaskFragmentOrganizer organizer) { private TaskFragmentController validateAndGetController(ITaskFragmentOrganizer organizer) {
if (!mOrganizers.contains(organizer)) { final TaskFragmentController controller =
mTaskFragmentOrganizerControllers.get(organizer.asBinder());
if (controller == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"TaskFragmentOrganizer has not been registered. Organizer=" + organizer); "TaskFragmentOrganizer has not been registered. Organizer=" + organizer);
} }
return controller;
} }
} }