Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Unified Diff: chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerTest.java

Issue 2742133002: Revert of Improve transition between opaque and translucent compositor views. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/android/java_sources.gni ('k') | content/browser/renderer_host/compositor_impl_android.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerTest.java
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerTest.java
deleted file mode 100644
index 4ed9c7cbde5251c82acd5d8f46f651910898db02..0000000000000000000000000000000000000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/CompositorSurfaceManagerTest.java
+++ /dev/null
@@ -1,440 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.compositor;
-
-import android.app.Activity;
-import android.graphics.PixelFormat;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.widget.FrameLayout;
-
-import static org.hamcrest.Matchers.lessThan;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.Shadows;
-import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.shadows.ShadowLooper;
-import org.robolectric.shadows.ShadowSurfaceView;
-
-import org.chromium.base.test.util.Feature;
-import org.chromium.testing.local.LocalRobolectricTestRunner;
-
-import java.util.Set;
-
-/**
- * Unit tests for the CompositorSurfaceManager.
- */
-@RunWith(LocalRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class CompositorSurfaceManagerTest {
- @Mock
- private SurfaceHolder.Callback mCallback;
-
- private CompositorSurfaceManager mManager;
-
- private FrameLayout mLayout;
-
- /**
- * Implementation of a SurfaceView shadow that provides additional functionality for controlling
- * the state of the underlying (fake) Surface.
- */
- @Implements(SurfaceView.class)
- public static class MyShadowSurfaceView extends ShadowSurfaceView {
- private final MyFakeSurfaceHolder mHolder = new MyFakeSurfaceHolder();
-
- /**
- * Robolectric's FakeSurfaceHolder doesn't keep track of the format, etc.
- */
- public static class MyFakeSurfaceHolder extends ShadowSurfaceView.FakeSurfaceHolder {
- /**
- * Fake surface that lets us control whether it's valid or not.
- */
- public static class MyFakeSurface extends Surface {
- public boolean valid = false;
-
- @Override
- public boolean isValid() {
- return valid;
- }
- }
-
- private int mFormat = PixelFormat.UNKNOWN;
- private final MyFakeSurface mSurface = new MyFakeSurface();
-
- @Implementation
- public void setFormat(int format) {
- mFormat = format;
- }
-
- public int getFormat() {
- return mFormat;
- }
-
- // Return a surface that we can control if it's valid or not.
- @Override
- public Surface getSurface() {
- return getFakeSurface();
- }
-
- public MyFakeSurface getFakeSurface() {
- return mSurface;
- }
- }
-
- public MyShadowSurfaceView() {}
-
- @Implementation
- public SurfaceHolder getHolder() {
- return getMyFakeSurfaceHolder();
- }
-
- @Override
- public FakeSurfaceHolder getFakeSurfaceHolder() {
- return getMyFakeSurfaceHolder();
- }
-
- public MyFakeSurfaceHolder getMyFakeSurfaceHolder() {
- return mHolder;
- }
- }
-
- @Before
- public void beforeTest() {
- MockitoAnnotations.initMocks(this);
- Activity activity = Robolectric.buildActivity(Activity.class).setup().get();
- mLayout = new FrameLayout(activity);
- mManager = new CompositorSurfaceManager(mLayout, mCallback);
- }
-
- private void runDelayedTasks() {
- ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
- }
-
- /**
- * Return the callback for |view|, or null. Will get mad if there's more than one.
- */
- private SurfaceHolder.Callback callbackFor(SurfaceView view) {
- MyShadowSurfaceView viewShadow = (MyShadowSurfaceView) Shadows.shadowOf(view);
- ShadowSurfaceView.FakeSurfaceHolder viewHolder = viewShadow.getFakeSurfaceHolder();
- Set<SurfaceHolder.Callback> callbacks = viewHolder.getCallbacks();
- // Zero or one is okay.
- assertThat(callbacks.size(), lessThan(2));
-
- if (callbacks.size() == 1) return callbacks.iterator().next();
-
- return null;
- }
-
- private MyShadowSurfaceView.MyFakeSurfaceHolder fakeHolderFor(SurfaceView view) {
- MyShadowSurfaceView viewShadow = (MyShadowSurfaceView) Shadows.shadowOf(view);
- return viewShadow.getMyFakeSurfaceHolder();
- }
-
- private void setSurfaceValid(SurfaceView view, boolean valid) {
- fakeHolderFor(view).getFakeSurface().valid = valid;
- }
-
- /**
- * Find and return the SurfaceView with format |format|.
- */
- private SurfaceView findSurface(int format) {
- final int childCount = mLayout.getChildCount();
- for (int i = 0; i < childCount; i++) {
- final SurfaceView child = (SurfaceView) mLayout.getChildAt(i);
- if (fakeHolderFor(child).getFormat() == format) return child;
- }
-
- return null;
- }
-
- /**
- * Request the pixel format |format|, and return the SurfaceView for it if it's attached. You
- * are responsible for sending surfaceCreated / Changed to |mManager| if you want it to think
- * that Android has provided the Surface.
- */
- private SurfaceView requestSurface(int format) {
- mManager.requestSurface(format);
- runDelayedTasks();
-
- return findSurface(format);
- }
-
- /**
- * Request format |format|, and send created / changed callbacks to |mManager| as if Android
- * had provided the underlying Surface.
- */
- private SurfaceView requestThenCreateSurface(int format) {
- SurfaceView view = requestSurface(format);
- setSurfaceValid(view, true);
- callbackFor(view).surfaceCreated(view.getHolder());
- final int actualFormat =
- (format == PixelFormat.OPAQUE) ? PixelFormat.RGB_565 : PixelFormat.RGBA_8888;
- final int width = 320;
- final int height = 240;
- callbackFor(view).surfaceChanged(view.getHolder(), actualFormat, width, height);
-
- return view;
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testRequestOpaqueSurface() {
- // Request a SurfaceView, and test in detail that it worked.
- SurfaceView opaque = requestSurface(PixelFormat.OPAQUE);
- verify(mCallback, times(0)).surfaceCreated(ArgumentMatchers.<SurfaceHolder>any());
- verify(mCallback, times(0))
- .surfaceChanged(
- ArgumentMatchers.<SurfaceHolder>any(), anyInt(), anyInt(), anyInt());
- verify(mCallback, times(0)).surfaceDestroyed(ArgumentMatchers.<SurfaceHolder>any());
-
- // Check that there's an opaque SurfaceView .
- assertEquals(1, mLayout.getChildCount());
- assertTrue(fakeHolderFor(opaque).getFormat() == PixelFormat.OPAQUE);
-
- // Verify that we are notified when the surface is created.
- callbackFor(opaque).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(0)).surfaceDestroyed(ArgumentMatchers.<SurfaceHolder>any());
-
- // Verify that we are notified when the surface is changed.
- final int format = PixelFormat.RGB_565;
- final int width = 320;
- final int height = 240;
- callbackFor(opaque).surfaceChanged(opaque.getHolder(), format, width, height);
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceChanged(opaque.getHolder(), format, width, height);
- verify(mCallback, times(0)).surfaceDestroyed(ArgumentMatchers.<SurfaceHolder>any());
-
- // Verify that we are notified when the surface is destroyed.
- callbackFor(opaque).surfaceDestroyed(opaque.getHolder());
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceChanged(opaque.getHolder(), format, width, height);
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testRequestOpaqueThenTranslucentSurface() {
- // Request opaque then translucent.
- SurfaceView opaque = requestThenCreateSurface(PixelFormat.OPAQUE);
- SurfaceView translucent = requestThenCreateSurface(PixelFormat.TRANSLUCENT);
-
- // Verify that we received a destroy for |opaque| and created / changed for |translucent|.
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- verify(mCallback, times(1)).surfaceCreated(translucent.getHolder());
- verify(mCallback, times(1))
- .surfaceChanged(eq(translucent.getHolder()), anyInt(), anyInt(), anyInt());
-
- // Both views should be present.
- assertEquals(2, mLayout.getChildCount());
-
- // Only the translucent surface should be left. Note that the old view is still valid.
- mManager.doneWithUnownedSurface();
- runDelayedTasks();
- assertEquals(1, mLayout.getChildCount());
- assertNotNull(findSurface(PixelFormat.TRANSLUCENT));
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testRequestSameSurface() {
- // Request an opaque surface, get it, then request it again. Verify that we get synthetic
- // create / destroy callbacks.
- SurfaceView opaque = requestThenCreateSurface(PixelFormat.OPAQUE);
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
- verify(mCallback, times(0)).surfaceDestroyed(opaque.getHolder());
-
- // Surface is curerntly valid. Request again. We should get back a destroy and create.
- assertEquals(opaque, requestSurface(PixelFormat.OPAQUE));
- verify(mCallback, times(2)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(2))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- assertEquals(1, mLayout.getChildCount());
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testRequestSameSurfaceBeforeReady() {
- // Request an opaque surface, then request it again before the first one shows up.
- SurfaceView opaque = requestSurface(PixelFormat.OPAQUE);
- verify(mCallback, times(0)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(0))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
- verify(mCallback, times(0)).surfaceDestroyed(opaque.getHolder());
-
- // Request again. We shouldn't get any callbacks, since the surface is still pending.
- assertEquals(opaque, requestSurface(PixelFormat.OPAQUE));
- verify(mCallback, times(0)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(0))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
- verify(mCallback, times(0)).surfaceDestroyed(opaque.getHolder());
-
- // Only the opaque view should be attached.
- assertEquals(1, mLayout.getChildCount());
-
- // When the surface is created, we should get notified created / changed, but not destroyed.
- callbackFor(opaque).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
-
- callbackFor(opaque).surfaceChanged(opaque.getHolder(), PixelFormat.RGB_565, 320, 240);
- verify(mCallback, times(1))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
- verify(mCallback, times(0)).surfaceDestroyed(opaque.getHolder());
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testRequestDifferentSurfacesBeforeReady() {
- // Request an opaque surface, then request the translucent one before the it one shows up.
- SurfaceView opaque = requestSurface(PixelFormat.OPAQUE);
- verify(mCallback, times(0)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(0))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
- verify(mCallback, times(0)).surfaceDestroyed(opaque.getHolder());
-
- // Request translucent. We should get no callbacks, but both views should be attached.
- SurfaceView translucent = requestSurface(PixelFormat.TRANSLUCENT);
- verify(mCallback, times(0)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(0)).surfaceCreated(translucent.getHolder());
- assertEquals(2, mLayout.getChildCount());
-
- // If the opaque surface arrives, we shouldn't hear about it. It should be detached, since
- // we've requested the other one.
- callbackFor(opaque).surfaceCreated(opaque.getHolder());
- runDelayedTasks();
- assertEquals(1, mLayout.getChildCount());
- verify(mCallback, times(0)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(0)).surfaceCreated(translucent.getHolder());
- verify(mCallback, times(0)).surfaceDestroyed(opaque.getHolder());
-
- // When we create the translucent surface, we should be notified.
- callbackFor(translucent).surfaceCreated(translucent.getHolder());
- verify(mCallback, times(0)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceCreated(translucent.getHolder());
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testPendingSurfaceChangedCallback() {
- // Request an opaque surface, and request it again between 'created' and 'changed'. We
- // should get a synthetic 'created', but a real 'changed' callback.
- SurfaceView opaque = requestSurface(PixelFormat.OPAQUE);
- callbackFor(opaque).surfaceCreated(opaque.getHolder());
- runDelayedTasks();
-
- // Sanity check.
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(0))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
-
- // Re-request while 'changed' is still pending. We should get a synthetic 'destroyed' and
- // synthetic 'created'.
- assertEquals(opaque, requestSurface(PixelFormat.OPAQUE));
- verify(mCallback, times(2)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- verify(mCallback, times(0))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
-
- // Send 'changed', and expect that we'll receive it.
- callbackFor(opaque).surfaceChanged(opaque.getHolder(), PixelFormat.RGB_565, 320, 240);
- verify(mCallback, times(1))
- .surfaceChanged(eq(opaque.getHolder()), anyInt(), anyInt(), anyInt());
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testJellyBeanWorkaround() {
- // See if recreateSurfaceForJellyBean destroys / re-creates the surface.
- // should get a synthetic 'created', but a real 'changed' callback.
- SurfaceView opaque = requestThenCreateSurface(PixelFormat.OPAQUE);
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- assertEquals(1, mLayout.getChildCount());
-
- // We should be notified that the surface was destroyed via synthetic callback, and the
- // surface should be detached.
- mManager.recreateSurfaceForJellyBean();
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- assertEquals(0, mLayout.getChildCount());
-
- // When the surface really is destroyed, it should be re-attached. We should not be
- // notified again, though.
- callbackFor(opaque).surfaceDestroyed(opaque.getHolder());
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- assertEquals(1, mLayout.getChildCount());
-
- // When the surface is re-created, we should be notified.
- callbackFor(opaque).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(2)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- assertEquals(1, mLayout.getChildCount());
- }
-
- @Test
- @Feature("Compositor")
- @Config(shadows = {MyShadowSurfaceView.class})
- public void testRequestSurfaceDuringDestruction() {
- // If we re-request a surface while we're tearing it down, it should be re-attached and
- // given back to us once the destruction completes.
- SurfaceView opaque = requestThenCreateSurface(PixelFormat.OPAQUE);
- SurfaceView translucent = requestThenCreateSurface(PixelFormat.TRANSLUCENT);
- mManager.doneWithUnownedSurface();
-
- // The transparent surface should be attached, and the opaque one detached.
- assertEquals(1, mLayout.getChildCount());
- assertNotNull(findSurface(PixelFormat.TRANSLUCENT));
-
- // Re-request the opaque surface. Nothing should happen until it's destroyed. It should
- // not be re-attached, since that is also deferred until destruction.
- assertEquals(null, requestSurface(PixelFormat.OPAQUE));
- assertEquals(1, mLayout.getChildCount());
- assertNotNull(findSurface(PixelFormat.TRANSLUCENT));
-
- // When the opaque surface is destroyed, then it should be re-attached. No callbacks shoud
- // have arrived yet, except for initial creation and (synthetic) destroyed when we got the
- // translucent surface.
- callbackFor(opaque).surfaceDestroyed(opaque.getHolder());
- assertEquals(2, mLayout.getChildCount());
- verify(mCallback, times(1)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- verify(mCallback, times(0)).surfaceDestroyed(translucent.getHolder());
-
- // When the opaque surface becomes available, we'll get the synthetic destroy for the
- // translucent one that we lost ownership of, and the real create for the opaque one.
- callbackFor(opaque).surfaceCreated(opaque.getHolder());
- assertEquals(2, mLayout.getChildCount());
- verify(mCallback, times(2)).surfaceCreated(opaque.getHolder());
- verify(mCallback, times(1)).surfaceDestroyed(opaque.getHolder());
- verify(mCallback, times(1)).surfaceDestroyed(translucent.getHolder());
- }
-}
« no previous file with comments | « chrome/android/java_sources.gni ('k') | content/browser/renderer_host/compositor_impl_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698