Merge "Defer resizing invisible stacks while drag resizing" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-04-20 14:43:38 +00:00
committed by Android (Google) Code Review
10 changed files with 148 additions and 9 deletions

View File

@@ -575,6 +575,11 @@ interface IActivityManager {
void resizeDockedStack(in Rect dockedBounds, in Rect tempDockedTaskBounds,
in Rect tempDockedTaskInsetBounds,
in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds);
/**
* Sets whether we are currently in an interactive split screen resize operation where we
* are changing the docked stack size.
*/
void setSplitScreenResizing(boolean resizing);
int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName);
// Gets the URI permissions granted to an arbitrary package (or all packages if null)
// NOTE: this is different from getPersistedUriPermissions(), which returns the URIs the package

View File

@@ -341,12 +341,6 @@ interface IWindowManager
*/
int getDockedStackSide();
/**
* Sets whether we are currently in a drag resize operation where we are changing the docked
* stack size.
*/
void setDockedStackResizing(boolean resizing);
/**
* Sets the region the user can touch the divider. This region will be excluded from the region
* which is used to cause a focus switch when dispatching touch.

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.graphics;
import static android.graphics.Rect.copyOrNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
public class RectTest {
@Test
public void copyOrNull_passesThroughNull() {
assertNull(copyOrNull(null));
}
@Test
public void copyOrNull_copiesNonNull() {
final Rect orig = new Rect(1, 2, 3, 4);
final Rect copy = copyOrNull(orig);
assertEquals(orig, copy);
assertNotSame(orig, copy);
}
}

View File

@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.CheckResult;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -99,6 +100,16 @@ public final class Rect implements Parcelable {
}
}
/**
* Returns a copy of {@code r} if {@code r} is not {@code null}, or {@code null} otherwise.
*
* @hide
*/
@Nullable
public static Rect copyOrNull(@Nullable Rect r) {
return r == null ? null : new Rect(r);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@@ -180,7 +180,7 @@ public class WindowManagerProxy {
@Override
public void run() {
try {
WindowManagerGlobal.getWindowManagerService().setDockedStackResizing(resizing);
ActivityManager.getService().setSplitScreenResizing(resizing);
} catch (RemoteException e) {
Log.w(TAG, "Error calling setDockedStackResizing: " + e);
}

View File

@@ -11450,6 +11450,19 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
@Override
public void setSplitScreenResizing(boolean resizing) {
enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
final long ident = Binder.clearCallingIdentity();
try {
synchronized (this) {
mStackSupervisor.setSplitScreenResizing(resizing);
}
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override
public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");

View File

@@ -1743,6 +1743,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
return getDisplay().isTopStack(this);
}
boolean isTopActivityVisible() {
final ActivityRecord topActivity = getTopActivity();
return topActivity != null && topActivity.visible;
}
/**
* Returns true if the stack should be visible.
*

View File

@@ -43,6 +43,7 @@ import static android.app.WindowConfiguration.activityTypeToString;
import static android.app.WindowConfiguration.windowingModeToString;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.graphics.Rect.copyOrNull;
import static android.os.PowerManager.PARTIAL_WAKE_LOCK;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
@@ -245,6 +246,20 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// the activity callback indicating that it has completed pausing
static final boolean PAUSE_IMMEDIATELY = true;
/** True if the docked stack is currently being resized. */
private boolean mDockedStackResizing;
/**
* True if there are pending docked bounds that need to be applied after
* {@link #mDockedStackResizing} is reset to false.
*/
private boolean mHasPendingDockedBounds;
private Rect mPendingDockedBounds;
private Rect mPendingTempDockedTaskBounds;
private Rect mPendingTempDockedTaskInsetBounds;
private Rect mPendingTempOtherTaskBounds;
private Rect mPendingTempOtherTaskInsetBounds;
/**
* The modes which affect which tasks are returned when calling
* {@link ActivityStackSupervisor#anyTaskForIdLocked(int)}.
@@ -2708,6 +2723,28 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
moveTasksToFullscreenStackInSurfaceTransaction(fromStack, toDisplayId, onTop));
}
void setSplitScreenResizing(boolean resizing) {
if (resizing == mDockedStackResizing) {
return;
}
mDockedStackResizing = resizing;
mWindowManager.setDockedStackResizing(resizing);
if (!resizing && mHasPendingDockedBounds) {
resizeDockedStackLocked(mPendingDockedBounds, mPendingTempDockedTaskBounds,
mPendingTempDockedTaskInsetBounds, mPendingTempOtherTaskBounds,
mPendingTempOtherTaskInsetBounds, PRESERVE_WINDOWS);
mHasPendingDockedBounds = false;
mPendingDockedBounds = null;
mPendingTempDockedTaskBounds = null;
mPendingTempDockedTaskInsetBounds = null;
mPendingTempOtherTaskBounds = null;
mPendingTempOtherTaskInsetBounds = null;
}
}
void resizeDockedStackLocked(Rect dockedBounds, Rect tempDockedTaskBounds,
Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds,
boolean preserveWindows) {
@@ -2731,6 +2768,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
return;
}
if (mDockedStackResizing) {
mHasPendingDockedBounds = true;
mPendingDockedBounds = copyOrNull(dockedBounds);
mPendingTempDockedTaskBounds = copyOrNull(tempDockedTaskBounds);
mPendingTempDockedTaskInsetBounds = copyOrNull(tempDockedTaskInsetBounds);
mPendingTempOtherTaskBounds = copyOrNull(tempOtherTaskBounds);
mPendingTempOtherTaskInsetBounds = copyOrNull(tempOtherTaskInsetBounds);
}
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeDockedStack");
mWindowManager.deferSurfaceLayout();
try {
@@ -2765,6 +2811,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
if (!current.affectedBySplitScreenResize()) {
continue;
}
if (mDockedStackResizing && !current.isTopActivityVisible()) {
// Non-visible stacks get resized once we're done with the resize
// interaction.
continue;
}
// Need to set windowing mode here before we try to get the dock bounds.
current.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
current.getStackDockedModeBounds(

View File

@@ -6864,7 +6864,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
@Override
public void setDockedStackResizing(boolean resizing) {
synchronized (mWindowMap) {
getDefaultDisplayContentLocked().getDockedDividerController().setResizing(resizing);

View File

@@ -2405,6 +2405,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
@Override
public void binderDied() {
try {
boolean resetSplitScreenResizing = false;
synchronized(mService.mWindowMap) {
final WindowState win = mService.windowForClientLocked(mSession, mClient, false);
Slog.i(TAG, "WIN DEATH: " + win);
@@ -2424,13 +2425,23 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (stack != null) {
stack.resetDockedStackToMiddle();
}
mService.setDockedStackResizing(false);
resetSplitScreenResizing = true;
}
} else if (mHasSurface) {
Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
WindowState.this.removeIfPossible();
}
}
if (resetSplitScreenResizing) {
try {
// Note: this calls into ActivityManager, so we must *not* hold the window
// manager lock while calling this.
mService.mActivityManager.setSplitScreenResizing(false);
} catch (RemoteException e) {
// Local call, shouldn't return RemoteException.
throw e.rethrowAsRuntimeException();
}
}
} catch (IllegalArgumentException ex) {
// This will happen if the window has already been removed.
}