Merge changes from topic "am-9ac462fdf8db49549ee55f6fc0dc3a87" into rvc-d1-dev-plus-aosp
* changes: Merge "Restrict ime adjustment to maintain primary split visibility" into rvc-dev am:0942cde6d6am:e18ed81604Merge "Unset minimized when recents dies" into rvc-dev am:1a760811beam:e9ae3a56be
This commit is contained in:
committed by
Android (Google) Code Review
commit
636112c904
@@ -670,6 +670,12 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
|
||||
});
|
||||
}
|
||||
startConnectionToCurrentUser();
|
||||
|
||||
// Clean up the minimized state if launcher dies
|
||||
Divider divider = mDividerOptional.get();
|
||||
if (divider != null) {
|
||||
divider.setMinimized(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void startConnectionToCurrentUser() {
|
||||
|
||||
@@ -273,10 +273,12 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
|
||||
}
|
||||
|
||||
// Update all the adjusted-for-ime states
|
||||
mView.setAdjustedForIme(mTargetShown, mTargetShown
|
||||
? DisplayImeController.ANIMATION_DURATION_SHOW_MS
|
||||
: DisplayImeController.ANIMATION_DURATION_HIDE_MS);
|
||||
setAdjustedForIme(mTargetShown);
|
||||
if (!mPaused) {
|
||||
mView.setAdjustedForIme(mTargetShown, mTargetShown
|
||||
? DisplayImeController.ANIMATION_DURATION_SHOW_MS
|
||||
: DisplayImeController.ANIMATION_DURATION_HIDE_MS);
|
||||
}
|
||||
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);
|
||||
}
|
||||
mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable);
|
||||
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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.util.Slog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A Tile. Right now this acts as a proxy for manipulating non-child stacks. Eventually, this
|
||||
@@ -141,6 +142,12 @@ public class TaskTile extends ActivityStack {
|
||||
}
|
||||
}
|
||||
|
||||
void forAllTileActivities(Consumer<ActivityRecord> callback) {
|
||||
for (int i = mChildren.size() - 1; i >= 0; --i) {
|
||||
mChildren.get(i).forAllActivities(callback, true /* traverseTopToBottom */);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Until this can be part of the hierarchy, the Stack level can use this utility during
|
||||
* resolveOverrideConfig to simulate inheritance.
|
||||
|
||||
Reference in New Issue
Block a user