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