blob: 3765916a6497ca43c39d241e96d0db6a783ed1b9 [file] [log] [blame]
/*
* 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 android.server.wm.scvh;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Size;
import android.view.Gravity;
import android.view.SurfaceControlViewHost.SurfacePackage;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.cts.surfacevalidator.ISurfaceValidatorTestCase;
import android.view.cts.surfacevalidator.PixelChecker;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.window.SurfaceSyncGroup;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class SyncValidatorSCVHTestCase implements ISurfaceValidatorTestCase {
private static final String TAG = "SCVHSyncValidatorTestCase";
private static final int HW_TIMEOUT_MULTIPLIER =
SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
private final Size[] mSizes = new Size[]{new Size(500, 500), new Size(700, 400),
new Size(300, 800), new Size(200, 200)};
private int mLastSizeIndex = 0;
private final long mDelayMs;
private final boolean mOverrideDefaultDuration;
private SurfaceControlViewHostHelper mSurfaceControlViewHostHelper;
private IAttachEmbeddedWindow mIAttachEmbeddedWindow;
private Handler mHandler;
private TextView mTextView;
private SurfaceView mSurfaceView;
private SurfacePackage mSurfacePackage;
private final CountDownLatch mReadyToStart = new CountDownLatch(1);
public SyncValidatorSCVHTestCase(long delayMs, boolean overrideDefaultDuration) {
mDelayMs = delayMs;
mOverrideDefaultDuration = overrideDefaultDuration;
}
private final Runnable mResizeWithSurfaceSyncGroup = new Runnable() {
@Override
public void run() {
Size size = mSizes[mLastSizeIndex % mSizes.length];
Runnable svResizeRunnable = () -> {
ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
svParams.width = size.getWidth();
svParams.height = size.getHeight();
mSurfaceView.setLayoutParams(svParams);
mTextView.setText(size.getWidth() + "x" + size.getHeight());
};
Runnable embeddedResizeRunnable = () -> {
try {
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
size.getWidth(), size.getHeight(),
WindowManager.LayoutParams.TYPE_APPLICATION, 0,
PixelFormat.TRANSPARENT);
mIAttachEmbeddedWindow.relayout(lp);
} catch (RemoteException e) {
Log.e(TAG, "Failed to call relayout for embedded window");
}
};
SurfaceSyncGroup syncGroup = new SurfaceSyncGroup(TAG);
syncGroup.add(mSurfaceView.getRootSurfaceControl(), svResizeRunnable);
syncGroup.add(mSurfacePackage, embeddedResizeRunnable);
syncGroup.markSyncReady();
mLastSizeIndex++;
mHandler.postDelayed(this, mDelayMs + 50);
}
};
@Override
public PixelChecker getChecker() {
return new PixelChecker(Color.BLACK) {
@Override
public boolean checkPixels(int matchingPixelCount, int width, int height) {
// Content has been set up yet.
if (mSurfacePackage == null) {
return true;
}
return matchingPixelCount == 0;
}
};
}
@Override
public void start(Context context, FrameLayout parent) {
mHandler = new Handler(Looper.getMainLooper());
mSurfaceControlViewHostHelper = new SurfaceControlViewHostHelper(TAG, mReadyToStart,
context, mDelayMs, mSizes[0]);
mSurfaceControlViewHostHelper.bindEmbeddedService();
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(mSizes[0].getWidth(),
mSizes[0].getHeight());
layoutParams.gravity = Gravity.CENTER;
mSurfaceView = mSurfaceControlViewHostHelper.attachSurfaceView(parent, layoutParams);
mTextView = new TextView(context);
mTextView.setTextColor(Color.GREEN);
mTextView.setText(mSizes[0].getWidth() + "x" + mSizes[0].getHeight());
FrameLayout.LayoutParams txtParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
txtParams.gravity = Gravity.TOP | Gravity.LEFT;
parent.addView(mTextView, txtParams);
}
@Override
public void waitForReady() {
boolean ready = false;
try {
ready = mReadyToStart.await(3 * HW_TIMEOUT_MULTIPLIER, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Log.e(TAG, "Failed to wait for SCVH to attach");
}
assertTrue("Failed to attach SCVH", ready);
mSurfacePackage = mSurfaceControlViewHostHelper.getSurfacePackage();
mIAttachEmbeddedWindow = mSurfaceControlViewHostHelper.getAttachedEmbeddedWindow();
mHandler.post(mResizeWithSurfaceSyncGroup);
}
@Override
public void end() {
mHandler.removeCallbacks(mResizeWithSurfaceSyncGroup);
}
@Override
public boolean hasAnimation() {
return !mOverrideDefaultDuration;
}
}