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

Commit f929bd97 authored by Evan Rosky's avatar Evan Rosky Committed by Automerger Merge Worker
Browse files

Merge "Restrict ime adjustment to maintain primary split visibility" into...

Merge "Restrict ime adjustment to maintain primary split visibility" into rvc-dev am: 0942cde6 am: 97c3d5ab am: 66e652bf

Change-Id: I81e5fb4735b1d72a9bcc10e51583885a11a72a8d
parents d140fc2e 66e652bf
Loading
Loading
Loading
Loading
+17 −7
Original line number Diff line number Diff line
@@ -273,10 +273,12 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            }

            // Update all the adjusted-for-ime states
            if (!mPaused) {
                mView.setAdjustedForIme(mTargetShown, mTargetShown
                        ? DisplayImeController.ANIMATION_DURATION_SHOW_MS
                        : DisplayImeController.ANIMATION_DURATION_HIDE_MS);
            setAdjustedForIme(mTargetShown);
            }
            setAdjustedForIme(mTargetShown && !mPaused);
        }

        @Override
@@ -390,6 +392,9 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
                mTargetPrimaryDim = mTargetSecondaryDim = 0.f;
                updateImeAdjustState();
                startAsyncAnimation();
                if (mAnimation != null) {
                    mAnimation.end();
                }
            });
        }

