Simplify Window/Surface trace by using one QS Tile

- Trigger both traces using a new Winscope Trace Tile

Bug: 73496681
Test: make RunSettingsRoboTests ROBOTEST_FILTER=WinscopeTraceTest
Test: flash and manually click on new tile
Change-Id: I3e05f625a983c382e58cc797d293a695223c630a
This commit is contained in:
Vishnu Nair
2018-02-22 07:14:36 -08:00
parent 44935e8602
commit 74100b3ac7
8 changed files with 250 additions and 336 deletions

View File

@@ -3213,19 +3213,9 @@
</intent-filter>
</service>
<service
android:name=".development.qstile.DevelopmentTiles$WindowTrace"
android:label="@string/window_trace_quick_settings_title"
android:icon="@drawable/tile_icon_window_trace"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:enabled="false">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<service
android:name=".development.qstile.DevelopmentTiles$LayerTrace"
android:label="@string/layer_trace_quick_settings_title"
android:icon="@drawable/tile_icon_layer_trace"
android:name=".development.qstile.DevelopmentTiles$WinscopeTrace"
android:label="@string/winscope_trace_quick_settings_title"
android:icon="@drawable/tile_icon_winscope_trace"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:enabled="false">
<intent-filter>

View File

@@ -1,29 +0,0 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
<path
android:pathData="M11.709,11.712 L7.061,8.098 6.039,8.893l5.676,4.415 5.676,-4.415 -1.028,-0.801zM11.716,10.11 L16.357,6.496 17.392,5.695 11.716,1.281 6.039,5.695 7.067,6.496Z"
android:fillColor="#FFFFFFFF"/>
<path
android:pathData="m20.27,15.235c0,0.82 -0.671,1.491 -1.491,1.491 -0.134,0 -0.261,-0.015 -0.38,-0.052l-2.654,2.646C15.782,19.439 15.797,19.573 15.797,19.708c0,0.82 -0.671,1.491 -1.491,1.491 -0.82,0 -1.491,-0.671 -1.491,-1.491 0,-0.134 0.015,-0.268 0.052,-0.388L10.966,17.419C10.847,17.456 10.713,17.471 10.579,17.471 10.444,17.471 10.31,17.456 10.191,17.419L6.799,20.818C6.836,20.938 6.851,21.064 6.851,21.199 6.851,22.019 6.18,22.689 5.36,22.689 4.54,22.689 3.869,22.019 3.869,21.199c0,-0.82 0.671,-1.491 1.491,-1.491 0.134,0 0.261,0.015 0.38,0.052L9.14,16.368C9.103,16.249 9.088,16.114 9.088,15.98 9.088,15.16 9.759,14.489 10.579,14.489c0.82,0 1.491,0.671 1.491,1.491 0,0.134 -0.015,0.268 -0.052,0.388l1.901,1.901C14.038,18.232 14.172,18.217 14.306,18.217c0.134,0 0.268,0.015 0.388,0.052L17.34,15.615C17.303,15.496 17.288,15.369 17.288,15.235c0,-0.82 0.671,-1.491 1.491,-1.491 0.82,0 1.491,0.671 1.491,1.491z"
android:fillColor="#FFFFFFFF"/>
</vector>

View File

@@ -8886,11 +8886,8 @@
<!-- [CHAR LIMIT=60] Name of dev option to enable extra quick settings tiles -->
<string name="quick_settings_developer_tiles">Quick settings developer tiles</string>
<!-- [CHAR LIMIT=25] Title of developer tile to toggle window trace -->
<string name="window_trace_quick_settings_title">Window Trace</string>
<!-- [CHAR LIMIT=25] Title of developer tile to toggle layer trace -->
<string name="layer_trace_quick_settings_title">Surface Trace</string>
<!-- [CHAR LIMIT=25] Title of developer tile to toggle winscope trace -->
<string name="winscope_trace_quick_settings_title">Winscope Trace</string>
<!-- Template for formatting country and language. eg Canada - French [CHAR LIMIT=NONE]-->
<string name="support_country_format"><xliff:g id="country" example="Canada">%1$s</xliff:g> - <xliff:g id="language" example="French">%2$s</xliff:g></string>

View File

