summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java8
-rw-r--r--services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java2
-rw-r--r--services/core/java/com/android/server/wm/RemoteDisplayChangeController.java106
3 files changed, 48 insertions, 68 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 86ed44e39425..e5ec4c3dfcd2 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -530,13 +530,7 @@ public class DisplayRotation {
private void startRemoteRotation(int fromRotation, int toRotation) {
mDisplayContent.mRemoteDisplayChangeController.performRemoteDisplayChange(
fromRotation, toRotation, null /* newDisplayAreaInfo */,
- (appliedChange, transaction) -> {
- final int newRotation = appliedChange != null
- ? appliedChange.toRotation
- // Timeout occurred, use old rotation
- : fromRotation;
- continueRotation(newRotation, transaction);
- }
+ (transaction) -> continueRotation(toRotation, transaction)
);
}
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
index 3e01f08994f8..d209f08e6312 100644
--- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -120,7 +120,7 @@ public class PhysicalDisplaySwitchTransitionLauncher {
final boolean started = mDisplayContent.mRemoteDisplayChangeController
.performRemoteDisplayChange(fromRotation, toRotation, newDisplayAreaInfo,
- (appliedChange, transaction) -> continueDisplayUpdate(transaction));
+ this::continueDisplayUpdate);
if (!started) {
markTransitionAsReady();
diff --git a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
index 553384b06268..43baebc7255a 100644
--- a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
+++ b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
@@ -18,14 +18,15 @@ package com.android.server.wm;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.RemoteException;
+import android.util.Slog;
import android.view.IDisplayChangeWindowCallback;
import android.window.DisplayAreaInfo;
import android.window.WindowContainerTransaction;
import com.android.internal.protolog.common.ProtoLog;
-import com.android.internal.util.function.pooled.PooledLambda;
import java.util.ArrayList;
import java.util.List;
@@ -38,16 +39,16 @@ import java.util.List;
*/
public class RemoteDisplayChangeController {
+ private static final String TAG = "RemoteDisplayChangeController";
+
private static final int REMOTE_DISPLAY_CHANGE_TIMEOUT_MS = 800;
private final WindowManagerService mService;
private final int mDisplayId;
- private boolean mIsWaitingForRemoteDisplayChange;
- private final Runnable mTimeoutRunnable = () -> {
- continueDisplayChange(null /* appliedChange */, null /* transaction */);
- };
+ private final Runnable mTimeoutRunnable = this::onContinueTimedOut;
+ // all remote changes that haven't finished yet.
private final List<ContinueRemoteDisplayChangeCallback> mCallbacks = new ArrayList<>();
public RemoteDisplayChangeController(WindowManagerService service, int displayId) {
@@ -61,7 +62,7 @@ public class RemoteDisplayChangeController {
* to perform in sync with the display change.
*/
public boolean isWaitingForRemoteDisplayChange() {
- return mIsWaitingForRemoteDisplayChange;
+ return !mCallbacks.isEmpty();
}
/**
@@ -79,7 +80,6 @@ public class RemoteDisplayChangeController {
if (mService.mDisplayChangeController == null) {
return false;
}
- mIsWaitingForRemoteDisplayChange = true;
mCallbacks.add(callback);
if (newDisplayAreaInfo != null) {
@@ -95,91 +95,77 @@ public class RemoteDisplayChangeController {
toRotation);
}
- final RemoteDisplayChange change = new RemoteDisplayChange(fromRotation, toRotation,
- newDisplayAreaInfo);
- final IDisplayChangeWindowCallback remoteCallback = createCallback(change);
+ final IDisplayChangeWindowCallback remoteCallback = createCallback(callback);
try {
- mService.mDisplayChangeController.onDisplayChange(mDisplayId, fromRotation, toRotation,
- newDisplayAreaInfo, remoteCallback);
-
mService.mH.removeCallbacks(mTimeoutRunnable);
mService.mH.postDelayed(mTimeoutRunnable, REMOTE_DISPLAY_CHANGE_TIMEOUT_MS);
+ mService.mDisplayChangeController.onDisplayChange(mDisplayId, fromRotation, toRotation,
+ newDisplayAreaInfo, remoteCallback);
return true;
} catch (RemoteException e) {
- mIsWaitingForRemoteDisplayChange = false;
+ Slog.e(TAG, "Exception while dispatching remote display-change", e);
+ mCallbacks.remove(callback);
return false;
}
}
- private void continueDisplayChange(@Nullable RemoteDisplayChange appliedChange,
- @Nullable WindowContainerTransaction transaction) {
+ private void onContinueTimedOut() {
+ Slog.e(TAG, "RemoteDisplayChange timed-out, UI might get messed-up after this.");
+ // timed-out, so run all continue callbacks and clear the list
synchronized (mService.mGlobalLock) {
- if (appliedChange != null) {
- ProtoLog.v(WM_DEBUG_CONFIGURATION,
- "Received remote change for Display[%d], applied: [%dx%d, rot = %d]",
- mDisplayId,
- appliedChange.displayAreaInfo != null ? appliedChange.displayAreaInfo
- .configuration.windowConfiguration.getMaxBounds().width() : -1,
- appliedChange.displayAreaInfo != null ? appliedChange.displayAreaInfo
- .configuration.windowConfiguration.getMaxBounds().height() : -1,
- appliedChange.toRotation);
- } else {
- ProtoLog.v(WM_DEBUG_CONFIGURATION, "Remote change for Display[%d]: timeout reached",
- mDisplayId);
+ for (int i = 0; i < mCallbacks.size(); ++i) {
+ mCallbacks.get(i).onContinueRemoteDisplayChange(null /* transaction */);
}
+ mCallbacks.clear();
+ }
+ }
- mIsWaitingForRemoteDisplayChange = false;
-
- for (int i = 0; i < mCallbacks.size(); i++) {
- ContinueRemoteDisplayChangeCallback callback = mCallbacks.get(i);
- callback.onContinueRemoteDisplayChange(appliedChange, transaction);
+ private void continueDisplayChange(@NonNull ContinueRemoteDisplayChangeCallback callback,
+ @Nullable WindowContainerTransaction transaction) {
+ synchronized (mService.mGlobalLock) {
+ int idx = mCallbacks.indexOf(callback);
+ if (idx < 0) {
+ // already called this callback or a more-recent one (eg. via timeout)
+ return;
+ }
+ for (int i = 0; i < idx; ++i) {
+ // Expect remote callbacks in order. If they don't come in order, then force
+ // ordering by continuing everything up until this one with empty transactions.
+ mCallbacks.get(i).onContinueRemoteDisplayChange(null /* transaction */);
}
+ mCallbacks.subList(0, idx + 1).clear();
+ if (mCallbacks.isEmpty()) {
+ mService.mH.removeCallbacks(mTimeoutRunnable);
+ }
+ callback.onContinueRemoteDisplayChange(transaction);
}
}
- private IDisplayChangeWindowCallback createCallback(RemoteDisplayChange originalChange) {
+ private IDisplayChangeWindowCallback createCallback(
+ @NonNull ContinueRemoteDisplayChangeCallback callback) {
return new IDisplayChangeWindowCallback.Stub() {
@Override
public void continueDisplayChange(WindowContainerTransaction t) {
synchronized (mService.mGlobalLock) {
- mService.mH.removeCallbacks(mTimeoutRunnable);
- mService.mH.sendMessage(PooledLambda.obtainMessage(
- RemoteDisplayChangeController::continueDisplayChange,
- RemoteDisplayChangeController.this,
- originalChange, t));
+ if (!mCallbacks.contains(callback)) {
+ // already ran this callback or a more-recent one.
+ return;
+ }
+ mService.mH.post(() -> RemoteDisplayChangeController.this
+ .continueDisplayChange(callback, t));
}
}
};
}
/**
- * Data class that contains information about a remote display change
- */
- public static class RemoteDisplayChange {
- final int fromRotation;
- final int toRotation;
- @Nullable
- final DisplayAreaInfo displayAreaInfo;
-
- public RemoteDisplayChange(int fromRotation, int toRotation,
- @Nullable DisplayAreaInfo displayAreaInfo) {
- this.fromRotation = fromRotation;
- this.toRotation = toRotation;
- this.displayAreaInfo = displayAreaInfo;
- }
- }
-
- /**
* Callback interface to handle continuation of the remote display change
*/
public interface ContinueRemoteDisplayChangeCallback {
/**
* This method is called when the remote display change has been applied
- * @param appliedChange the change that was applied or null if there was
- * an error during remote display change (e.g. timeout)
* @param transaction window changes collected by the remote display change
*/
- void onContinueRemoteDisplayChange(@Nullable RemoteDisplayChange appliedChange,
- @Nullable WindowContainerTransaction transaction);
+ void onContinueRemoteDisplayChange(@Nullable WindowContainerTransaction transaction);
}
}