From a218bc05e6408e40c97c4b10da5c8b561a068857 Mon Sep 17 00:00:00 2001 From: Ioana Stefan Date: Tue, 3 Nov 2020 17:12:52 +0000 Subject: [PATCH] Add IME tracing to data gathered in WinscopeTrace This change starts and stops IME tracing together with the other traces gathered when the WinscopeTrace tile is used. The data is saved along the other traces in /data/misc/wmtrace/. Bug: 154348613 Bug: 167948910 Test: flash a device together with the other change in this topic enable the WinscopeTrace tile and do some actions disable the WinscopeTrace tile do a bugreport and visualise contents in Winscope or just check contents of /data/misc/wmtrace/ through adb Change-Id: If0b16dd5c19aa8bb33174abe2fe242fc8e6bdd90 --- .../development/qstile/DevelopmentTiles.java | 29 ++++++- .../development/qstile/WinscopeTraceTest.java | 75 +++++++++++++++++-- 2 files changed, 98 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java index b8af7403254..e64c8c05756 100644 --- a/src/com/android/settings/development/qstile/DevelopmentTiles.java +++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java @@ -49,6 +49,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.app.LocalePicker; import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.view.IInputMethodManager; import com.android.settings.R; import com.android.settings.development.WirelessDebuggingPreferenceController; import com.android.settings.overlay.FeatureFactory; @@ -197,6 +198,7 @@ public abstract class DevelopmentTiles extends TileService { static final int SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE = 1026; private IBinder mSurfaceFlinger; private IWindowManager mWindowManager; + private IInputMethodManager mInputMethodManager; private Toast mToast; @Override @@ -204,6 +206,8 @@ public abstract class DevelopmentTiles extends TileService { super.onCreate(); mWindowManager = WindowManagerGlobal.getWindowManagerService(); mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger"); + mInputMethodManager = IInputMethodManager.Stub.asInterface( + ServiceManager.getService("input_method")); Context context = getApplicationContext(); CharSequence text = "Trace files written to /data/misc/wmtrace"; mToast = Toast.makeText(context, text, Toast.LENGTH_LONG); @@ -256,9 +260,19 @@ public abstract class DevelopmentTiles extends TileService { return false; } + private boolean isImeTraceEnabled() { + try { + return mInputMethodManager.isImeTraceEnabled(); + } catch (RemoteException e) { + Log.e(TAG, "Could not get ime trace status, defaulting to false.", e); + } + return false; + } + @Override protected boolean isEnabled() { - return isWindowTraceEnabled() || isLayerTraceEnabled() || isSystemUiTracingEnabled(); + return isWindowTraceEnabled() || isLayerTraceEnabled() || isSystemUiTracingEnabled() + || isImeTraceEnabled(); } private void setWindowTraceEnabled(boolean isEnabled) { @@ -308,11 +322,24 @@ public abstract class DevelopmentTiles extends TileService { } } + private void setImeTraceEnabled(boolean isEnabled) { + try { + if (isEnabled) { + mInputMethodManager.startImeTrace(); + } else { + mInputMethodManager.stopImeTrace(); + } + } catch (RemoteException e) { + Log.e(TAG, "Could not set ime trace status." + e.toString()); + } + } + @Override protected void setIsEnabled(boolean isEnabled) { setWindowTraceEnabled(isEnabled); setLayerTraceEnabled(isEnabled); setSystemUiTracing(isEnabled); + setImeTraceEnabled(isEnabled); if (!isEnabled) { mToast.show(); } diff --git a/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java index cafebe44c0b..b4dab0d7cbd 100644 --- a/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java +++ b/tests/robotests/src/com/android/settings/development/qstile/WinscopeTraceTest.java @@ -37,6 +37,7 @@ import android.os.RemoteException; import android.view.IWindowManager; import android.widget.Toast; +import com.android.internal.view.IInputMethodManager; import com.android.settings.testutils.shadow.ShadowParcel; import org.junit.After; @@ -55,6 +56,8 @@ public class WinscopeTraceTest { @Mock private IWindowManager mWindowManager; @Mock + private IInputMethodManager mInputMethodManager; + @Mock private IBinder mSurfaceFlinger; @Mock private Toast mToast; @@ -66,6 +69,7 @@ public class WinscopeTraceTest { MockitoAnnotations.initMocks(this); mWinscopeTrace = spy(new DevelopmentTiles.WinscopeTrace()); ReflectionHelpers.setField(mWinscopeTrace, "mWindowManager", mWindowManager); + ReflectionHelpers.setField(mWinscopeTrace, "mInputMethodManager", mInputMethodManager); ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", mSurfaceFlinger); ReflectionHelpers.setField(mWinscopeTrace, "mToast", mToast); } @@ -78,7 +82,7 @@ public class WinscopeTraceTest { @Test @Config(shadows = ShadowParcel.class) public void wmReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException { - // Assume Surface Trace is disabled. + // Assume Surface Trace and Input Method Manager are disabled. ShadowParcel.sReadBoolResult = false; doReturn(true).when(mWindowManager).isWindowTraceEnabled(); assertThat(mWinscopeTrace.isEnabled()).isTrue(); @@ -87,8 +91,9 @@ public class WinscopeTraceTest { @Test @Config(shadows = ShadowParcel.class) public void sfReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException { - // Assume Window Trace is disabled. + // Assume Window Trace and Input Method Manager are disabled. doReturn(false).when(mWindowManager).isWindowTraceEnabled(); + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); ShadowParcel.sReadBoolResult = true; assertThat(mWinscopeTrace.isEnabled()).isTrue(); verify(mSurfaceFlinger) @@ -106,16 +111,48 @@ public class WinscopeTraceTest { } @Test - public void wmAndSfReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException { + public void wmAndSfAndImmReturnTraceDisabled_shouldReturnDisabled() throws RemoteException { ShadowParcel.sReadBoolResult = false; doReturn(false).when(mWindowManager).isWindowTraceEnabled(); + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); assertThat(mWinscopeTrace.isEnabled()).isFalse(); verify(mSurfaceFlinger) .transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(), - eq(0 /* flags */)); + eq(0 /* flags */)); verifyNoMoreInteractions(mSurfaceFlinger); } + @Test + public void wmAndSfReturnTraceDisabled_immReturnsTraceEnabled_shouldReturnEnabled() + throws RemoteException { + ShadowParcel.sReadBoolResult = false; + doReturn(false).when(mWindowManager).isWindowTraceEnabled(); + doReturn(true).when(mInputMethodManager).isImeTraceEnabled(); + 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 immReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException { + // Assume Window Manager and Surface Trace are disabled. + ShadowParcel.sReadBoolResult = false; + doReturn(true).when(mInputMethodManager).isImeTraceEnabled(); + assertThat(mWinscopeTrace.isEnabled()).isTrue(); + } + + @Test + @Config(shadows = ShadowParcel.class) + public void immReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException { + // Assume Window Manager and Surface Trace are disabled. + ShadowParcel.sReadBoolResult = false; + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); + assertThat(mWinscopeTrace.isEnabled()).isFalse(); + } + @Test @Config(shadows = ShadowParcel.class) public void wmThrowsRemoteExAndSfReturnsTraceDisabled_shouldReturnDisabled() @@ -127,9 +164,10 @@ public class WinscopeTraceTest { } @Test - public void sfUnavailableAndWmReturnsTraceDisabled_shouldReturnDisabled() + public void sfUnavailableAndWmAndImmReturnTraceDisabled_shouldReturnDisabled() throws RemoteException { doReturn(false).when(mWindowManager).isWindowTraceEnabled(); + doReturn(false).when(mInputMethodManager).isImeTraceEnabled(); ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", null); assertThat(mWinscopeTrace.isEnabled()).isFalse(); } @@ -141,6 +179,13 @@ public class WinscopeTraceTest { verifyNoMoreInteractions(mWindowManager); } + @Test + public void setIsEnableTrue_shouldEnableImeTrace() throws RemoteException { + mWinscopeTrace.setIsEnabled(true); + verify(mInputMethodManager).startImeTrace(); + verifyNoMoreInteractions(mInputMethodManager); + } + @Test @Config(shadows = ShadowParcel.class) public void setIsEnableTrue_shouldEnableLayerTrace() throws RemoteException { @@ -161,6 +206,15 @@ public class WinscopeTraceTest { verify(mToast).show(); } + @Test + @Config(shadows = ShadowParcel.class) + public void setIsEnableFalse_shouldDisableImeTrace() throws RemoteException { + mWinscopeTrace.setIsEnabled(false); + verify(mInputMethodManager).stopImeTrace(); + verifyNoMoreInteractions(mInputMethodManager); + verify(mToast).show(); + } + @Test @Config(shadows = ShadowParcel.class) public void setIsEnableFalse_shouldDisableLayerTrace() throws RemoteException { @@ -190,6 +244,17 @@ public class WinscopeTraceTest { mWinscopeTrace.setIsEnabled(true); } + /** + * Verify when input method manager call throws a remote exception, it is handled without + * re-throwing the exception. + */ + @Test + public void setIsEnableAndImmThrowsRemoteException_shouldFailGracefully() + throws RemoteException { + doThrow(new RemoteException("Unknown")).when(mInputMethodManager).isImeTraceEnabled(); + mWinscopeTrace.setIsEnabled(true); + } + /** * Verify is surface flinger is not available not calls are made to it. */