@@ -142,26 +142,29 @@ public abstract class DevelopmentTiles extends TileService {
}
/**
* Tile to toggle Window Trace.
* Tile to toggle Winscope trace which consists of Window and Layer traces.
*/
public static class WindowTrace extends DevelopmentTiles {
public static class WinscopeTrace extends DevelopmentTiles {
@VisibleForTesting
IWindowManagerWrapper mWindowManager;
static final int SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE = 1025;
@VisibleForTesting
Toast mToast;
static final int SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE = 1026;
private IBinder mSurfaceFlinger;
private IWindowManagerWrapper mWindowManager;
private Toast mToast;
@Override
public void onCreate() {
super.onCreate();
mWindowManager = new IWindowManagerWrapper(WindowManagerGlobal
.getWindowManagerService());
mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
Context context = getApplicationContext();
CharSequence text = "Trace written to /data/misc/wmtrace/wm_trace.pb";
CharSequence text = "Trace files written to /data/misc/wmtrace";
mToast = Toast.makeText(context, text, Toast.LENGTH_LONG);
}
@Override
protected boolean isEnabled() {
private boolean isWindowTraceEnabled() {
try {
return mWindowManager.isWindowTraceEnabled();
} catch (RemoteException e) {
@@ -171,46 +174,8 @@ public abstract class DevelopmentTiles extends TileService {
return false;
}
@Override
protected void setIsEnabled(boolean isEnabled) {
try {
if (isEnabled) {
mWindowManager.startWindowTrace();
} else {
mWindowManager.stopWindowTrace();
mToast.show();
}
} catch (RemoteException e) {
Log.e(TAG, "Could not set window trace status." + e.toString());
}
}
}
/**
* Tile to toggle Layer Trace.
*/
public static class LayerTrace extends DevelopmentTiles {
@VisibleForTesting
static final int SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE = 1025;
@VisibleForTesting
static final int SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE = 1026;
@VisibleForTesting
IBinder mSurfaceFlinger;
@VisibleForTesting
Toast mToast;
@Override
public void onCreate() {
super.onCreate();
mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
Context context = getApplicationContext();
CharSequence text = "Trace written to /data/misc/wmtrace/layers_trace.pb";
mToast = Toast.makeText(context, text, Toast.LENGTH_LONG);
}
@Override
protected boolean isEnabled() {
boolean surfaceTraceEnabled = false;
private boolean isLayerTraceEnabled() {
boolean layerTraceEnabled = false;
Parcel reply = null;
Parcel data = null;
try {
@@ -220,7 +185,7 @@ public abstract class DevelopmentTiles extends TileService {
data.writeInterfaceToken("android.ui.ISurfaceComposer");
mSurfaceFlinger.transact(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE,
data, reply, 0 /* flags */);
surfaceTraceEnabled = reply.readBoolean();
layerTraceEnabled = reply.readBoolean();
}
} catch (RemoteException e) {
Log.e(TAG, "Could not get layer trace status, defaulting to false." + e.toString());
@@ -230,11 +195,27 @@ public abstract class DevelopmentTiles extends TileService {
reply.recycle();
}
}
return surfaceTraceEnabled;
return layerTraceEnabled;
}
@Override
protected void setIsEnabled(boolean isEnabled) {
protected boolean isEnabled() {
return isWindowTraceEnabled() || isLayerTraceEnabled();
}
private void setWindowTraceEnabled(boolean isEnabled) {
try {
if (isEnabled) {
mWindowManager.startWindowTrace();
} else {
mWindowManager.stopWindowTrace();
}
} catch (RemoteException e) {
Log.e(TAG, "Could not set window trace status." + e.toString());
}
}
private void setLayerTraceEnabled(boolean isEnabled) {
Parcel data = null;
try {
if (mSurfaceFlinger != null) {
@@ -243,9 +224,6 @@ public abstract class DevelopmentTiles extends TileService {
data.writeInt(isEnabled ? 1 : 0);
mSurfaceFlinger.transact(SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE,
data, null, 0 /* flags */);
if (!isEnabled){
mToast.show();
}
}
} catch (RemoteException e) {
Log.e(TAG, "Could not set layer tracing." + e.toString());
@@ -255,5 +233,14 @@ public abstract class DevelopmentTiles extends TileService {
}
}
}
@Override
protected void setIsEnabled(boolean isEnabled) {
setWindowTraceEnabled(isEnabled);
setLayerTraceEnabled(isEnabled);
if (!isEnabled) {
mToast.show();
}
}
}
}

View File

@@ -1,128 +0,0 @@
/*
* 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.settings.development.qstile;
import static com.android.settings.development.qstile.DevelopmentTiles.LayerTrace
.SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE;
import static com.android.settings.development.qstile.DevelopmentTiles.LayerTrace
.SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.Toast;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.ShadowParcel;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class LayerTraceTest {
@Mock
private IBinder mSurfaceFlinger;
@Mock
private Toast mToast;
private DevelopmentTiles.LayerTrace mLayerTraceTile;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mLayerTraceTile = spy(new DevelopmentTiles.LayerTrace());
ReflectionHelpers.setField(mLayerTraceTile, "mSurfaceFlinger", mSurfaceFlinger);
ReflectionHelpers.setField(mLayerTraceTile, "mToast", mToast);
}
@After
public void after() {
verifyNoMoreInteractions(mSurfaceFlinger);
verifyNoMoreInteractions(mToast);
}
@Test
@Config(shadows = {ShadowParcel.class})
public void sfReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
ShadowParcel.sReadBoolResult = true;
assertThat(mLayerTraceTile.isEnabled()).isTrue();
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
eq(0 /* flags */));
}
@Test
@Config(shadows = {ShadowParcel.class})
public void sfReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException {
ShadowParcel.sReadBoolResult = false;
assertThat(mLayerTraceTile.isEnabled()).isFalse();
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
eq(0 /* flags */));
}
@Test
public void sfUnavailable_shouldReturnDisabled() throws RemoteException {
ReflectionHelpers.setField(mLayerTraceTile, "mSurfaceFlinger", null);
assertThat(mLayerTraceTile.isEnabled()).isFalse();
}
@Test
@Config(shadows = {ShadowParcel.class})
public void setIsEnableTrue_shouldEnableLayerTrace() throws RemoteException {
mLayerTraceTile.setIsEnabled(true);
assertThat(ShadowParcel.sWriteIntResult).isEqualTo(1);
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE), any(), isNull(),
eq(0 /* flags */));
}
@Test
@Config(shadows = {ShadowParcel.class})
public void setIsEnableFalse_shouldDisableLayerTraceAndShowToast() throws RemoteException {
mLayerTraceTile.setIsEnabled(false);
assertThat(ShadowParcel.sWriteIntResult).isEqualTo(0);
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE), any(), isNull(),
eq(0 /* flags */));
verify(mToast).show();
}
@Test
public void setIsEnableAndSfUnavailable_shouldDoNothing() throws RemoteException {
ReflectionHelpers.setField(mLayerTraceTile, "mSurfaceFlinger", null);
mLayerTraceTile.setIsEnabled(true);
mLayerTraceTile.setIsEnabled(false);
}
}