@@ -605,15 +610,17 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
                    + mHomeStackResizable + "->" + homeStackResizable + " split:" + inSplitMode());
        }
        WindowContainerTransaction wct = new WindowContainerTransaction();
        final boolean minimizedChanged = mMinimized != minimized;
        // Update minimized state
        if (mMinimized != minimized) {
        if (minimizedChanged) {
            mMinimized = minimized;
        }
        // Always set this because we could be entering split when mMinimized is already true
        wct.setFocusable(mSplits.mPrimary.token, !mMinimized);

        // Update home-stack resizability
        if (mHomeStackResizable != homeStackResizable) {
        final boolean homeResizableChanged = mHomeStackResizable != homeStackResizable;
        if (homeResizableChanged) {
            mHomeStackResizable = homeStackResizable;
            if (inSplitMode()) {
                WindowManagerProxy.applyHomeTasksMinimized(
@@ -629,7 +636,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            if (mMinimized) {
                mImePositionProcessor.pause(displayId);
            }
            if (minimizedChanged || homeResizableChanged) {
                // This conflicts with IME adjustment, so only call it when things change.
                mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable);
            }
            if (!mMinimized) {
                // afterwards so it can end any animations started in view
                mImePositionProcessor.resume(displayId);
+16 −5
Original line number Diff line number Diff line
@@ -191,13 +191,24 @@ public class SplitDisplayLayout {
        final int currDividerWidth =
                (int) (dividerWidthInactive * shownFraction + dividerWidth * (1.f - shownFraction));

        // Calculate the highest we can move the bottom of the top stack to keep 30% visible.
        final int minTopStackBottom = displayStableRect.top
                + (int) ((mPrimary.bottom - displayStableRect.top) * ADJUSTED_STACK_FRACTION_MIN);
        final int minImeTop = minTopStackBottom + currDividerWidth;

        // Calculate an offset which shifts the stacks up by the height of the IME, but still
        // leaves at least 30% of the top stack visible.
        final int yOffset = Math.max(0, dl.height() - Math.max(currImeTop, minImeTop));
        // Based on that, calculate the maximum amount we'll allow the ime to shift things.
        final int maxOffset = mPrimary.bottom - minTopStackBottom;
        // Calculate how much we would shift things without limits (basically the height of ime).
        final int desiredOffset = hiddenTop - shownTop;
        // Calculate an "adjustedTop" which is the currImeTop but restricted by our constraints.
        // We want an effect where the adjustment only occurs during the "highest" portion of the
        // ime animation. This is done by shifting the adjustment values by the difference in
        // offsets (effectively playing the whole adjustment animation some fixed amount of pixels
        // below the ime top).
        final int topCorrection = Math.max(0, desiredOffset - maxOffset);
        final int adjustedTop = currImeTop + topCorrection;
        // The actual yOffset is the distance between adjustedTop and the bottom of the display.
        // Since our adjustedTop values are playing "below" the ime, we clamp at 0 so we only
        // see adjustment upward.
        final int yOffset = Math.max(0, dl.height() - adjustedTop);

        // TOP
        // Reduce the offset by an additional small amount to squish the divider bar.
+10 −3
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@ import android.os.RemoteException;
import android.util.Log;
import android.view.Display;
import android.view.ITaskOrganizer;
import android.view.IWindowContainer;
import android.view.SurfaceControl;
import android.view.SurfaceSession;

@@ -108,6 +107,8 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
     * presentations based on the contents of the split regions.
     */
    private void handleTaskInfoChanged(RunningTaskInfo info) {
        final boolean secondaryWasHomeOrRecents = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
                || mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS;
        final boolean primaryWasEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
        final boolean secondaryWasEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
        if (info.token.asBinder() == mPrimary.token.asBinder()) {
@@ -117,9 +118,16 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
        }
        final boolean primaryIsEmpty = mPrimary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
        final boolean secondaryIsEmpty = mSecondary.topActivityType == ACTIVITY_TYPE_UNDEFINED;
        final boolean secondaryIsHomeOrRecents = mSecondary.topActivityType == ACTIVITY_TYPE_HOME
                || mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS;
        if (DEBUG) {
            Log.d(TAG, "onTaskInfoChanged " + mPrimary + "  " + mSecondary);
        }
        if (primaryIsEmpty == primaryWasEmpty && secondaryWasEmpty == secondaryIsEmpty
                && secondaryWasHomeOrRecents == secondaryIsHomeOrRecents) {
            // No relevant changes
            return;
        }
        if (primaryIsEmpty || secondaryIsEmpty) {
            // At-least one of the splits is empty which means we are currently transitioning
            // into or out-of split-screen mode.
@@ -146,8 +154,7 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
                }
                mDivider.startEnterSplit();
            }
        } else if (mSecondary.topActivityType == ACTIVITY_TYPE_HOME
                || mSecondary.topActivityType == ACTIVITY_TYPE_RECENTS) {
        } else if (secondaryIsHomeOrRecents) {
            // Both splits are populated but the secondary split has a home/recents stack on top,
            // so enter minimized mode.
            mDivider.ensureMinimizedSplit();
+15 −7
Original line number Diff line number Diff line
@@ -1938,7 +1938,12 @@ class Task extends WindowContainer<WindowContainer> {
        // TODO: Should also take care of Pip mode changes here.

        saveLaunchingStateIfNeeded();
        updateTaskOrganizerState(false /* forceUpdate */);
        final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */);
        // If the task organizer has changed, then it will already be receiving taskAppeared with
        // the latest task-info thus the task-info won't have changed.
        if (!taskOrgChanged && mTaskOrganizer != null) {
            mAtmService.mTaskOrganizerController.dispatchTaskInfoChanged(this, false /* force */);
        }
    }

    /**
@@ -4043,15 +4048,16 @@ class Task extends WindowContainer<WindowContainer> {
        }
   }

    void setTaskOrganizer(ITaskOrganizer organizer) {
    boolean setTaskOrganizer(ITaskOrganizer organizer) {
        if (mTaskOrganizer == organizer) {
            return;
            return false;
        }
        // Let the old organizer know it has lost control.
        sendTaskVanished();
        mTaskOrganizer = organizer;
        sendTaskAppeared();
        onTaskOrganizerChanged();
        return true;
    }

    // Called on Binder death.
@@ -4068,10 +4074,11 @@ class Task extends WindowContainer<WindowContainer> {
     * @param forceUpdate Updates the task organizer to the one currently specified in the task
     *                    org controller for the task's windowing mode, ignoring the cached
     *                    windowing mode checks.
     * @return {@code true} if task organizer changed.
     */
    void updateTaskOrganizerState(boolean forceUpdate) {
    boolean updateTaskOrganizerState(boolean forceUpdate) {
        if (!isRootTask()) {
            return;
            return false;
        }

        final int windowingMode = getWindowingMode();
@@ -4080,7 +4087,7 @@ class Task extends WindowContainer<WindowContainer> {
            // with our old organizer. This lets us implement the semantic
            // where SysUI can continue to manage it's old tasks
            // while CTS temporarily takes over the registration.
            return;
            return false;
        }
        /*
         * Different windowing modes may be managed by different task organizers. If
@@ -4089,8 +4096,9 @@ class Task extends WindowContainer<WindowContainer> {
         */
        final ITaskOrganizer org =
                mWmService.mAtmService.mTaskOrganizerController.getTaskOrganizer(windowingMode);
        setTaskOrganizer(org);
        final boolean result = setTaskOrganizer(org);
        mLastTaskOrganizerWindowingMode = windowingMode;
        return result;
    }

    private void onTaskOrganizerChanged() {
+40 −7
Original line number Diff line number Diff line
@@ -67,6 +67,21 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub
    private static final int TRANSACT_EFFECTS_CLIENT_CONFIG = 1;
    private static final int TRANSACT_EFFECTS_LIFECYCLE = 1 << 1;

    /**
     * Masks specifying which configurations task-organizers can control. Incoming transactions
     * will be filtered to only include these.
     */
    private static final int CONTROLLABLE_CONFIGS = ActivityInfo.CONFIG_WINDOW_CONFIGURATION
                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE | ActivityInfo.CONFIG_SCREEN_SIZE;
    private static final int CONTROLLABLE_WINDOW_CONFIGS = WindowConfiguration.WINDOW_CONFIG_BOUNDS
                | WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
    /**
     * 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;

    private final WindowManagerGlobalLock mGlobalLock;

    private class DeathRecipient implements IBinder.DeathRecipient {
@@ -321,11 +336,23 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub
        if (mTmpTaskInfo == null) {
            mTmpTaskInfo = new RunningTaskInfo();
        }
        mTmpTaskInfo.configuration.unset();
        task.fillTaskInfo(mTmpTaskInfo);
        boolean changed = lastInfo == null
                || mTmpTaskInfo.topActivityType != lastInfo.topActivityType
                || mTmpTaskInfo.isResizable() != lastInfo.isResizable()
                || mTmpTaskInfo.pictureInPictureParams != lastInfo.pictureInPictureParams;
        if (!changed) {
            int cfgChanges = mTmpTaskInfo.configuration.diff(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)) {
            return;
        }
@@ -480,12 +507,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub
        final Task task = (Task) container;
        // The "client"-facing API should prevent bad changes; however, just in case, sanitize
        // masks here.
        int configMask = change.getConfigSetMask();
        int windowMask = change.getWindowSetMask();
        configMask &= ActivityInfo.CONFIG_WINDOW_CONFIGURATION
                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE | ActivityInfo.CONFIG_SCREEN_SIZE;
        windowMask &= (WindowConfiguration.WINDOW_CONFIG_BOUNDS
                | WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS);
        final int configMask = change.getConfigSetMask() & CONTROLLABLE_CONFIGS;
        final int windowMask = change.getWindowSetMask() & CONTROLLABLE_WINDOW_CONFIGS;
        int effects = 0;
        if (configMask != 0) {
            Configuration c = new Configuration(container.getRequestedOverrideConfiguration());
@@ -672,7 +695,17 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub
                                false /* preserveWindow */);
                        try {
                            for (int i = haveConfigChanges.size() - 1; i >= 0; --i) {
                                haveConfigChanges.valueAt(i).forAllActivities(f);
                                final WindowContainer wc = haveConfigChanges.valueAt(i);
                                final Task task = wc.asTask();
                                final TaskTile tile = task != null ? task.asTile() : null;
                                if (tile != null) {
                                    // Special case for tile. Can't override normal forAllActivities
                                    // because it generates duplicate calls and messes up existing
                                    // code-paths.
                                    tile.forAllTileActivities(f);
                                } else {
                                    wc.forAllActivities(f);
                                }
                            }
                        } finally {
                            f.recycle();
Loading