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
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index dec12ba..7b24600 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -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>
diff --git a/res/drawable/tile_icon_layer_trace.xml b/res/drawable/tile_icon_layer_trace.xml
deleted file mode 100644
index 21dafd3..0000000
--- a/res/drawable/tile_icon_layer_trace.xml
+++ /dev/null
@@ -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>
-
diff --git a/res/drawable/tile_icon_window_trace.xml b/res/drawable/tile_icon_winscope_trace.xml
similarity index 100%
rename from res/drawable/tile_icon_window_trace.xml
rename to res/drawable/tile_icon_winscope_trace.xml
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d7a4586..cbfcbf4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -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>
diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java
index 38f9565..736c40c 100644
--- a/src/com/android/settings/development/qstile/DevelopmentTiles.java
+++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java
@@ -142,26 +142,29 @@
}
/**
- * 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 @@
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 {
@@ -219,8 +184,8 @@
data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
mSurfaceFlinger.transact(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE,
- data, reply, 0 /* flags */ );
- surfaceTraceEnabled = reply.readBoolean();
+ data, reply, 0 /* flags */);
+ layerTraceEnabled = reply.readBoolean();
}
} catch (RemoteException e) {
Log.e(TAG, "Could not get layer trace status, defaulting to false." + e.toString());
@@ -230,11 +195,27 @@
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 @@
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 @@
}
}
}
+
+ @Override
+ protected void setIsEnabled(boolean isEnabled) {
+ setWindowTraceEnabled(isEnabled);
+ setLayerTraceEnabled(isEnabled);
+ if (!isEnabled) {
+ mToast.show();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/development/qstile/LayerTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/LayerTraceTest.java
deleted file mode 100644
index 0e42759..0000000
--- a/tests/robotests/src/com/android/settings/development/qstile/LayerTraceTest.java
+++ /dev/null
@@ -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);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/development/qstile/WindowTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/WindowTraceTest.java
deleted file mode 100644
index d8a8084..0000000
--- a/tests/robotests/src/com/android/settings/development/qstile/WindowTraceTest.java
+++ /dev/null
@@ -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);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java
new file mode 100644
index 0000000..92f5c22
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java
@@ -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);
+ }
+}