Merge "Avoid extra relaunch when rotating side-by-side apps" into nyc-dev

am: fbe10f1

* commit 'fbe10f175fa3cb2083d15b4dbfb05c6f223d7f2c':
  Avoid extra relaunch when rotating side-by-side apps

Change-Id: I1f58f668a9593571b26d9c8c9692cd625e9679a8
This commit is contained in:
Chong Zhang
2016-04-01 22:07:39 +00:00
committed by android-build-merger
6 changed files with 87 additions and 22 deletions

View File

@@ -180,7 +180,12 @@ interface IWindowManager
// caller must call setNewConfiguration() sometime later.
Configuration updateOrientationFromAppTokens(in Configuration currentConfig,
IBinder freezeThisOneIfNeeded);
void setNewConfiguration(in Configuration config);
// Notify window manager of the new configuration. Returns an array of stack ids that's
// affected by the update, ActivityManager should resize these stacks.
int[] setNewConfiguration(in Configuration config);
// Retrieves the new bounds after the configuration update evaluated by window manager.
Rect getBoundsForNewConfiguration(int stackId);
void startFreezingScreen(int exitAnim, int enterAnim);
void stopFreezingScreen();

View File

@@ -238,6 +238,14 @@ public class ArrayUtils {
return total;
}
public static int[] convertToIntArray(List<Integer> list) {
int[] array = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
return array;
}
/**
* Adds value to given array if not already present, providing set-like
* behavior.

View File

@@ -18045,6 +18045,9 @@ public final class ActivityManagerService extends ActivityManagerNative
ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
int changes = 0;
if (mWindowManager != null) {
mWindowManager.deferSurfaceLayout();
}
if (values != null) {
Configuration newConfig = new Configuration(mConfiguration);
changes = newConfig.updateFrom(values);
@@ -18145,6 +18148,20 @@ public final class ActivityManagerService extends ActivityManagerNative
null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
}
}
// Update the configuration with WM first and check if any of the stacks need to be
// resized due to the configuration change. If so, resize the stacks now and do any
// relaunches if necessary. This way we don't need to relaunch again below in
// ensureActivityConfigurationLocked().
if (mWindowManager != null) {
final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
if (resizedStacks != null) {
for (int stackId : resizedStacks) {
final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
mStackSupervisor.resizeStackLocked(
stackId, newBounds, null, null, false, false);
}
}
}
}
boolean kept = true;
@@ -18166,11 +18183,9 @@ public final class ActivityManagerService extends ActivityManagerNative
!PRESERVE_WINDOWS);
}
}
if (values != null && mWindowManager != null) {
mWindowManager.setNewConfiguration(mConfiguration);
if (mWindowManager != null) {
mWindowManager.continueSurfaceLayout();
}
return kept;
}

View File

@@ -128,6 +128,10 @@ public class TaskStack implements DimLayer.DimLayerUser,
// in which case a second window animation would cause jitter.
private boolean mFreezeMovementAnimations = false;
// Temporary storage for the new bounds that should be used after the configuration change.
// Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
private final Rect mBoundsAfterRotation = new Rect();
TaskStack(WindowManagerService service, int stackId) {
mService = service;
mStackId = stackId;
@@ -343,28 +347,28 @@ public class TaskStack implements DimLayer.DimLayerUser,
setBounds(mTmpRect2);
} else {
mLastUpdateDisplayInfoRotation = newRotation;
updateBoundsAfterRotation();
updateBoundsAfterRotation(true);
}
}
void onConfigurationChanged() {
boolean onConfigurationChanged() {
mLastConfigChangedRotation = getDisplayInfo().rotation;
updateBoundsAfterRotation();
return updateBoundsAfterRotation(false);
}
void updateBoundsAfterRotation() {
boolean updateBoundsAfterRotation(boolean scheduleResize) {
if (mLastConfigChangedRotation != mLastUpdateDisplayInfoRotation) {
// We wait for the rotation values after configuration change and display info. update
// to be equal before updating the bounds due to rotation change otherwise things might
// get out of alignment...
return;
return false;
}
final int newRotation = getDisplayInfo().rotation;
if (mRotation == newRotation) {
// Nothing to do here if the rotation didn't change
return;
return false;
}
mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
@@ -373,11 +377,22 @@ public class TaskStack implements DimLayer.DimLayerUser,
snapDockedStackAfterRotation(mTmpRect2);
}
// Post message to inform activity manager of the bounds change simulating
// a one-way call. We do this to prevent a deadlock between window manager
// lock and activity manager lock been held.
mService.mH.obtainMessage(
RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget();
if (scheduleResize) {
// Post message to inform activity manager of the bounds change simulating
// a one-way call. We do this to prevent a deadlock between window manager
// lock and activity manager lock been held.
mService.mH.obtainMessage(RESIZE_STACK, mStackId,
0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget();
} else {
mBoundsAfterRotation.set(mTmpRect2);
}
return true;
}
void getBoundsForNewConfiguration(Rect outBounds) {
outBounds.set(mBoundsAfterRotation);
mBoundsAfterRotation.setEmpty();
}
/**

View File

@@ -125,6 +125,7 @@ import com.android.internal.R;
import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IShortcutService;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -515,6 +516,8 @@ public class WindowManagerService extends IWindowManager.Stub
private final SparseIntArray mTmpTaskIds = new SparseIntArray();
private final ArrayList<Integer> mChangedStackList = new ArrayList();
boolean mForceResizableTasks = false;
int getDragLayerLocked() {
@@ -3580,7 +3583,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
public void setNewConfiguration(Configuration config) {
public int[] setNewConfiguration(Configuration config) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setNewConfiguration()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3592,16 +3595,30 @@ public class WindowManagerService extends IWindowManager.Stub
mWaitingForConfig = false;
mLastFinishedFreezeSource = "new-config";
}
onConfigurationChanged();
mWindowPlacerLocked.performSurfacePlacement();
return onConfigurationChanged();
}
}
private void onConfigurationChanged() {
@Override
public Rect getBoundsForNewConfiguration(int stackId) {
synchronized(mWindowMap) {
final TaskStack stack = mStackIdToStack.get(stackId);
final Rect outBounds = new Rect();
stack.getBoundsForNewConfiguration(outBounds);
return outBounds;
}
}
private int[] onConfigurationChanged() {
mChangedStackList.clear();
for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) {
final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
stack.onConfigurationChanged();
if (stack.onConfigurationChanged()) {
mChangedStackList.add(stack.mStackId);
}
}
return mChangedStackList.isEmpty() ?
null : ArrayUtils.convertToIntArray(mChangedStackList);
}
@Override

View File

@@ -403,7 +403,12 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
public void setNewConfiguration(Configuration arg0) throws RemoteException {
public int[] setNewConfiguration(Configuration arg0) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
public Rect getBoundsForNewConfiguration(int stackId) throws RemoteException {
// TODO Auto-generated method stub
}