Fixes concurrent display test flakiness am: c3b80dc70b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22656860

Change-Id: I3deee71a0e007a5e59cddfe8fb1d5e697753bbeb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Kenneth Ford
2023-05-10 20:04:57 +00:00
committed by Automerger Merge Worker
3 changed files with 127 additions and 30 deletions

View File

@@ -20,9 +20,6 @@ import static androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_
import static androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_INACTIVE; import static androidx.window.extensions.area.WindowAreaComponent.SESSION_STATE_INACTIVE;
import android.content.Context; import android.content.Context;
import android.hardware.devicestate.DeviceStateRequest;
import android.hardware.display.DisplayManager;
import android.util.Log;
import android.view.Display; import android.view.Display;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -32,17 +29,12 @@ import androidx.window.extensions.core.util.function.Consumer;
import java.util.Objects; import java.util.Objects;
/** /**
* Controller class that keeps track of the status of the device state request * Controller class that manages the creation of the {@link android.app.Presentation} object used
* to enable the rear display presentation feature. This controller notifies the session callback * to show content on the rear facing display. This controller notifies the session callback with
* when the state request is active, and notifies the callback when the request is canceled. * {@link androidx.window.extensions.area.WindowAreaComponent.WindowAreaStatus} values when the
* * feature is active, or when the feature has been ended.
* Clients are notified via {@link Consumer} provided with
* {@link androidx.window.extensions.area.WindowAreaComponent.WindowAreaStatus} values to signify
* when the request becomes active and cancelled.
*/ */
class RearDisplayPresentationController implements DeviceStateRequest.Callback { class RearDisplayPresentationController {
private static final String TAG = "RearDisplayPresentationController";
// Original context that requested to enable rear display presentation mode // Original context that requested to enable rear display presentation mode
@NonNull @NonNull
@@ -51,8 +43,6 @@ class RearDisplayPresentationController implements DeviceStateRequest.Callback {
private final Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> mStateConsumer; private final Consumer<@WindowAreaComponent.WindowAreaSessionState Integer> mStateConsumer;
@Nullable @Nullable
private ExtensionWindowAreaPresentation mExtensionWindowAreaPresentation; private ExtensionWindowAreaPresentation mExtensionWindowAreaPresentation;
@NonNull
private final DisplayManager mDisplayManager;
/** /**
* Creates the RearDisplayPresentationController * Creates the RearDisplayPresentationController
@@ -71,25 +61,15 @@ class RearDisplayPresentationController implements DeviceStateRequest.Callback {
mContext = context; mContext = context;
mStateConsumer = stateConsumer; mStateConsumer = stateConsumer;
mDisplayManager = context.getSystemService(DisplayManager.class);
} }
@Override public void startSession(@NonNull Display rearDisplay) {
public void onRequestActivated(@NonNull DeviceStateRequest request) {
Display[] rearDisplays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_REAR);
if (rearDisplays.length == 0) {
mStateConsumer.accept(SESSION_STATE_INACTIVE);
Log.e(TAG, "Rear display list should not be empty");
return;
}
mExtensionWindowAreaPresentation = mExtensionWindowAreaPresentation =
new RearDisplayPresentation(mContext, rearDisplays[0], mStateConsumer); new RearDisplayPresentation(mContext, rearDisplay, mStateConsumer);
mStateConsumer.accept(SESSION_STATE_ACTIVE); mStateConsumer.accept(SESSION_STATE_ACTIVE);
} }
@Override public void endSession() {
public void onRequestCanceled(@NonNull DeviceStateRequest request) {
mStateConsumer.accept(SESSION_STATE_INACTIVE); mStateConsumer.accept(SESSION_STATE_INACTIVE);
} }

View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2023 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 androidx.window.extensions.area;
import android.content.Context;
import android.hardware.devicestate.DeviceStateRequest;
import android.hardware.display.DisplayManager;
import android.view.Display;
import androidx.annotation.NonNull;
/**
* Callback class to be notified of updates to a {@link DeviceStateRequest} for the rear display
* presentation state. This class notifies the {@link RearDisplayPresentationController} when the
* device is ready to enable the rear display presentation feature.
*/
public class RearDisplayPresentationRequestCallback implements DeviceStateRequest.Callback {
private static final String TAG = RearDisplayPresentationRequestCallback.class.getSimpleName();
@NonNull
private final DisplayManager mDisplayManager;
@NonNull
private final DisplayManager.DisplayListener mRearDisplayListener = new RearDisplayListener();
@NonNull
private final RearDisplayPresentationController mRearDisplayPresentationController;
private boolean mWaitingForRearDisplay = false;
public RearDisplayPresentationRequestCallback(@NonNull Context context,
@NonNull RearDisplayPresentationController rearDisplayPresentationController) {
mDisplayManager = context.getSystemService(DisplayManager.class);
mDisplayManager.registerDisplayListener(mRearDisplayListener,
context.getMainThreadHandler(), DisplayManager.EVENT_FLAG_DISPLAY_ADDED
| DisplayManager.EVENT_FLAG_DISPLAY_CHANGED);
mRearDisplayPresentationController = rearDisplayPresentationController;
}
@Override
public void onRequestActivated(@NonNull DeviceStateRequest request) {
Display[] rearDisplays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_REAR);
if (rearDisplays.length == 0) {
// No rear facing display found, marking waiting for display flag as true.
mWaitingForRearDisplay = true;
return;
}
mDisplayManager.unregisterDisplayListener(mRearDisplayListener);
mRearDisplayPresentationController.startSession(rearDisplays[0]);
}
@Override
public void onRequestCanceled(@NonNull DeviceStateRequest request) {
mDisplayManager.unregisterDisplayListener(mRearDisplayListener);
mRearDisplayPresentationController.endSession();
}
/**
* {@link DisplayManager.DisplayListener} to be used if a rear facing {@link Display} isn't
* available synchronously when the device is entered into the rear display presentation state.
* A rear facing {@link Display} is a {@link Display} that is categorized as
* {@link DisplayManager#DISPLAY_CATEGORY_REAR}. This can occur if {@link DisplayManager} is
* still in the process of configuring itself for this state when
* {@link DeviceStateRequest.Callback#onRequestActivated} is called.
*
* The {@link DisplayManager.DisplayListener} removes itself when a rear facing display is
* found.
*/
private class RearDisplayListener implements DisplayManager.DisplayListener {
@Override
public void onDisplayAdded(int displayId) {
Display display = mDisplayManager.getDisplay(displayId);
if (mWaitingForRearDisplay && (display.getFlags() & Display.FLAG_REAR) != 0) {
startRearDisplayPresentation(display);
}
}
@Override
public void onDisplayRemoved(int displayId) {}
@Override
public void onDisplayChanged(int displayId) {
Display display = mDisplayManager.getDisplay(displayId);
if (mWaitingForRearDisplay && (display.getFlags() & Display.FLAG_REAR) != 0) {
startRearDisplayPresentation(display);
}
}
/**
* Starts a new {@link RearDisplayPresentation} with the updated {@link Display} with a
* category of {@link DisplayManager#DISPLAY_CATEGORY_REAR}.
*/
private void startRearDisplayPresentation(Display rearDisplay) {
// We have been notified of a change to a rear display, we can unregister the
// callback and stop waiting for a display
mDisplayManager.unregisterDisplayListener(this);
mWaitingForRearDisplay = false;
mRearDisplayPresentationController.startSession(rearDisplay);
}
}
}

View File

@@ -337,13 +337,15 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
consumer.accept(stateStatus); consumer.accept(stateStatus);
} }
}); });
RearDisplayPresentationRequestCallback deviceStateCallback =
new RearDisplayPresentationRequestCallback(activity,
mRearDisplayPresentationController);
DeviceStateRequest concurrentDisplayStateRequest = DeviceStateRequest.newBuilder( DeviceStateRequest concurrentDisplayStateRequest = DeviceStateRequest.newBuilder(
mConcurrentDisplayState).build(); mConcurrentDisplayState).build();
mDeviceStateManager.requestState( mDeviceStateManager.requestState(
concurrentDisplayStateRequest, concurrentDisplayStateRequest,
mExecutor, mExecutor,
mRearDisplayPresentationController deviceStateCallback
); );
} }
} }