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

Commit 3b7391c2 authored by Tony Huang's avatar Tony Huang Committed by Automerger Merge Worker
Browse files

Merge "Add api for systemUi getting split visibility" into sc-v2-dev am: ff254dd7 am: 39092ebc

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

Change-Id: Ia5248cfc12f4c0d124b35b8085c80e0439980f03
parents c689abb7 39092ebc
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -17,10 +17,13 @@
package com.android.wm.shell.splitscreen;

import android.annotation.IntDef;
import android.annotation.NonNull;

import com.android.wm.shell.common.annotations.ExternalThread;
import com.android.wm.shell.common.split.SplitLayout.SplitPosition;

import java.util.concurrent.Executor;

/**
 * Interface to engage split-screen feature.
 * TODO: Figure out which of these are actually needed outside of the Shell
@@ -53,10 +56,18 @@ public interface SplitScreen {

    /** Callback interface for listening to changes in a split-screen stage. */
    interface SplitScreenListener {
        void onStagePositionChanged(@StageType int stage, @SplitPosition int position);
        void onTaskStageChanged(int taskId, @StageType int stage, boolean visible);
        default void onStagePositionChanged(@StageType int stage, @SplitPosition int position) {}
        default void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {}
        default void onSplitVisibilityChanged(boolean visible) {}
    }

    /** Registers listener that gets split screen callback. */
    void registerSplitScreenListener(@NonNull SplitScreenListener listener,
            @NonNull Executor executor);

    /** Unregisters listener that gets split screen callback. */
    void unregisterSplitScreenListener(@NonNull SplitScreenListener listener);

    /**
     * Returns a binder that can be passed to an external process to manipulate SplitScreen.
     */
+62 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.RemoteAnimationAdapter;
@@ -64,6 +65,7 @@ import com.android.wm.shell.transition.LegacyTransitions;
import com.android.wm.shell.transition.Transitions;

import java.io.PrintWriter;
import java.util.concurrent.Executor;

/**
 * Class manages split-screen multitasking mode and implements the main interface
@@ -293,6 +295,38 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    @ExternalThread
    private class SplitScreenImpl implements SplitScreen {
        private ISplitScreenImpl mISplitScreen;
        private final ArrayMap<SplitScreenListener, Executor> mExecutors = new ArrayMap<>();
        private final SplitScreen.SplitScreenListener mListener = new SplitScreenListener() {
            @Override
            public void onStagePositionChanged(int stage, int position) {
                for (int i = 0; i < mExecutors.size(); i++) {
                    final int index = i;
                    mExecutors.valueAt(index).execute(() -> {
                        mExecutors.keyAt(index).onStagePositionChanged(stage, position);
                    });
                }
            }

            @Override
            public void onTaskStageChanged(int taskId, int stage, boolean visible) {
                for (int i = 0; i < mExecutors.size(); i++) {
                    final int index = i;
                    mExecutors.valueAt(index).execute(() -> {
                        mExecutors.keyAt(index).onTaskStageChanged(taskId, stage, visible);
                    });
                }
            }

            @Override
            public void onSplitVisibilityChanged(boolean visible) {
                for (int i = 0; i < mExecutors.size(); i++) {
                    final int index = i;
                    mExecutors.valueAt(index).execute(() -> {
                        mExecutors.keyAt(index).onSplitVisibilityChanged(visible);
                    });
                }
            }
        };

        @Override
        public ISplitScreen createExternalInterface() {
@@ -309,6 +343,34 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
                SplitScreenController.this.onKeyguardOccludedChanged(occluded);
            });
        }

        @Override
        public void registerSplitScreenListener(SplitScreenListener listener, Executor executor) {
            if (mExecutors.containsKey(listener)) return;

            mMainExecutor.execute(() -> {
                if (mExecutors.size() == 0) {
                    SplitScreenController.this.registerSplitScreenListener(mListener);
                }

                mExecutors.put(listener, executor);
            });

            executor.execute(() -> {
                mStageCoordinator.sendStatusToListener(listener);
            });
        }

        @Override
        public void unregisterSplitScreenListener(SplitScreenListener listener) {
            mMainExecutor.execute(() -> {
                mExecutors.remove(listener);

                if (mExecutors.size() == 0) {
                    SplitScreenController.this.unregisterSplitScreenListener(mListener);
                }
            });
        }
    }

    /**
+17 −4
Original line number Diff line number Diff line
@@ -501,16 +501,21 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
    void registerSplitScreenListener(SplitScreen.SplitScreenListener listener) {
        if (mListeners.contains(listener)) return;
        mListeners.add(listener);
        listener.onStagePositionChanged(STAGE_TYPE_MAIN, getMainStagePosition());
        listener.onStagePositionChanged(STAGE_TYPE_SIDE, getSideStagePosition());
        mSideStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_SIDE);
        mMainStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_MAIN);
        sendStatusToListener(listener);
    }

    void unregisterSplitScreenListener(SplitScreen.SplitScreenListener listener) {
        mListeners.remove(listener);
    }

    void sendStatusToListener(SplitScreen.SplitScreenListener listener) {
        listener.onStagePositionChanged(STAGE_TYPE_MAIN, getMainStagePosition());
        listener.onStagePositionChanged(STAGE_TYPE_SIDE, getSideStagePosition());
        listener.onSplitVisibilityChanged(isSplitScreenVisible());
        mSideStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_SIDE);
        mMainStage.onSplitScreenListenerRegistered(listener, STAGE_TYPE_MAIN);
    }

    private void sendOnStagePositionChanged() {
        for (int i = mListeners.size() - 1; i >= 0; --i) {
            final SplitScreen.SplitScreenListener l = mListeners.get(i);
@@ -535,6 +540,13 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        }
    }

    private void sendSplitVisibilityChanged() {
        for (int i = mListeners.size() - 1; i >= 0; --i) {
            final SplitScreen.SplitScreenListener l = mListeners.get(i);
            l.onSplitVisibilityChanged(mDividerVisible);
        }
    }

    private void onStageRootTaskAppeared(StageListenerImpl stageListener) {
        if (mMainStageListener.mHasRootTask && mSideStageListener.mHasRootTask) {
            mUseLegacySplit = mContext.getResources().getBoolean(R.bool.config_useLegacySplit);
@@ -574,6 +586,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        } else {
            mSplitLayout.release();
        }
        sendSplitVisibilityChanged();
    }

    private void onStageVisibilityChanged(StageListenerImpl stageListener) {