Loading core/java/android/window/ITaskFragmentOrganizerController.aidl +16 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.window; import android.os.Bundle; import android.os.IBinder; import android.view.RemoteAnimationDefinition; import android.window.ITaskFragmentOrganizer; Loading @@ -24,20 +25,33 @@ import android.window.WindowContainerTransaction; /** @hide */ interface ITaskFragmentOrganizerController { /** * Registers a TaskFragmentOrganizer to manage TaskFragments. Registering a system * organizer requires MANAGE_ACTIVITY_TASKS permission, and the organizer will have additional * system capabilities. * * @param organizer The TaskFragmentOrganizer to register * @param isSystemOrganizer If it is a system organizer * @param outSavedState Returning the saved state (if any) that previously saved. This is * useful when retrieve the state from the same TaskFragmentOrganizer * that was killed by the system (e.g. to reclaim memory). Note that * the save state is dropped and unable to retrieve once the system * restarts or the organizer is unregistered. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value=android.Manifest.permission.MANAGE_ACTIVITY_TASKS, conditional=true)") void registerOrganizer(in ITaskFragmentOrganizer organizer, in boolean isSystemOrganizer); void registerOrganizer(in ITaskFragmentOrganizer organizer, in boolean isSystemOrganizer, out Bundle outSavedState); /** * Unregisters a previously registered TaskFragmentOrganizer. */ void unregisterOrganizer(in ITaskFragmentOrganizer organizer); /** * Saves the state in the system, where the state can be restored if the process of * the TaskFragmentOrganizer is restarted. */ void setSavedState(in ITaskFragmentOrganizer organizer, in Bundle savedState); /** * Notifies the server that the organizer has finished handling the given transaction. The * server should apply the given {@link WindowContainerTransaction} for the necessary changes. Loading core/java/android/window/TaskFragmentOrganizer.java +50 −8 Original line number Diff line number Diff line Loading @@ -165,17 +165,12 @@ public class TaskFragmentOrganizer extends WindowOrganizer { */ @CallSuper public void registerOrganizer() { // TODO(b/302420256) point to registerOrganizer(boolean) when flag is removed. try { getController().registerOrganizer(mInterface, false /* isSystemOrganizer */); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } registerOrganizer(false /* isSystemOrganizer */, null /* outSavedState */); } /** * Registers a {@link TaskFragmentOrganizer} to manage TaskFragments. * * <p> * Registering a system organizer requires MANAGE_ACTIVITY_TASKS permission, and the organizer * will have additional system capabilities, including: (1) it will receive SurfaceControl for * the organized TaskFragment, and (2) it needs to update the Loading @@ -187,8 +182,31 @@ public class TaskFragmentOrganizer extends WindowOrganizer { @RequiresPermission(value = "android.permission.MANAGE_ACTIVITY_TASKS", conditional = true) @FlaggedApi(Flags.FLAG_TASK_FRAGMENT_SYSTEM_ORGANIZER_FLAG) public void registerOrganizer(boolean isSystemOrganizer) { registerOrganizer(isSystemOrganizer, null /* outSavedState */); } /** * Registers a {@link TaskFragmentOrganizer} to manage TaskFragments. * <p> * Registering a system organizer requires MANAGE_ACTIVITY_TASKS permission, and the organizer * will have additional system capabilities, including: (1) it will receive SurfaceControl for * the organized TaskFragment, and (2) it needs to update the * {@link android.view.SurfaceControl} following the window change accordingly. * * @param isSystemOrganizer If it is a system organizer * @param outSavedState Returning the saved state (if any) that previously saved. This is * useful when retrieve the state from the same TaskFragmentOrganizer * that was killed by the system (e.g. to reclaim memory). Note that * the save state is dropped and unable to retrieve once the system * restarts or the organizer is unregistered. * @hide */ @CallSuper @RequiresPermission(value = "android.permission.MANAGE_ACTIVITY_TASKS", conditional = true) public void registerOrganizer(boolean isSystemOrganizer, @Nullable Bundle outSavedState) { try { getController().registerOrganizer(mInterface, isSystemOrganizer); getController().registerOrganizer(mInterface, isSystemOrganizer, outSavedState != null ? outSavedState : new Bundle()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading @@ -206,6 +224,30 @@ public class TaskFragmentOrganizer extends WindowOrganizer { } } /** * Saves the state in the system, where the state can be restored if the process of * the TaskFragmentOrganizer is restarted. * * @hide * * @param state the state to save. */ public void setSavedState(@NonNull Bundle state) { if (!Flags.aeBackStackRestore()) { return; } if (state.getSize() > 200000) { throw new IllegalArgumentException("Saved state too large, " + state.getSize()); } try { getController().setSavedState(mInterface, state); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notifies the server that the organizer has finished handling the given transaction. The * server should apply the given {@link WindowContainerTransaction} for the necessary changes. Loading services/core/java/com/android/server/wm/TaskFragment.java +11 −1 Original line number Diff line number Diff line Loading @@ -478,6 +478,10 @@ class TaskFragment extends WindowContainer<WindowContainer> { mTaskFragmentOrganizerProcessName = processName; } void onTaskFragmentOrganizerRestarted(@NonNull ITaskFragmentOrganizer organizer) { mTaskFragmentOrganizer = organizer; } void onTaskFragmentOrganizerRemoved() { mTaskFragmentOrganizer = null; } Loading Loading @@ -2960,7 +2964,13 @@ class TaskFragment extends WindowContainer<WindowContainer> { } boolean shouldRemoveSelfOnLastChildRemoval() { return !mCreatedByOrganizer || mIsRemovalRequested; if (!mCreatedByOrganizer || mIsRemovalRequested) { return true; } // The TaskFragmentOrganizer may be killed while the embedded TaskFragments remains in WM // core. The embedded TaskFragment should still be removed when the child activities are // all gone (like package force-stopped). return mIsEmbedded && mTaskFragmentOrganizer == null; } /** Loading services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +100 −13 Original line number Diff line number Diff line Loading @@ -85,6 +85,12 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr */ private final ArrayMap<IBinder, TaskFragmentOrganizerState> mTaskFragmentOrganizerState = new ArrayMap<>(); /** * The cached {@link TaskFragmentOrganizerState} for the {@link ITaskFragmentOrganizer} that * have no running process. */ private final ArrayList<TaskFragmentOrganizerState> mCachedTaskFragmentOrganizerStates = new ArrayList<>(); /** * Map from {@link ITaskFragmentOrganizer} to a list of related {@link PendingTaskFragmentEvent} */ Loading @@ -105,11 +111,16 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr * {@link TaskFragment TaskFragments}. */ private class TaskFragmentOrganizerState implements IBinder.DeathRecipient { @NonNull private final ArrayList<TaskFragment> mOrganizedTaskFragments = new ArrayList<>(); private final IApplicationThread mAppThread; private final ITaskFragmentOrganizer mOrganizer; private final int mOrganizerPid; private final int mOrganizerUid; @NonNull private IApplicationThread mAppThread; @NonNull private ITaskFragmentOrganizer mOrganizer; private int mOrganizerPid; @Nullable private Bundle mSavedState; /** * Map from {@link TaskFragment} to the last {@link TaskFragmentInfo} sent to the Loading Loading @@ -182,6 +193,24 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } void restore(@NonNull ITaskFragmentOrganizer organizer, int pid) { mOrganizer = organizer; mOrganizerPid = pid; mAppThread = getAppThread(pid, mOrganizerUid); for (int i = mOrganizedTaskFragments.size() - 1; i >= 0; i--) { mOrganizedTaskFragments.get(i).onTaskFragmentOrganizerRestarted(organizer); } try { mOrganizer.asBinder().linkToDeath(this, 0 /*flags*/); } catch (RemoteException e) { Slog.e(TAG, "TaskFragmentOrganizer failed to register death recipient"); } } boolean hasSavedState() { return mSavedState != null && !mSavedState.isEmpty(); } /** * @return {@code true} if taskFragment is organized and not sent the appeared event before. */ Loading Loading @@ -226,13 +255,19 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr containsNonEmbeddedActivity ? null : task, null /* remoteTransition */, null /* displayChange */); } // Defer to avoid unnecessary layout when there are multiple TaskFragments removal. mAtmService.deferWindowLayout(); try { while (!mOrganizedTaskFragments.isEmpty()) { final TaskFragment taskFragment = mOrganizedTaskFragments.remove(0); // Removes the TaskFragments if no saved state or is empty. final boolean haveSavedState = hasSavedState(); for (int i = mOrganizedTaskFragments.size() - 1; i >= 0; i--) { final TaskFragment taskFragment = mOrganizedTaskFragments.get(i); if (!haveSavedState || !taskFragment.hasChild()) { mOrganizedTaskFragments.remove(i); taskFragment.removeImmediately(); } } } finally { mAtmService.continueWindowLayout(); } Loading Loading @@ -478,15 +513,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } @Override public void registerOrganizer( @NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer) { registerOrganizerInternal( organizer, Flags.taskFragmentSystemOrganizerFlag() && isSystemOrganizer); public void registerOrganizer(@NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer, @NonNull Bundle outSavedState) { registerOrganizerInternal(organizer, Flags.taskFragmentSystemOrganizerFlag() && isSystemOrganizer, outSavedState); } private void registerOrganizerInternal( @NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer) { @NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer, @NonNull Bundle outSavedState) { if (isSystemOrganizer) { enforceTaskPermission("registerSystemOrganizer()"); } Loading @@ -496,16 +531,49 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register task fragment organizer=%s uid=%d pid=%d", organizer.asBinder(), uid, pid); if (isOrganizerRegistered(organizer)) { throw new IllegalStateException( "Replacing existing organizer currently unsupported"); } if (restoreFromCachedStateIfPossible(organizer, pid, uid, outSavedState)) { return; } mTaskFragmentOrganizerState.put(organizer.asBinder(), new TaskFragmentOrganizerState(organizer, pid, uid, isSystemOrganizer)); mPendingTaskFragmentEvents.put(organizer.asBinder(), new ArrayList<>()); } } private boolean restoreFromCachedStateIfPossible(@NonNull ITaskFragmentOrganizer organizer, int pid, int uid, @NonNull Bundle outSavedState) { if (!Flags.aeBackStackRestore()) { return false; } TaskFragmentOrganizerState cachedState = null; int i = mCachedTaskFragmentOrganizerStates.size() - 1; for (; i >= 0; i--) { final TaskFragmentOrganizerState state = mCachedTaskFragmentOrganizerStates.get(i); if (state.mOrganizerUid == uid) { cachedState = state; break; } } if (cachedState == null) { return false; } mCachedTaskFragmentOrganizerStates.remove(cachedState); outSavedState.putAll(cachedState.mSavedState); cachedState.restore(organizer, pid); mTaskFragmentOrganizerState.put(organizer.asBinder(), cachedState); mPendingTaskFragmentEvents.put(organizer.asBinder(), new ArrayList<>()); return true; } @Override public void unregisterOrganizer(@NonNull ITaskFragmentOrganizer organizer) { final int pid = Binder.getCallingPid(); Loading @@ -523,6 +591,23 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } @Override public void setSavedState(@NonNull ITaskFragmentOrganizer organizer, @Nullable Bundle state) { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); synchronized (mGlobalLock) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Set state for organizer=%s uid=%d pid=%d", organizer.asBinder(), uid, pid); final TaskFragmentOrganizerState organizerState = mTaskFragmentOrganizerState.get( organizer.asBinder()); if (organizerState == null) { throw new IllegalStateException("The organizer hasn't been registered."); } organizerState.mSavedState = state; } } @Override public void onTransactionHandled(@NonNull IBinder transactionToken, @NonNull WindowContainerTransaction wct, Loading Loading @@ -768,9 +853,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr // Remove any pending event of this organizer first because state.dispose() may trigger // event dispatch as result of surface placement. mPendingTaskFragmentEvents.remove(organizer.asBinder()); // remove all of the children of the organized TaskFragment state.dispose(reason); mTaskFragmentOrganizerState.remove(organizer.asBinder()); if (state.hasSavedState()) { mCachedTaskFragmentOrganizerStates.add(state); } } /** Loading services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +2 −1 Original line number Diff line number Diff line Loading @@ -924,7 +924,8 @@ public class WindowTestsBase extends SystemServiceTestsBase { mSystemServicesTestRule.addProcess("pkgName", "procName", WindowManagerService.MY_PID, WindowManagerService.MY_UID); } mAtm.mTaskFragmentOrganizerController.registerOrganizer(organizer, isSystemOrganizer); mAtm.mTaskFragmentOrganizerController.registerOrganizer(organizer, isSystemOrganizer, new Bundle()); } /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */ Loading Loading
core/java/android/window/ITaskFragmentOrganizerController.aidl +16 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.window; import android.os.Bundle; import android.os.IBinder; import android.view.RemoteAnimationDefinition; import android.window.ITaskFragmentOrganizer; Loading @@ -24,20 +25,33 @@ import android.window.WindowContainerTransaction; /** @hide */ interface ITaskFragmentOrganizerController { /** * Registers a TaskFragmentOrganizer to manage TaskFragments. Registering a system * organizer requires MANAGE_ACTIVITY_TASKS permission, and the organizer will have additional * system capabilities. * * @param organizer The TaskFragmentOrganizer to register * @param isSystemOrganizer If it is a system organizer * @param outSavedState Returning the saved state (if any) that previously saved. This is * useful when retrieve the state from the same TaskFragmentOrganizer * that was killed by the system (e.g. to reclaim memory). Note that * the save state is dropped and unable to retrieve once the system * restarts or the organizer is unregistered. */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value=android.Manifest.permission.MANAGE_ACTIVITY_TASKS, conditional=true)") void registerOrganizer(in ITaskFragmentOrganizer organizer, in boolean isSystemOrganizer); void registerOrganizer(in ITaskFragmentOrganizer organizer, in boolean isSystemOrganizer, out Bundle outSavedState); /** * Unregisters a previously registered TaskFragmentOrganizer. */ void unregisterOrganizer(in ITaskFragmentOrganizer organizer); /** * Saves the state in the system, where the state can be restored if the process of * the TaskFragmentOrganizer is restarted. */ void setSavedState(in ITaskFragmentOrganizer organizer, in Bundle savedState); /** * Notifies the server that the organizer has finished handling the given transaction. The * server should apply the given {@link WindowContainerTransaction} for the necessary changes. Loading
core/java/android/window/TaskFragmentOrganizer.java +50 −8 Original line number Diff line number Diff line Loading @@ -165,17 +165,12 @@ public class TaskFragmentOrganizer extends WindowOrganizer { */ @CallSuper public void registerOrganizer() { // TODO(b/302420256) point to registerOrganizer(boolean) when flag is removed. try { getController().registerOrganizer(mInterface, false /* isSystemOrganizer */); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } registerOrganizer(false /* isSystemOrganizer */, null /* outSavedState */); } /** * Registers a {@link TaskFragmentOrganizer} to manage TaskFragments. * * <p> * Registering a system organizer requires MANAGE_ACTIVITY_TASKS permission, and the organizer * will have additional system capabilities, including: (1) it will receive SurfaceControl for * the organized TaskFragment, and (2) it needs to update the Loading @@ -187,8 +182,31 @@ public class TaskFragmentOrganizer extends WindowOrganizer { @RequiresPermission(value = "android.permission.MANAGE_ACTIVITY_TASKS", conditional = true) @FlaggedApi(Flags.FLAG_TASK_FRAGMENT_SYSTEM_ORGANIZER_FLAG) public void registerOrganizer(boolean isSystemOrganizer) { registerOrganizer(isSystemOrganizer, null /* outSavedState */); } /** * Registers a {@link TaskFragmentOrganizer} to manage TaskFragments. * <p> * Registering a system organizer requires MANAGE_ACTIVITY_TASKS permission, and the organizer * will have additional system capabilities, including: (1) it will receive SurfaceControl for * the organized TaskFragment, and (2) it needs to update the * {@link android.view.SurfaceControl} following the window change accordingly. * * @param isSystemOrganizer If it is a system organizer * @param outSavedState Returning the saved state (if any) that previously saved. This is * useful when retrieve the state from the same TaskFragmentOrganizer * that was killed by the system (e.g. to reclaim memory). Note that * the save state is dropped and unable to retrieve once the system * restarts or the organizer is unregistered. * @hide */ @CallSuper @RequiresPermission(value = "android.permission.MANAGE_ACTIVITY_TASKS", conditional = true) public void registerOrganizer(boolean isSystemOrganizer, @Nullable Bundle outSavedState) { try { getController().registerOrganizer(mInterface, isSystemOrganizer); getController().registerOrganizer(mInterface, isSystemOrganizer, outSavedState != null ? outSavedState : new Bundle()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading @@ -206,6 +224,30 @@ public class TaskFragmentOrganizer extends WindowOrganizer { } } /** * Saves the state in the system, where the state can be restored if the process of * the TaskFragmentOrganizer is restarted. * * @hide * * @param state the state to save. */ public void setSavedState(@NonNull Bundle state) { if (!Flags.aeBackStackRestore()) { return; } if (state.getSize() > 200000) { throw new IllegalArgumentException("Saved state too large, " + state.getSize()); } try { getController().setSavedState(mInterface, state); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notifies the server that the organizer has finished handling the given transaction. The * server should apply the given {@link WindowContainerTransaction} for the necessary changes. Loading
services/core/java/com/android/server/wm/TaskFragment.java +11 −1 Original line number Diff line number Diff line Loading @@ -478,6 +478,10 @@ class TaskFragment extends WindowContainer<WindowContainer> { mTaskFragmentOrganizerProcessName = processName; } void onTaskFragmentOrganizerRestarted(@NonNull ITaskFragmentOrganizer organizer) { mTaskFragmentOrganizer = organizer; } void onTaskFragmentOrganizerRemoved() { mTaskFragmentOrganizer = null; } Loading Loading @@ -2960,7 +2964,13 @@ class TaskFragment extends WindowContainer<WindowContainer> { } boolean shouldRemoveSelfOnLastChildRemoval() { return !mCreatedByOrganizer || mIsRemovalRequested; if (!mCreatedByOrganizer || mIsRemovalRequested) { return true; } // The TaskFragmentOrganizer may be killed while the embedded TaskFragments remains in WM // core. The embedded TaskFragment should still be removed when the child activities are // all gone (like package force-stopped). return mIsEmbedded && mTaskFragmentOrganizer == null; } /** Loading
services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +100 −13 Original line number Diff line number Diff line Loading @@ -85,6 +85,12 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr */ private final ArrayMap<IBinder, TaskFragmentOrganizerState> mTaskFragmentOrganizerState = new ArrayMap<>(); /** * The cached {@link TaskFragmentOrganizerState} for the {@link ITaskFragmentOrganizer} that * have no running process. */ private final ArrayList<TaskFragmentOrganizerState> mCachedTaskFragmentOrganizerStates = new ArrayList<>(); /** * Map from {@link ITaskFragmentOrganizer} to a list of related {@link PendingTaskFragmentEvent} */ Loading @@ -105,11 +111,16 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr * {@link TaskFragment TaskFragments}. */ private class TaskFragmentOrganizerState implements IBinder.DeathRecipient { @NonNull private final ArrayList<TaskFragment> mOrganizedTaskFragments = new ArrayList<>(); private final IApplicationThread mAppThread; private final ITaskFragmentOrganizer mOrganizer; private final int mOrganizerPid; private final int mOrganizerUid; @NonNull private IApplicationThread mAppThread; @NonNull private ITaskFragmentOrganizer mOrganizer; private int mOrganizerPid; @Nullable private Bundle mSavedState; /** * Map from {@link TaskFragment} to the last {@link TaskFragmentInfo} sent to the Loading Loading @@ -182,6 +193,24 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } void restore(@NonNull ITaskFragmentOrganizer organizer, int pid) { mOrganizer = organizer; mOrganizerPid = pid; mAppThread = getAppThread(pid, mOrganizerUid); for (int i = mOrganizedTaskFragments.size() - 1; i >= 0; i--) { mOrganizedTaskFragments.get(i).onTaskFragmentOrganizerRestarted(organizer); } try { mOrganizer.asBinder().linkToDeath(this, 0 /*flags*/); } catch (RemoteException e) { Slog.e(TAG, "TaskFragmentOrganizer failed to register death recipient"); } } boolean hasSavedState() { return mSavedState != null && !mSavedState.isEmpty(); } /** * @return {@code true} if taskFragment is organized and not sent the appeared event before. */ Loading Loading @@ -226,13 +255,19 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr containsNonEmbeddedActivity ? null : task, null /* remoteTransition */, null /* displayChange */); } // Defer to avoid unnecessary layout when there are multiple TaskFragments removal. mAtmService.deferWindowLayout(); try { while (!mOrganizedTaskFragments.isEmpty()) { final TaskFragment taskFragment = mOrganizedTaskFragments.remove(0); // Removes the TaskFragments if no saved state or is empty. final boolean haveSavedState = hasSavedState(); for (int i = mOrganizedTaskFragments.size() - 1; i >= 0; i--) { final TaskFragment taskFragment = mOrganizedTaskFragments.get(i); if (!haveSavedState || !taskFragment.hasChild()) { mOrganizedTaskFragments.remove(i); taskFragment.removeImmediately(); } } } finally { mAtmService.continueWindowLayout(); } Loading Loading @@ -478,15 +513,15 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } @Override public void registerOrganizer( @NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer) { registerOrganizerInternal( organizer, Flags.taskFragmentSystemOrganizerFlag() && isSystemOrganizer); public void registerOrganizer(@NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer, @NonNull Bundle outSavedState) { registerOrganizerInternal(organizer, Flags.taskFragmentSystemOrganizerFlag() && isSystemOrganizer, outSavedState); } private void registerOrganizerInternal( @NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer) { @NonNull ITaskFragmentOrganizer organizer, boolean isSystemOrganizer, @NonNull Bundle outSavedState) { if (isSystemOrganizer) { enforceTaskPermission("registerSystemOrganizer()"); } Loading @@ -496,16 +531,49 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register task fragment organizer=%s uid=%d pid=%d", organizer.asBinder(), uid, pid); if (isOrganizerRegistered(organizer)) { throw new IllegalStateException( "Replacing existing organizer currently unsupported"); } if (restoreFromCachedStateIfPossible(organizer, pid, uid, outSavedState)) { return; } mTaskFragmentOrganizerState.put(organizer.asBinder(), new TaskFragmentOrganizerState(organizer, pid, uid, isSystemOrganizer)); mPendingTaskFragmentEvents.put(organizer.asBinder(), new ArrayList<>()); } } private boolean restoreFromCachedStateIfPossible(@NonNull ITaskFragmentOrganizer organizer, int pid, int uid, @NonNull Bundle outSavedState) { if (!Flags.aeBackStackRestore()) { return false; } TaskFragmentOrganizerState cachedState = null; int i = mCachedTaskFragmentOrganizerStates.size() - 1; for (; i >= 0; i--) { final TaskFragmentOrganizerState state = mCachedTaskFragmentOrganizerStates.get(i); if (state.mOrganizerUid == uid) { cachedState = state; break; } } if (cachedState == null) { return false; } mCachedTaskFragmentOrganizerStates.remove(cachedState); outSavedState.putAll(cachedState.mSavedState); cachedState.restore(organizer, pid); mTaskFragmentOrganizerState.put(organizer.asBinder(), cachedState); mPendingTaskFragmentEvents.put(organizer.asBinder(), new ArrayList<>()); return true; } @Override public void unregisterOrganizer(@NonNull ITaskFragmentOrganizer organizer) { final int pid = Binder.getCallingPid(); Loading @@ -523,6 +591,23 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } @Override public void setSavedState(@NonNull ITaskFragmentOrganizer organizer, @Nullable Bundle state) { final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); synchronized (mGlobalLock) { ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Set state for organizer=%s uid=%d pid=%d", organizer.asBinder(), uid, pid); final TaskFragmentOrganizerState organizerState = mTaskFragmentOrganizerState.get( organizer.asBinder()); if (organizerState == null) { throw new IllegalStateException("The organizer hasn't been registered."); } organizerState.mSavedState = state; } } @Override public void onTransactionHandled(@NonNull IBinder transactionToken, @NonNull WindowContainerTransaction wct, Loading Loading @@ -768,9 +853,11 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr // Remove any pending event of this organizer first because state.dispose() may trigger // event dispatch as result of surface placement. mPendingTaskFragmentEvents.remove(organizer.asBinder()); // remove all of the children of the organized TaskFragment state.dispose(reason); mTaskFragmentOrganizerState.remove(organizer.asBinder()); if (state.hasSavedState()) { mCachedTaskFragmentOrganizerStates.add(state); } } /** Loading
services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +2 −1 Original line number Diff line number Diff line Loading @@ -924,7 +924,8 @@ public class WindowTestsBase extends SystemServiceTestsBase { mSystemServicesTestRule.addProcess("pkgName", "procName", WindowManagerService.MY_PID, WindowManagerService.MY_UID); } mAtm.mTaskFragmentOrganizerController.registerOrganizer(organizer, isSystemOrganizer); mAtm.mTaskFragmentOrganizerController.registerOrganizer(organizer, isSystemOrganizer, new Bundle()); } /** Creates a {@link DisplayContent} that supports IME and adds it to the system. */ Loading