View File

@@ -1,107 +0,0 @@
/*
* 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.settings.development.qstile;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.os.RemoteException;
import android.widget.Toast;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.ShadowParcel;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.IWindowManagerWrapper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WindowTraceTest {
@Mock
private IWindowManagerWrapper mWindowManager;
@Mock
private Toast mToast;
private DevelopmentTiles.WindowTrace mWindowTrace;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mWindowTrace = spy(new DevelopmentTiles.WindowTrace());
ReflectionHelpers.setField(mWindowTrace, "mWindowManager", mWindowManager);
ReflectionHelpers.setField(mWindowTrace, "mToast", mToast);
}
@After
public void teardown() {
verifyNoMoreInteractions(mToast);
}
@Test
public void wmReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
doReturn(true).when(mWindowManager).isWindowTraceEnabled();
assertThat(mWindowTrace.isEnabled()).isTrue();
}
@Test
public void wmReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException {
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
assertThat(mWindowTrace.isEnabled()).isFalse();
}
@Test
public void wmThrowsRemoteException_shouldReturnDisabled() throws RemoteException {
doThrow(new RemoteException("Unknown"))
.when(mWindowManager).isWindowTraceEnabled();
assertThat(mWindowTrace.isEnabled()).isFalse();
}
@Test
public void setIsEnableTrue_shouldEnableWindowTrace() throws RemoteException {
mWindowTrace.setIsEnabled(true);
verify(mWindowManager).startWindowTrace();
verifyNoMoreInteractions(mWindowManager);
}
@Test
@Config(shadows = {ShadowParcel.class})
public void setIsEnableFalse_shouldDisableWindowTraceAndShowToast() throws RemoteException {
mWindowTrace.setIsEnabled(false);
verify(mWindowManager).stopWindowTrace();
verify(mToast).show();
verifyNoMoreInteractions(mWindowManager);
}
@Test
public void setIsEnableAndWmThrowsRemoteException_shouldDoNothing() throws RemoteException {
doThrow(new RemoteException("Unknown")).when(mWindowManager).isWindowTraceEnabled();
mWindowTrace.setIsEnabled(true);
}
}

View File

@@ -0,0 +1,204 @@
/*
* 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.settings.development.qstile;
import static com.android.settings.development.qstile.DevelopmentTiles.WinscopeTrace
.SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE;
import static com.android.settings.development.qstile.DevelopmentTiles.WinscopeTrace
.SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.Toast;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.ShadowParcel;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.wrapper.IWindowManagerWrapper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class WinscopeTraceTest {
@Mock
private IWindowManagerWrapper mWindowManager;
@Mock
private IBinder mSurfaceFlinger;
@Mock
private Toast mToast;
private DevelopmentTiles.WinscopeTrace mWinscopeTrace;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mWinscopeTrace = spy(new DevelopmentTiles.WinscopeTrace());
ReflectionHelpers.setField(mWinscopeTrace, "mWindowManager", mWindowManager);
ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", mSurfaceFlinger);
ReflectionHelpers.setField(mWinscopeTrace, "mToast", mToast);
}
@After
public void teardown() {
verifyNoMoreInteractions(mToast);
}
@Test
@Config(shadows = {ShadowParcel.class})
public void wmReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
// Assume Surface Trace is disabled.
ShadowParcel.sReadBoolResult = false;
doReturn(true).when(mWindowManager).isWindowTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isTrue();
}
@Test
@Config(shadows = {ShadowParcel.class})
public void sfReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
// Assume Window Trace is disabled.
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
ShadowParcel.sReadBoolResult = true;
assertThat(mWinscopeTrace.isEnabled()).isTrue();
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
eq(0 /* flags */));
verifyNoMoreInteractions(mSurfaceFlinger);
}
@Test
@Config(shadows = {ShadowParcel.class})
public void sfAndWmReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
ShadowParcel.sReadBoolResult = true;
doReturn(true).when(mWindowManager).isWindowTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isTrue();
}
@Test
public void wmAndSfReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException {
ShadowParcel.sReadBoolResult = false;
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isFalse();
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
eq(0 /* flags */));
verifyNoMoreInteractions(mSurfaceFlinger);
}
@Test
@Config(shadows = {ShadowParcel.class})
public void wmThrowsRemoteExAndSfReturnsTraceDisabled_shouldReturnDisabled()
throws RemoteException {
ShadowParcel.sReadBoolResult = false;
doThrow(new RemoteException("Unknown"))
.when(mWindowManager).isWindowTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isFalse();
}
@Test
public void sfUnavailableAndWmReturnsTraceDisabled_shouldReturnDisabled()
throws RemoteException {
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", null);
assertThat(mWinscopeTrace.isEnabled()).isFalse();
}
@Test
public void setIsEnableTrue_shouldEnableWindowTrace() throws RemoteException {
mWinscopeTrace.setIsEnabled(true);
verify(mWindowManager).startWindowTrace();
verifyNoMoreInteractions(mWindowManager);
}
@Test
@Config(shadows = {ShadowParcel.class})
public void setIsEnableTrue_shouldEnableLayerTrace() throws RemoteException {
mWinscopeTrace.setIsEnabled(true);
assertThat(ShadowParcel.sWriteIntResult).isEqualTo(1);
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE), any(), isNull(),
eq(0 /* flags */));
verifyNoMoreInteractions(mSurfaceFlinger);
}
@Test
@Config(shadows = {ShadowParcel.class})
public void setIsEnableFalse_shouldDisableWindowTrace() throws RemoteException {
mWinscopeTrace.setIsEnabled(false);
verify(mWindowManager).stopWindowTrace();
verifyNoMoreInteractions(mWindowManager);
verify(mToast).show();
}
@Test
@Config(shadows = {ShadowParcel.class})
public void setIsEnableFalse_shouldDisableLayerTrace() throws RemoteException {
mWinscopeTrace.setIsEnabled(false);
assertThat(ShadowParcel.sWriteIntResult).isEqualTo(0);
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_CONTROL_CODE), any(), isNull(),
eq(0 /* flags */));
verifyNoMoreInteractions(mSurfaceFlinger);
verify(mToast).show();
}
@Test
public void setIsEnableFalse_shouldShowToast() throws RemoteException {
mWinscopeTrace.setIsEnabled(false);
verify(mToast).show();
}
/**
* Verify when window manager call throws a remote exception, it is handled without
* re-throwing the exception.
*/
@Test
public void setIsEnableAndWmThrowsRemoteException_shouldFailGracefully()
throws RemoteException {
doThrow(new RemoteException("Unknown")).when(mWindowManager).isWindowTraceEnabled();
mWinscopeTrace.setIsEnabled(true);
}
/**
* Verify is surface flinger is not available not calls are made to it.
*/
@Test
public void setIsEnableAndSfUnavailable_shouldFailGracefully() throws RemoteException {
ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", null);
mWinscopeTrace.setIsEnabled(true);
verifyNoMoreInteractions(mSurfaceFlinger);
}
}