Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a00e2b2 authored by Chris Li's avatar Chris Li Committed by Android (Google) Code Review
Browse files

Merge "Notify TaskFragmentOrganizer onConfigurationChanged" into sc-v2-dev

parents 4b698e0d ad2dc018
Loading
Loading
Loading
Loading
+4 −5
Original line number Original line Diff line number Diff line
@@ -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) {
+25 −0
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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);
+31 −0
Original line number Original line Diff line number Diff line
@@ -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
@@ -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) {
@@ -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}.
+58 −5
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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}.
@@ -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;
@@ -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...
        }
        }
@@ -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);
        }
    }
}
}
+4 −22
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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
@@ -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