blob: 42b2acace8c9fdf15439919e4f6679505b60af35 [file] [log] [blame]
/*
* 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 com.android.server.wm.flicker;
import static com.android.server.wm.flicker.TestFileUtils.readTestFile;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.support.test.InstrumentationRegistry;
import android.view.WindowManager;
import org.junit.Test;
import java.util.List;
import java.util.stream.Collectors;
/**
* Contains {@link LayersTrace} tests.
* To run this test: {@code atest FlickerLibTest:LayersTraceTest}
*/
public class LayersTraceTest {
private static LayersTrace readLayerTraceFromFile(String relativePath) {
try {
return LayersTrace.parseFrom(readTestFile(relativePath));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static Rect getDisplayBounds() {
Point display = new Point();
WindowManager wm =
(WindowManager) InstrumentationRegistry.getContext().getSystemService(
Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getRealSize(display);
return new Rect(0, 0, display.x, display.y);
}
@Test
public void canParseAllLayers() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
assertThat(trace.getEntries()).isNotEmpty();
assertThat(trace.getEntries().get(0).getTimestamp()).isEqualTo(2307984557311L);
assertThat(trace.getEntries().get(trace.getEntries().size() - 1).getTimestamp())
.isEqualTo(2308521813510L);
List<LayersTrace.Layer> flattenedLayers = trace.getEntries().get(0).asFlattenedLayers();
String msg = "Layers:\n" + flattenedLayers.stream().map(layer -> layer.mProto.name)
.collect(Collectors.joining("\n\t"));
assertWithMessage(msg).that(flattenedLayers).hasSize(47);
}
@Test
public void canParseVisibleLayers() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
assertThat(trace.getEntries()).isNotEmpty();
assertThat(trace.getEntries().get(0).getTimestamp()).isEqualTo(2307984557311L);
assertThat(trace.getEntries().get(trace.getEntries().size() - 1).getTimestamp())
.isEqualTo(2308521813510L);
List<LayersTrace.Layer> flattenedLayers = trace.getEntries().get(0).asFlattenedLayers();
List<LayersTrace.Layer> visibleLayers = flattenedLayers.stream()
.filter(layer -> layer.isVisible() && !layer.isHiddenByParent())
.collect(Collectors.toList());
String msg = "Visible Layers:\n" + visibleLayers.stream()
.map(layer -> layer.mProto.name)
.collect(Collectors.joining("\n\t"));
assertWithMessage(msg).that(visibleLayers).hasSize(9);
}
@Test
public void canParseLayerHierarchy() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
assertThat(trace.getEntries()).isNotEmpty();
assertThat(trace.getEntries().get(0).getTimestamp()).isEqualTo(2307984557311L);
assertThat(trace.getEntries().get(trace.getEntries().size() - 1).getTimestamp())
.isEqualTo(2308521813510L);
List<LayersTrace.Layer> layers = trace.getEntries().get(0).getRootLayers();
assertThat(layers).hasSize(2);
assertThat(layers.get(0).mChildren).hasSize(layers.get(0).mProto.children.length);
assertThat(layers.get(1).mChildren).hasSize(layers.get(1).mProto.children.length);
}
// b/76099859
@Test
public void canDetectOrphanLayers() {
try {
readLayerTraceFromFile(
"layers_trace_orphanlayers.pb");
fail("Failed to detect orphaned layers.");
} catch (RuntimeException exception) {
assertThat(exception.getMessage()).contains(
"Failed to parse layers trace. Found orphan layers "
+ "with parent layer id:1006 : 49");
}
}
// b/75276931
@Test
public void canDetectUncoveredRegion() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
LayersTrace.Entry entry = trace.getEntry(2308008331271L);
Assertions.Result result = entry.coversRegion(getDisplayBounds());
assertThat(result.failed()).isTrue();
assertThat(result.reason).contains("Region to test: Rect(0, 0 - 1440, 2880)");
assertThat(result.reason).contains("first empty point: 0, 99");
assertThat(result.reason).contains("visible regions:");
assertWithMessage("Reason contains list of visible regions")
.that(result.reason).contains("StatusBar#0Rect(0, 0 - 1440, 98");
}
// Visible region tests
@Test
public void canTestLayerVisibleRegion_layerDoesNotExist() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
LayersTrace.Entry entry = trace.getEntry(2308008331271L);
final Rect expectedVisibleRegion = new Rect(0, 0, 1, 1);
Assertions.Result result = entry.hasVisibleRegion("ImaginaryLayer",
expectedVisibleRegion);
assertThat(result.failed()).isTrue();
assertThat(result.reason).contains("Could not find ImaginaryLayer");
}
@Test
public void canTestLayerVisibleRegion_layerDoesNotHaveExpectedVisibleRegion() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
LayersTrace.Entry entry = trace.getEntry(2307993020072L);
final Rect expectedVisibleRegion = new Rect(0, 0, 1, 1);
Assertions.Result result = entry.hasVisibleRegion("NexusLauncherActivity#2",
expectedVisibleRegion);
assertThat(result.failed()).isTrue();
assertThat(result.reason).contains(
"Layer com.google.android.apps.nexuslauncher/com.google.android.apps"
+ ".nexuslauncher.NexusLauncherActivity#2 is invisible: activeBuffer=null"
+ " type != ColorLayer flags=1 (FLAG_HIDDEN set) visible region is empty");
}
@Test
public void canTestLayerVisibleRegion_layerIsHiddenByParent() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
LayersTrace.Entry entry = trace.getEntry(2308455948035L);
final Rect expectedVisibleRegion = new Rect(0, 0, 1, 1);
Assertions.Result result = entry.hasVisibleRegion(
"SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main",
expectedVisibleRegion);
assertThat(result.failed()).isTrue();
assertThat(result.reason).contains(
"Layer SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0 is "
+ "hidden by parent: com.android.chrome/com.google.android.apps.chrome"
+ ".Main#0");
}
@Test
public void canTestLayerVisibleRegion_incorrectRegionSize() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
LayersTrace.Entry entry = trace.getEntry(2308008331271L);
final Rect expectedVisibleRegion = new Rect(0, 0, 1440, 99);
Assertions.Result result = entry.hasVisibleRegion(
"StatusBar",
expectedVisibleRegion);
assertThat(result.failed()).isTrue();
assertThat(result.reason).contains("StatusBar#0 has visible "
+ "region:Rect(0, 0 - 1440, 98) expected:Rect(0, 0 - 1440, 99)");
}
@Test
public void canTestLayerVisibleRegion() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_emptyregion.pb");
LayersTrace.Entry entry = trace.getEntry(2308008331271L);
final Rect expectedVisibleRegion = new Rect(0, 0, 1440, 98);
Assertions.Result result = entry.hasVisibleRegion("StatusBar", expectedVisibleRegion);
assertThat(result.passed()).isTrue();
}
@Test
public void canTestLayerVisibleRegion_layerIsNotVisible() {
LayersTrace trace = readLayerTraceFromFile(
"layers_trace_invalid_layer_visibility.pb");
LayersTrace.Entry entry = trace.getEntry(252794268378458L);
Assertions.Result result = entry.isVisible("com.android.server.wm.flicker.testapp");
assertThat(result.failed()).isTrue();
assertThat(result.reason).contains(
"Layer com.android.server.wm.flicker.testapp/com.android.server.wm.flicker"
+ ".testapp.SimpleActivity#0 is invisible: type != ColorLayer visible "
+ "region is empty");
}
}