diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngineConnectionRegistry.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngineConnectionRegistry.java index e1ae7440f0..c0e269f19a 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngineConnectionRegistry.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/FlutterEngineConnectionRegistry.java @@ -125,8 +125,9 @@ import java.util.Set; @Override public void add(@NonNull FlutterPlugin plugin) { - TraceSection.begin("FlutterEngineConnectionRegistry#add " + plugin.getClass().getSimpleName()); - try { + try (TraceSection e = + TraceSection.scoped( + "FlutterEngineConnectionRegistry#add " + plugin.getClass().getSimpleName())) { if (has(plugin.getClass())) { Log.w( TAG, @@ -192,8 +193,6 @@ import java.util.Set; contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding); } } - } finally { - TraceSection.end(); } } @@ -221,8 +220,9 @@ import java.util.Set; return; } - TraceSection.begin("FlutterEngineConnectionRegistry#remove " + pluginClass.getSimpleName()); - try { + try (TraceSection e = + TraceSection.scoped( + "FlutterEngineConnectionRegistry#remove " + pluginClass.getSimpleName())) { // For ActivityAware plugins, notify the plugin that it is detached from // an Activity if an Activity is currently attached to this engine. Then // remove the plugin from our set of ActivityAware plugins. @@ -271,8 +271,6 @@ import java.util.Set; // it from our set of generic plugins. plugin.onDetachedFromEngine(pluginBinding); plugins.remove(pluginClass); - } finally { - TraceSection.end(); } } @@ -315,8 +313,7 @@ import java.util.Set; @Override public void attachToActivity( @NonNull ExclusiveAppComponent exclusiveActivity, @NonNull Lifecycle lifecycle) { - TraceSection.begin("FlutterEngineConnectionRegistry#attachToActivity"); - try { + try (TraceSection e = TraceSection.scoped("FlutterEngineConnectionRegistry#attachToActivity")) { if (this.exclusiveActivity != null) { this.exclusiveActivity.detachFromFlutterEngine(); } @@ -324,8 +321,6 @@ import java.util.Set; detachFromAppComponent(); this.exclusiveActivity = exclusiveActivity; attachToActivityInternal(exclusiveActivity.getAppComponent(), lifecycle); - } finally { - TraceSection.end(); } } @@ -361,8 +356,9 @@ import java.util.Set; @Override public void detachFromActivityForConfigChanges() { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#detachFromActivityForConfigChanges"); - try { + try (TraceSection e = + TraceSection.scoped( + "FlutterEngineConnectionRegistry#detachFromActivityForConfigChanges")) { isWaitingForActivityReattachment = true; for (ActivityAware activityAware : activityAwarePlugins.values()) { @@ -370,8 +366,6 @@ import java.util.Set; } detachFromActivityInternal(); - } finally { - TraceSection.end(); } } else { Log.e(TAG, "Attempted to detach plugins from an Activity when no Activity was attached."); @@ -381,15 +375,13 @@ import java.util.Set; @Override public void detachFromActivity() { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#detachFromActivity"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#detachFromActivity")) { for (ActivityAware activityAware : activityAwarePlugins.values()) { activityAware.onDetachedFromActivity(); } detachFromActivityInternal(); - } finally { - TraceSection.end(); } } else { Log.e(TAG, "Attempted to detach plugins from an Activity when no Activity was attached."); @@ -408,12 +400,10 @@ import java.util.Set; public boolean onRequestPermissionsResult( int requestCode, @NonNull String[] permissions, @NonNull int[] grantResult) { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onRequestPermissionsResult"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#onRequestPermissionsResult")) { return activityPluginBinding.onRequestPermissionsResult( requestCode, permissions, grantResult); - } finally { - TraceSection.end(); } } else { Log.e( @@ -427,11 +417,9 @@ import java.util.Set; @Override public boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onActivityResult"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#onActivityResult")) { return activityPluginBinding.onActivityResult(requestCode, resultCode, data); - } finally { - TraceSection.end(); } } else { Log.e( @@ -445,11 +433,8 @@ import java.util.Set; @Override public void onNewIntent(@NonNull Intent intent) { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onNewIntent"); - try { + try (TraceSection e = TraceSection.scoped("FlutterEngineConnectionRegistry#onNewIntent")) { activityPluginBinding.onNewIntent(intent); - } finally { - TraceSection.end(); } } else { Log.e( @@ -462,11 +447,9 @@ import java.util.Set; @Override public void onUserLeaveHint() { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onUserLeaveHint"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#onUserLeaveHint")) { activityPluginBinding.onUserLeaveHint(); - } finally { - TraceSection.end(); } } else { Log.e( @@ -479,11 +462,9 @@ import java.util.Set; @Override public void onSaveInstanceState(@NonNull Bundle bundle) { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onSaveInstanceState"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#onSaveInstanceState")) { activityPluginBinding.onSaveInstanceState(bundle); - } finally { - TraceSection.end(); } } else { Log.e( @@ -496,11 +477,9 @@ import java.util.Set; @Override public void onRestoreInstanceState(@Nullable Bundle bundle) { if (isAttachedToActivity()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onRestoreInstanceState"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#onRestoreInstanceState")) { activityPluginBinding.onRestoreInstanceState(bundle); - } finally { - TraceSection.end(); } } else { Log.e( @@ -519,8 +498,7 @@ import java.util.Set; @Override public void attachToService( @NonNull Service service, @Nullable Lifecycle lifecycle, boolean isForeground) { - TraceSection.begin("FlutterEngineConnectionRegistry#attachToService"); - try { + try (TraceSection e = TraceSection.scoped("FlutterEngineConnectionRegistry#attachToService")) { // If we were already attached to an Android component, detach from it. detachFromAppComponent(); @@ -531,16 +509,14 @@ import java.util.Set; for (ServiceAware serviceAware : serviceAwarePlugins.values()) { serviceAware.onAttachedToService(servicePluginBinding); } - } finally { - TraceSection.end(); } } @Override public void detachFromService() { if (isAttachedToService()) { - TraceSection.begin("FlutterEngineConnectionRegistry#detachFromService"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#detachFromService")) { // Notify all ServiceAware plugins that they are no longer attached to a Service. for (ServiceAware serviceAware : serviceAwarePlugins.values()) { serviceAware.onDetachedFromService(); @@ -548,8 +524,6 @@ import java.util.Set; service = null; servicePluginBinding = null; - } finally { - TraceSection.end(); } } else { Log.e(TAG, "Attempted to detach plugins from a Service when no Service was attached."); @@ -559,11 +533,9 @@ import java.util.Set; @Override public void onMoveToForeground() { if (isAttachedToService()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onMoveToForeground"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#onMoveToForeground")) { servicePluginBinding.onMoveToForeground(); - } finally { - TraceSection.end(); } } } @@ -571,12 +543,9 @@ import java.util.Set; @Override public void onMoveToBackground() { if (isAttachedToService()) { - TraceSection.begin("FlutterEngineConnectionRegistry#onMoveToBackground"); - ; - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#onMoveToBackground")) { servicePluginBinding.onMoveToBackground(); - } finally { - TraceSection.end(); } } } @@ -590,8 +559,8 @@ import java.util.Set; @Override public void attachToBroadcastReceiver( @NonNull BroadcastReceiver broadcastReceiver, @NonNull Lifecycle lifecycle) { - TraceSection.begin("FlutterEngineConnectionRegistry#attachToBroadcastReceiver"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#attachToBroadcastReceiver")) { // If we were already attached to an Android component, detach from it. detachFromAppComponent(); @@ -606,24 +575,20 @@ import java.util.Set; for (BroadcastReceiverAware broadcastReceiverAware : broadcastReceiverAwarePlugins.values()) { broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding); } - } finally { - TraceSection.end(); } } @Override public void detachFromBroadcastReceiver() { if (isAttachedToBroadcastReceiver()) { - TraceSection.begin("FlutterEngineConnectionRegistry#detachFromBroadcastReceiver"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#detachFromBroadcastReceiver")) { // Notify all BroadcastReceiverAware plugins that they are no longer attached to a // BroadcastReceiver. for (BroadcastReceiverAware broadcastReceiverAware : broadcastReceiverAwarePlugins.values()) { broadcastReceiverAware.onDetachedFromBroadcastReceiver(); } - } finally { - TraceSection.end(); } } else { Log.e( @@ -643,8 +608,8 @@ import java.util.Set; public void attachToContentProvider( @NonNull ContentProvider contentProvider, @NonNull Lifecycle lifecycle) { - TraceSection.begin("FlutterEngineConnectionRegistry#attachToContentProvider"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#attachToContentProvider")) { // If we were already attached to an Android component, detach from it. detachFromAppComponent(); @@ -659,23 +624,19 @@ import java.util.Set; for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) { contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding); } - } finally { - TraceSection.end(); } } @Override public void detachFromContentProvider() { if (isAttachedToContentProvider()) { - TraceSection.begin("FlutterEngineConnectionRegistry#detachFromContentProvider"); - try { + try (TraceSection e = + TraceSection.scoped("FlutterEngineConnectionRegistry#detachFromContentProvider")) { // Notify all ContentProviderAware plugins that they are no longer attached to a // ContentProvider. for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) { contentProviderAware.onDetachedFromContentProvider(); } - } finally { - TraceSection.end(); } } else { Log.e( diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java index e7fb3fc10d..8f6b862c5a 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartExecutor.java @@ -141,8 +141,7 @@ public class DartExecutor implements BinaryMessenger { return; } - TraceSection.begin("DartExecutor#executeDartEntrypoint"); - try { + try (TraceSection e = TraceSection.scoped("DartExecutor#executeDartEntrypoint")) { Log.v(TAG, "Executing Dart entrypoint: " + dartEntrypoint); flutterJNI.runBundleAndSnapshotFromLibrary( dartEntrypoint.pathToBundle, @@ -152,8 +151,6 @@ public class DartExecutor implements BinaryMessenger { dartEntrypointArgs); isApplicationRunning = true; - } finally { - TraceSection.end(); } } @@ -170,8 +167,7 @@ public class DartExecutor implements BinaryMessenger { return; } - TraceSection.begin("DartExecutor#executeDartCallback"); - try { + try (TraceSection e = TraceSection.scoped("DartExecutor#executeDartCallback")) { Log.v(TAG, "Executing Dart callback: " + dartCallback); flutterJNI.runBundleAndSnapshotFromLibrary( dartCallback.pathToBundle, @@ -181,8 +177,6 @@ public class DartExecutor implements BinaryMessenger { null); isApplicationRunning = true; - } finally { - TraceSection.end(); } } diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java index 98cb37874c..6a7561d741 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/dart/DartMessenger.java @@ -269,8 +269,7 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler { @NonNull String channel, @Nullable ByteBuffer message, @Nullable BinaryMessenger.BinaryReply callback) { - TraceSection.begin("DartMessenger#send on " + channel); - try { + try (TraceSection e = TraceSection.scoped("DartMessenger#send on " + channel)) { Log.v(TAG, "Sending message with callback over channel '" + channel + "'"); int replyId = nextReplyId++; if (callback != null) { @@ -281,8 +280,6 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler { } else { flutterJNI.dispatchPlatformMessage(channel, message, message.position(), replyId); } - } finally { - TraceSection.end(); } } @@ -317,8 +314,8 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler { Runnable myRunnable = () -> { TraceSection.endAsyncSection("PlatformChannel ScheduleHandler on " + channel, replyId); - TraceSection.begin("DartMessenger#handleMessageFromDart on " + channel); - try { + try (TraceSection e = + TraceSection.scoped("DartMessenger#handleMessageFromDart on " + channel)) { invokeHandler(handlerInfo, message, replyId); if (message != null && message.isDirect()) { // This ensures that if a user retains an instance to the ByteBuffer and it @@ -328,7 +325,6 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler { } finally { // This is deleting the data underneath the message object. flutterJNI.cleanupMessageData(messageData); - TraceSection.end(); } }; final DartMessengerTaskQueue nonnullTaskQueue = diff --git a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index 599de9bbcf..c7eb09b0a2 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -157,8 +157,7 @@ public class FlutterLoader { throw new IllegalStateException("startInitialization must be called on the main thread"); } - TraceSection.begin("FlutterLoader#startInitialization"); - try { + try (TraceSection e = TraceSection.scoped("FlutterLoader#startInitialization")) { // Ensure that the context is actually the application context. final Context appContext = applicationContext.getApplicationContext(); @@ -186,8 +185,7 @@ public class FlutterLoader { new Callable() { @Override public InitResult call() { - TraceSection.begin("FlutterLoader initTask"); - try { + try (TraceSection e = TraceSection.scoped("FlutterLoader initTask")) { ResourceExtractor resourceExtractor = initResources(appContext); flutterJNI.loadLibrary(); @@ -205,14 +203,10 @@ public class FlutterLoader { PathUtils.getFilesDir(appContext), PathUtils.getCacheDirectory(appContext), PathUtils.getDataDirectory(appContext)); - } finally { - TraceSection.end(); } } }; initResultFuture = executorService.submit(initTask); - } finally { - TraceSection.end(); } } @@ -245,8 +239,7 @@ public class FlutterLoader { "ensureInitializationComplete must be called after startInitialization"); } - TraceSection.begin("FlutterLoader#ensureInitializationComplete"); - try { + try (TraceSection e = TraceSection.scoped("FlutterLoader#ensureInitializationComplete")) { InitResult result = initResultFuture.get(); List shellArgs = new ArrayList<>(); @@ -363,8 +356,6 @@ public class FlutterLoader { } catch (Exception e) { Log.e(TAG, "Flutter initialization failed.", e); throw new RuntimeException(e); - } finally { - TraceSection.end(); } } diff --git a/engine/src/flutter/shell/platform/android/io/flutter/util/TraceSection.java b/engine/src/flutter/shell/platform/android/io/flutter/util/TraceSection.java index 53c2889678..83352f8722 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/util/TraceSection.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/util/TraceSection.java @@ -4,10 +4,37 @@ package io.flutter.util; +import android.annotation.TargetApi; import androidx.annotation.NonNull; import androidx.tracing.Trace; -public final class TraceSection { +@TargetApi(19) +public final class TraceSection implements AutoCloseable { + /** + * Factory used to support the try-with-resource construct. + * + *

To get scoped trace events, use the try-with-resource construct, for instance: + * + *

{@code
+   * try (TraceSection e = TraceSection.scoped("MyTraceEvent")) {
+   *   // code.
+   * }
+   * }
+ */ + public static TraceSection scoped(String name) { + return new TraceSection(name); + } + + /** Constructor used to support the try-with-resource construct. */ + private TraceSection(String name) { + begin(name); + } + + @Override + public void close() { + end(); + } + private static String cropSectionName(@NonNull String sectionName) { return sectionName.length() < 124 ? sectionName : sectionName.substring(0, 124) + "..."; }