Loading core/java/android/app/TaskInfo.java +4 −5 Original line number Original line Diff line number Diff line Loading @@ -331,9 +331,8 @@ public class TaskInfo { } } /** /** * Returns {@code true} if parameters that are important for task organizers have changed * Returns {@code true} if the parameters that are important for task organizers are equal * and {@link com.android.server.wm.TaskOrginizerController} needs to notify listeners * between this {@link TaskInfo} and {@param that}. * about that. * @hide * @hide */ */ public boolean equalsForTaskOrganizer(@Nullable TaskInfo that) { public boolean equalsForTaskOrganizer(@Nullable TaskInfo that) { Loading core/java/android/window/TaskFragmentInfo.java +25 −0 Original line number Original line Diff line number Diff line Loading @@ -16,7 +16,10 @@ package android.window; package android.window; import static android.app.WindowConfiguration.WindowingMode; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.res.Configuration; import android.content.res.Configuration; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -94,6 +97,28 @@ public final class TaskFragmentInfo implements Parcelable { return mIsVisible; return mIsVisible; } } @WindowingMode public int getWindowingMode() { return mConfiguration.windowConfiguration.getWindowingMode(); } /** * Returns {@code true} if the parameters that are important for task fragment organizers are * equal between this {@link TaskFragmentInfo} and {@param that}. */ public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentInfo that) { if (that == null) { return false; } return mFragmentToken.equals(that.mFragmentToken) && mInitialComponentName.equals(that.mInitialComponentName) && mToken.equals(that.mToken) && mIsEmpty == that.mIsEmpty && mIsVisible == that.mIsVisible && getWindowingMode() == that.getWindowingMode(); } private TaskFragmentInfo(Parcel in) { private TaskFragmentInfo(Parcel in) { mFragmentToken = in.readStrongBinder(); mFragmentToken = in.readStrongBinder(); mInitialComponentName = in.readTypedObject(ComponentName.CREATOR); mInitialComponentName = in.readTypedObject(ComponentName.CREATOR); Loading services/core/java/com/android/server/wm/TaskFragment.java +31 −0 Original line number Original line Diff line number Diff line Loading @@ -142,6 +142,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { final ActivityTaskManagerService mAtmService; final ActivityTaskManagerService mAtmService; final ActivityTaskSupervisor mTaskSupervisor; final ActivityTaskSupervisor mTaskSupervisor; final RootWindowContainer mRootWindowContainer; final RootWindowContainer mRootWindowContainer; private final TaskFragmentOrganizerController mTaskFragmentOrganizerController; // TODO(b/189384393): this is not set in TaskFragment so far. It should be passed from the // TODO(b/189384393): this is not set in TaskFragment so far. It should be passed from the // parent task when adding to the hierarchy // parent task when adding to the hierarchy Loading Loading @@ -272,6 +273,8 @@ class TaskFragment extends WindowContainer<WindowContainer> { mTaskSupervisor = atmService.mTaskSupervisor; mTaskSupervisor = atmService.mTaskSupervisor; mRootWindowContainer = mAtmService.mRootWindowContainer; mRootWindowContainer = mAtmService.mRootWindowContainer; mCreatedByOrganizer = createdByOrganizer; mCreatedByOrganizer = createdByOrganizer; mTaskFragmentOrganizerController = mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController; } } void setAdjacentTaskFragment(TaskFragment taskFragment) { void setAdjacentTaskFragment(TaskFragment taskFragment) { Loading Loading @@ -1966,6 +1969,34 @@ class TaskFragment extends WindowContainer<WindowContainer> { return getTopChild().getActivityType(); return getTopChild().getActivityType(); } } @Override public void onConfigurationChanged(Configuration newParentConfig) { super.onConfigurationChanged(newParentConfig); if (mTaskFragmentOrganizer != null) { // Parent config may have changed. The controller will check if there is any important // config change for the organizer. mTaskFragmentOrganizerController .onTaskFragmentParentInfoChanged(mTaskFragmentOrganizer, this); mTaskFragmentOrganizerController .onTaskFragmentInfoChanged(mTaskFragmentOrganizer, this); } } // TODO(b/190433129) call when TaskFragment is created from WCT#createTaskFragment private void sendTaskFragmentAppeared() { if (mTaskFragmentOrganizer != null) { mTaskFragmentOrganizerController.onTaskFragmentAppeared(mTaskFragmentOrganizer, this); } } // TODO(b/190433129) call when TaskFragment is removed from WCT#deleteTaskFragment private void sendTaskFragmentVanished() { if (mTaskFragmentOrganizer != null) { mTaskFragmentOrganizerController.onTaskFragmentVanished(mTaskFragmentOrganizer, this); } } /** /** * Returns a {@link TaskFragmentInfo} with information from this TaskFragment. Should not be * Returns a {@link TaskFragmentInfo} with information from this TaskFragment. Should not be * called from {@link Task}. * called from {@link Task}. Loading services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +58 −5 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,9 @@ package com.android.server.wm; package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer; import android.content.res.Configuration; import android.os.Binder; import android.os.Binder; import android.os.IBinder; import android.os.IBinder; import android.os.RemoteException; import android.os.RemoteException; Loading @@ -27,11 +29,13 @@ import android.view.SurfaceControl; import android.window.ITaskFragmentOrganizer; import android.window.ITaskFragmentOrganizer; import android.window.ITaskFragmentOrganizerController; import android.window.ITaskFragmentOrganizerController; import android.window.TaskFragmentAppearedInfo; import android.window.TaskFragmentAppearedInfo; import android.window.TaskFragmentInfo; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.protolog.common.ProtoLog; import java.util.Map; import java.util.Map; import java.util.Set; import java.util.Set; import java.util.WeakHashMap; /** /** * Stores and manages the client {@link android.window.TaskFragmentOrganizer}. * Stores and manages the client {@link android.window.TaskFragmentOrganizer}. Loading @@ -43,6 +47,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr private final WindowManagerGlobalLock mGlobalLock; private final WindowManagerGlobalLock mGlobalLock; private final Set<ITaskFragmentOrganizer> mOrganizers = new ArraySet<>(); private final Set<ITaskFragmentOrganizer> mOrganizers = new ArraySet<>(); private final Map<ITaskFragmentOrganizer, DeathRecipient> mDeathRecipients = new ArrayMap<>(); private final Map<ITaskFragmentOrganizer, DeathRecipient> mDeathRecipients = new ArrayMap<>(); private final Map<TaskFragment, TaskFragmentInfo> mLastSentTaskFragmentInfos = new WeakHashMap<>(); private final Map<TaskFragment, Configuration> mLastSentTaskFragmentParentConfigs = new WeakHashMap<>(); private class DeathRecipient implements IBinder.DeathRecipient { private class DeathRecipient implements IBinder.DeathRecipient { final ITaskFragmentOrganizer mOrganizer; final ITaskFragmentOrganizer mOrganizer; Loading Loading @@ -118,43 +126,75 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(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()); try { final TaskFragmentInfo info = tf.getTaskFragmentInfo(); final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(), final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(), "TaskFragmentOrganizerController.onTaskFragmentInfoAppeared"); "TaskFragmentOrganizerController.onTaskFragmentInfoAppeared"); try { organizer.onTaskFragmentAppeared( organizer.onTaskFragmentAppeared( new TaskFragmentAppearedInfo(tf.getTaskFragmentInfo(), outSurfaceControl)); new TaskFragmentAppearedInfo(info, outSurfaceControl)); mLastSentTaskFragmentInfos.put(tf, info); } catch (RemoteException e) { } catch (RemoteException e) { // Oh well... // Oh well... } } } } void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(organizer); // Check if the info is different from the last reported info. final TaskFragmentInfo info = tf.getTaskFragmentInfo(); final TaskFragmentInfo lastInfo = mLastSentTaskFragmentInfos.get(tf); if (info.equalsForTaskFragmentOrganizer(lastInfo) && configurationsAreEqualForOrganizer( info.getConfiguration(), lastInfo.getConfiguration())) { return; } ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s", tf.getName()); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s", tf.getName()); try { try { organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo()); organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo()); mLastSentTaskFragmentInfos.put(tf, info); } catch (RemoteException e) { } catch (RemoteException e) { // Oh well... // Oh well... } } } } void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(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... // Oh well... } } mLastSentTaskFragmentInfos.remove(tf); mLastSentTaskFragmentParentConfigs.remove(tf); } } void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(organizer); // Check if the parent info is different from the last reported parent info. if (tf.getParent() == null || tf.getParent().asTask() == null) { mLastSentTaskFragmentParentConfigs.remove(tf); return; } final Task parent = tf.getParent().asTask(); final Task parent = tf.getParent().asTask(); final Configuration parentConfig = parent.getConfiguration(); final Configuration lastParentConfig = mLastSentTaskFragmentParentConfigs.get(tf); if (configurationsAreEqualForOrganizer(parentConfig, lastParentConfig)) { return; } ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment parent info changed name=%s parentTaskId=%d", "TaskFragment parent info changed name=%s parentTaskId=%d", tf.getName(), parent.mTaskId); tf.getName(), parent.mTaskId); try { try { organizer.onTaskFragmentParentInfoChanged( organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig); tf.getFragmentToken(), parent.getConfiguration()); mLastSentTaskFragmentParentConfigs.put(tf, parentConfig); } catch (RemoteException e) { } catch (RemoteException e) { // Oh well... // Oh well... } } Loading @@ -167,4 +207,17 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } // TODO(b/190432728) move child activities of organized TaskFragment to leaf Task // TODO(b/190432728) move child activities of organized TaskFragment to leaf Task } } /** * Makes sure that the organizer has been correctly registered to prevent any Sidecar * implementation from organizing {@link TaskFragment} without registering first. In such case, * 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)) { throw new IllegalArgumentException( "TaskFragmentOrganizer has not been registered. Organizer=" + organizer); } } } } services/core/java/com/android/server/wm/TaskOrganizerController.java +4 −22 Original line number Original line Diff line number Diff line Loading @@ -23,15 +23,13 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANI import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission; import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL; import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS; import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer; import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDOW_CONFIGS; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration; import android.app.WindowConfiguration; import android.content.Intent; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ParceledListSlice; import android.content.pm.ParceledListSlice; import android.graphics.Rect; import android.graphics.Rect; import android.os.Binder; import android.os.Binder; Loading Loading @@ -69,13 +67,6 @@ import java.util.function.Consumer; class TaskOrganizerController extends ITaskOrganizerController.Stub { class TaskOrganizerController extends ITaskOrganizerController.Stub { private static final String TAG = "TaskOrganizerController"; private static final String TAG = "TaskOrganizerController"; /** * Masks specifying which configurations are important to report back to an organizer when * changed. */ private static final int REPORT_CONFIGS = CONTROLLABLE_CONFIGS; private static final int REPORT_WINDOW_CONFIGS = CONTROLLABLE_WINDOW_CONFIGS; // The set of modes that are currently supports // The set of modes that are currently supports // TODO: Remove once the task organizer can support all modes // TODO: Remove once the task organizer can support all modes @VisibleForTesting @VisibleForTesting Loading Loading @@ -790,18 +781,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mTmpTaskInfo.configuration.unset(); mTmpTaskInfo.configuration.unset(); task.fillTaskInfo(mTmpTaskInfo); task.fillTaskInfo(mTmpTaskInfo); boolean changed = !mTmpTaskInfo.equalsForTaskOrganizer(lastInfo); boolean changed = !mTmpTaskInfo.equalsForTaskOrganizer(lastInfo) if (!changed) { || !configurationsAreEqualForOrganizer( int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration); mTmpTaskInfo.configuration, lastInfo.configuration); final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff( lastInfo.configuration.windowConfiguration, true /* compareUndefined */) : 0; if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) { cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION; } changed = (cfgChanges & REPORT_CONFIGS) != 0; } if (!(changed || force)) { if (!(changed || force)) { // mTmpTaskInfo will be reused next time. // mTmpTaskInfo will be reused next time. return; return; Loading Loading
core/java/android/app/TaskInfo.java +4 −5 Original line number Original line Diff line number Diff line Loading @@ -331,9 +331,8 @@ public class TaskInfo { } } /** /** * Returns {@code true} if parameters that are important for task organizers have changed * Returns {@code true} if the parameters that are important for task organizers are equal * and {@link com.android.server.wm.TaskOrginizerController} needs to notify listeners * between this {@link TaskInfo} and {@param that}. * about that. * @hide * @hide */ */ public boolean equalsForTaskOrganizer(@Nullable TaskInfo that) { public boolean equalsForTaskOrganizer(@Nullable TaskInfo that) { Loading
core/java/android/window/TaskFragmentInfo.java +25 −0 Original line number Original line Diff line number Diff line Loading @@ -16,7 +16,10 @@ package android.window; package android.window; import static android.app.WindowConfiguration.WindowingMode; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ComponentName; import android.content.res.Configuration; import android.content.res.Configuration; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -94,6 +97,28 @@ public final class TaskFragmentInfo implements Parcelable { return mIsVisible; return mIsVisible; } } @WindowingMode public int getWindowingMode() { return mConfiguration.windowConfiguration.getWindowingMode(); } /** * Returns {@code true} if the parameters that are important for task fragment organizers are * equal between this {@link TaskFragmentInfo} and {@param that}. */ public boolean equalsForTaskFragmentOrganizer(@Nullable TaskFragmentInfo that) { if (that == null) { return false; } return mFragmentToken.equals(that.mFragmentToken) && mInitialComponentName.equals(that.mInitialComponentName) && mToken.equals(that.mToken) && mIsEmpty == that.mIsEmpty && mIsVisible == that.mIsVisible && getWindowingMode() == that.getWindowingMode(); } private TaskFragmentInfo(Parcel in) { private TaskFragmentInfo(Parcel in) { mFragmentToken = in.readStrongBinder(); mFragmentToken = in.readStrongBinder(); mInitialComponentName = in.readTypedObject(ComponentName.CREATOR); mInitialComponentName = in.readTypedObject(ComponentName.CREATOR); Loading
services/core/java/com/android/server/wm/TaskFragment.java +31 −0 Original line number Original line Diff line number Diff line Loading @@ -142,6 +142,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { final ActivityTaskManagerService mAtmService; final ActivityTaskManagerService mAtmService; final ActivityTaskSupervisor mTaskSupervisor; final ActivityTaskSupervisor mTaskSupervisor; final RootWindowContainer mRootWindowContainer; final RootWindowContainer mRootWindowContainer; private final TaskFragmentOrganizerController mTaskFragmentOrganizerController; // TODO(b/189384393): this is not set in TaskFragment so far. It should be passed from the // TODO(b/189384393): this is not set in TaskFragment so far. It should be passed from the // parent task when adding to the hierarchy // parent task when adding to the hierarchy Loading Loading @@ -272,6 +273,8 @@ class TaskFragment extends WindowContainer<WindowContainer> { mTaskSupervisor = atmService.mTaskSupervisor; mTaskSupervisor = atmService.mTaskSupervisor; mRootWindowContainer = mAtmService.mRootWindowContainer; mRootWindowContainer = mAtmService.mRootWindowContainer; mCreatedByOrganizer = createdByOrganizer; mCreatedByOrganizer = createdByOrganizer; mTaskFragmentOrganizerController = mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController; } } void setAdjacentTaskFragment(TaskFragment taskFragment) { void setAdjacentTaskFragment(TaskFragment taskFragment) { Loading Loading @@ -1966,6 +1969,34 @@ class TaskFragment extends WindowContainer<WindowContainer> { return getTopChild().getActivityType(); return getTopChild().getActivityType(); } } @Override public void onConfigurationChanged(Configuration newParentConfig) { super.onConfigurationChanged(newParentConfig); if (mTaskFragmentOrganizer != null) { // Parent config may have changed. The controller will check if there is any important // config change for the organizer. mTaskFragmentOrganizerController .onTaskFragmentParentInfoChanged(mTaskFragmentOrganizer, this); mTaskFragmentOrganizerController .onTaskFragmentInfoChanged(mTaskFragmentOrganizer, this); } } // TODO(b/190433129) call when TaskFragment is created from WCT#createTaskFragment private void sendTaskFragmentAppeared() { if (mTaskFragmentOrganizer != null) { mTaskFragmentOrganizerController.onTaskFragmentAppeared(mTaskFragmentOrganizer, this); } } // TODO(b/190433129) call when TaskFragment is removed from WCT#deleteTaskFragment private void sendTaskFragmentVanished() { if (mTaskFragmentOrganizer != null) { mTaskFragmentOrganizerController.onTaskFragmentVanished(mTaskFragmentOrganizer, this); } } /** /** * Returns a {@link TaskFragmentInfo} with information from this TaskFragment. Should not be * Returns a {@link TaskFragmentInfo} with information from this TaskFragment. Should not be * called from {@link Task}. * called from {@link Task}. Loading
services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +58 −5 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,9 @@ package com.android.server.wm; package com.android.server.wm; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer; import android.content.res.Configuration; import android.os.Binder; import android.os.Binder; import android.os.IBinder; import android.os.IBinder; import android.os.RemoteException; import android.os.RemoteException; Loading @@ -27,11 +29,13 @@ import android.view.SurfaceControl; import android.window.ITaskFragmentOrganizer; import android.window.ITaskFragmentOrganizer; import android.window.ITaskFragmentOrganizerController; import android.window.ITaskFragmentOrganizerController; import android.window.TaskFragmentAppearedInfo; import android.window.TaskFragmentAppearedInfo; import android.window.TaskFragmentInfo; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.protolog.common.ProtoLog; import java.util.Map; import java.util.Map; import java.util.Set; import java.util.Set; import java.util.WeakHashMap; /** /** * Stores and manages the client {@link android.window.TaskFragmentOrganizer}. * Stores and manages the client {@link android.window.TaskFragmentOrganizer}. Loading @@ -43,6 +47,10 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr private final WindowManagerGlobalLock mGlobalLock; private final WindowManagerGlobalLock mGlobalLock; private final Set<ITaskFragmentOrganizer> mOrganizers = new ArraySet<>(); private final Set<ITaskFragmentOrganizer> mOrganizers = new ArraySet<>(); private final Map<ITaskFragmentOrganizer, DeathRecipient> mDeathRecipients = new ArrayMap<>(); private final Map<ITaskFragmentOrganizer, DeathRecipient> mDeathRecipients = new ArrayMap<>(); private final Map<TaskFragment, TaskFragmentInfo> mLastSentTaskFragmentInfos = new WeakHashMap<>(); private final Map<TaskFragment, Configuration> mLastSentTaskFragmentParentConfigs = new WeakHashMap<>(); private class DeathRecipient implements IBinder.DeathRecipient { private class DeathRecipient implements IBinder.DeathRecipient { final ITaskFragmentOrganizer mOrganizer; final ITaskFragmentOrganizer mOrganizer; Loading Loading @@ -118,43 +126,75 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentAppeared(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(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()); try { final TaskFragmentInfo info = tf.getTaskFragmentInfo(); final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(), final SurfaceControl outSurfaceControl = new SurfaceControl(tf.getSurfaceControl(), "TaskFragmentOrganizerController.onTaskFragmentInfoAppeared"); "TaskFragmentOrganizerController.onTaskFragmentInfoAppeared"); try { organizer.onTaskFragmentAppeared( organizer.onTaskFragmentAppeared( new TaskFragmentAppearedInfo(tf.getTaskFragmentInfo(), outSurfaceControl)); new TaskFragmentAppearedInfo(info, outSurfaceControl)); mLastSentTaskFragmentInfos.put(tf, info); } catch (RemoteException e) { } catch (RemoteException e) { // Oh well... // Oh well... } } } } void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(organizer); // Check if the info is different from the last reported info. final TaskFragmentInfo info = tf.getTaskFragmentInfo(); final TaskFragmentInfo lastInfo = mLastSentTaskFragmentInfos.get(tf); if (info.equalsForTaskFragmentOrganizer(lastInfo) && configurationsAreEqualForOrganizer( info.getConfiguration(), lastInfo.getConfiguration())) { return; } ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s", tf.getName()); ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment info changed name=%s", tf.getName()); try { try { organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo()); organizer.onTaskFragmentInfoChanged(tf.getTaskFragmentInfo()); mLastSentTaskFragmentInfos.put(tf, info); } catch (RemoteException e) { } catch (RemoteException e) { // Oh well... // Oh well... } } } } void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentVanished(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(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... // Oh well... } } mLastSentTaskFragmentInfos.remove(tf); mLastSentTaskFragmentParentConfigs.remove(tf); } } void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { void onTaskFragmentParentInfoChanged(ITaskFragmentOrganizer organizer, TaskFragment tf) { validateOrganizer(organizer); // Check if the parent info is different from the last reported parent info. if (tf.getParent() == null || tf.getParent().asTask() == null) { mLastSentTaskFragmentParentConfigs.remove(tf); return; } final Task parent = tf.getParent().asTask(); final Task parent = tf.getParent().asTask(); final Configuration parentConfig = parent.getConfiguration(); final Configuration lastParentConfig = mLastSentTaskFragmentParentConfigs.get(tf); if (configurationsAreEqualForOrganizer(parentConfig, lastParentConfig)) { return; } ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "TaskFragment parent info changed name=%s parentTaskId=%d", "TaskFragment parent info changed name=%s parentTaskId=%d", tf.getName(), parent.mTaskId); tf.getName(), parent.mTaskId); try { try { organizer.onTaskFragmentParentInfoChanged( organizer.onTaskFragmentParentInfoChanged(tf.getFragmentToken(), parentConfig); tf.getFragmentToken(), parent.getConfiguration()); mLastSentTaskFragmentParentConfigs.put(tf, parentConfig); } catch (RemoteException e) { } catch (RemoteException e) { // Oh well... // Oh well... } } Loading @@ -167,4 +207,17 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } // TODO(b/190432728) move child activities of organized TaskFragment to leaf Task // TODO(b/190432728) move child activities of organized TaskFragment to leaf Task } } /** * Makes sure that the organizer has been correctly registered to prevent any Sidecar * implementation from organizing {@link TaskFragment} without registering first. In such case, * 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)) { throw new IllegalArgumentException( "TaskFragmentOrganizer has not been registered. Organizer=" + organizer); } } } }
services/core/java/com/android/server/wm/TaskOrganizerController.java +4 −22 Original line number Original line Diff line number Diff line Loading @@ -23,15 +23,13 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANI import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission; import static com.android.server.wm.ActivityTaskManagerService.enforceTaskPermission; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL; import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_STARTING_REVEAL; import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_CONFIGS; import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer; import static com.android.server.wm.WindowOrganizerController.CONTROLLABLE_WINDOW_CONFIGS; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningTaskInfo; import android.app.WindowConfiguration; import android.app.WindowConfiguration; import android.content.Intent; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ParceledListSlice; import android.content.pm.ParceledListSlice; import android.graphics.Rect; import android.graphics.Rect; import android.os.Binder; import android.os.Binder; Loading Loading @@ -69,13 +67,6 @@ import java.util.function.Consumer; class TaskOrganizerController extends ITaskOrganizerController.Stub { class TaskOrganizerController extends ITaskOrganizerController.Stub { private static final String TAG = "TaskOrganizerController"; private static final String TAG = "TaskOrganizerController"; /** * Masks specifying which configurations are important to report back to an organizer when * changed. */ private static final int REPORT_CONFIGS = CONTROLLABLE_CONFIGS; private static final int REPORT_WINDOW_CONFIGS = CONTROLLABLE_WINDOW_CONFIGS; // The set of modes that are currently supports // The set of modes that are currently supports // TODO: Remove once the task organizer can support all modes // TODO: Remove once the task organizer can support all modes @VisibleForTesting @VisibleForTesting Loading Loading @@ -790,18 +781,9 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { mTmpTaskInfo.configuration.unset(); mTmpTaskInfo.configuration.unset(); task.fillTaskInfo(mTmpTaskInfo); task.fillTaskInfo(mTmpTaskInfo); boolean changed = !mTmpTaskInfo.equalsForTaskOrganizer(lastInfo); boolean changed = !mTmpTaskInfo.equalsForTaskOrganizer(lastInfo) if (!changed) { || !configurationsAreEqualForOrganizer( int cfgChanges = mTmpTaskInfo.configuration.diff(lastInfo.configuration); mTmpTaskInfo.configuration, lastInfo.configuration); final int winCfgChanges = (cfgChanges & ActivityInfo.CONFIG_WINDOW_CONFIGURATION) != 0 ? (int) mTmpTaskInfo.configuration.windowConfiguration.diff( lastInfo.configuration.windowConfiguration, true /* compareUndefined */) : 0; if ((winCfgChanges & REPORT_WINDOW_CONFIGS) == 0) { cfgChanges &= ~ActivityInfo.CONFIG_WINDOW_CONFIGURATION; } changed = (cfgChanges & REPORT_CONFIGS) != 0; } if (!(changed || force)) { if (!(changed || force)) { // mTmpTaskInfo will be reused next time. // mTmpTaskInfo will be reused next time. return; return; Loading