Add traces to Android embedding (flutter/engine#29230)

This commit is contained in:
Jia Hao
2021-10-29 11:59:32 +08:00
committed by GitHub
parent 5b1ae8d184
commit 302c2be546
9 changed files with 374 additions and 196 deletions

View File

@@ -14,6 +14,7 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.tracing.Trace;
import io.flutter.Log;
import io.flutter.embedding.android.ExclusiveAppComponent;
import io.flutter.embedding.engine.loader.FlutterLoader;
@@ -122,70 +123,76 @@ import java.util.Set;
@Override
public void add(@NonNull FlutterPlugin plugin) {
if (has(plugin.getClass())) {
Log.w(
TAG,
"Attempted to register plugin ("
+ plugin
+ ") but it was "
+ "already registered with this FlutterEngine ("
+ flutterEngine
+ ").");
return;
}
Trace.beginSection("FlutterEngineConnectionRegistry#add " + plugin.getClass().getSimpleName());
Log.v(TAG, "Adding plugin: " + plugin);
// Add the plugin to our generic set of plugins and notify the plugin
// that is has been attached to an engine.
plugins.put(plugin.getClass(), plugin);
plugin.onAttachedToEngine(pluginBinding);
// For ActivityAware plugins, add the plugin to our set of ActivityAware
// plugins, and if this engine is currently attached to an Activity,
// notify the ActivityAware plugin that it is now attached to an Activity.
if (plugin instanceof ActivityAware) {
ActivityAware activityAware = (ActivityAware) plugin;
activityAwarePlugins.put(plugin.getClass(), activityAware);
if (isAttachedToActivity()) {
activityAware.onAttachedToActivity(activityPluginBinding);
try {
if (has(plugin.getClass())) {
Log.w(
TAG,
"Attempted to register plugin ("
+ plugin
+ ") but it was "
+ "already registered with this FlutterEngine ("
+ flutterEngine
+ ").");
return;
}
}
// For ServiceAware plugins, add the plugin to our set of ServiceAware
// plugins, and if this engine is currently attached to a Service,
// notify the ServiceAware plugin that it is now attached to a Service.
if (plugin instanceof ServiceAware) {
ServiceAware serviceAware = (ServiceAware) plugin;
serviceAwarePlugins.put(plugin.getClass(), serviceAware);
Log.v(TAG, "Adding plugin: " + plugin);
// Add the plugin to our generic set of plugins and notify the plugin
// that is has been attached to an engine.
plugins.put(plugin.getClass(), plugin);
plugin.onAttachedToEngine(pluginBinding);
if (isAttachedToService()) {
serviceAware.onAttachedToService(servicePluginBinding);
// For ActivityAware plugins, add the plugin to our set of ActivityAware
// plugins, and if this engine is currently attached to an Activity,
// notify the ActivityAware plugin that it is now attached to an Activity.
if (plugin instanceof ActivityAware) {
ActivityAware activityAware = (ActivityAware) plugin;
activityAwarePlugins.put(plugin.getClass(), activityAware);
if (isAttachedToActivity()) {
activityAware.onAttachedToActivity(activityPluginBinding);
}
}
}
// For BroadcastReceiverAware plugins, add the plugin to our set of BroadcastReceiverAware
// plugins, and if this engine is currently attached to a BroadcastReceiver,
// notify the BroadcastReceiverAware plugin that it is now attached to a BroadcastReceiver.
if (plugin instanceof BroadcastReceiverAware) {
BroadcastReceiverAware broadcastReceiverAware = (BroadcastReceiverAware) plugin;
broadcastReceiverAwarePlugins.put(plugin.getClass(), broadcastReceiverAware);
// For ServiceAware plugins, add the plugin to our set of ServiceAware
// plugins, and if this engine is currently attached to a Service,
// notify the ServiceAware plugin that it is now attached to a Service.
if (plugin instanceof ServiceAware) {
ServiceAware serviceAware = (ServiceAware) plugin;
serviceAwarePlugins.put(plugin.getClass(), serviceAware);
if (isAttachedToBroadcastReceiver()) {
broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding);
if (isAttachedToService()) {
serviceAware.onAttachedToService(servicePluginBinding);
}
}
}
// For ContentProviderAware plugins, add the plugin to our set of ContentProviderAware
// plugins, and if this engine is currently attached to a ContentProvider,
// notify the ContentProviderAware plugin that it is now attached to a ContentProvider.
if (plugin instanceof ContentProviderAware) {
ContentProviderAware contentProviderAware = (ContentProviderAware) plugin;
contentProviderAwarePlugins.put(plugin.getClass(), contentProviderAware);
// For BroadcastReceiverAware plugins, add the plugin to our set of BroadcastReceiverAware
// plugins, and if this engine is currently attached to a BroadcastReceiver,
// notify the BroadcastReceiverAware plugin that it is now attached to a BroadcastReceiver.
if (plugin instanceof BroadcastReceiverAware) {
BroadcastReceiverAware broadcastReceiverAware = (BroadcastReceiverAware) plugin;
broadcastReceiverAwarePlugins.put(plugin.getClass(), broadcastReceiverAware);
if (isAttachedToContentProvider()) {
contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding);
if (isAttachedToBroadcastReceiver()) {
broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding);
}
}
// For ContentProviderAware plugins, add the plugin to our set of ContentProviderAware
// plugins, and if this engine is currently attached to a ContentProvider,
// notify the ContentProviderAware plugin that it is now attached to a ContentProvider.
if (plugin instanceof ContentProviderAware) {
ContentProviderAware contentProviderAware = (ContentProviderAware) plugin;
contentProviderAwarePlugins.put(plugin.getClass(), contentProviderAware);
if (isAttachedToContentProvider()) {
contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding);
}
}
} finally {
Trace.endSection();
}
}
@@ -209,7 +216,13 @@ import java.util.Set;
@Override
public void remove(@NonNull Class<? extends FlutterPlugin> pluginClass) {
FlutterPlugin plugin = plugins.get(pluginClass);
if (plugin != null) {
if (plugin == null) {
return;
}
Trace.beginSection("FlutterEngineConnectionRegistry#remove " + pluginClass.getSimpleName());
try {
Log.v(TAG, "Removing plugin: " + plugin);
// For ActivityAware plugins, notify the plugin that it is detached from
// an Activity if an Activity is currently attached to this engine. Then
@@ -259,6 +272,8 @@ import java.util.Set;
// it from our set of generic plugins.
plugin.onDetachedFromEngine(pluginBinding);
plugins.remove(pluginClass);
} finally {
Trace.endSection();
}
}
@@ -301,20 +316,26 @@ import java.util.Set;
@Override
public void attachToActivity(
@NonNull ExclusiveAppComponent<Activity> exclusiveActivity, @NonNull Lifecycle lifecycle) {
Log.v(
TAG,
"Attaching to an exclusive Activity: "
+ exclusiveActivity.getAppComponent()
+ (isAttachedToActivity() ? " evicting previous activity " + attachedActivity() : "")
+ "."
+ (isWaitingForActivityReattachment ? " This is after a config change." : ""));
if (this.exclusiveActivity != null) {
this.exclusiveActivity.detachFromFlutterEngine();
Trace.beginSection("FlutterEngineConnectionRegistry#attachToActivity");
try {
Log.v(
TAG,
"Attaching to an exclusive Activity: "
+ exclusiveActivity.getAppComponent()
+ (isAttachedToActivity() ? " evicting previous activity " + attachedActivity() : "")
+ "."
+ (isWaitingForActivityReattachment ? " This is after a config change." : ""));
if (this.exclusiveActivity != null) {
this.exclusiveActivity.detachFromFlutterEngine();
}
// If we were already attached to an app component, detach from it.
detachFromAppComponent();
this.exclusiveActivity = exclusiveActivity;
attachToActivityInternal(exclusiveActivity.getAppComponent(), lifecycle);
} finally {
Trace.endSection();
}
// If we were already attached to an app component, detach from it.
detachFromAppComponent();
this.exclusiveActivity = exclusiveActivity;
attachToActivityInternal(exclusiveActivity.getAppComponent(), lifecycle);
}
private void attachToActivityInternal(@NonNull Activity activity, @NonNull Lifecycle lifecycle) {
@@ -341,14 +362,20 @@ import java.util.Set;
@Override
public void detachFromActivityForConfigChanges() {
if (isAttachedToActivity()) {
Trace.beginSection("FlutterEngineConnectionRegistry#detachFromActivityForConfigChanges");
Log.v(TAG, "Detaching from an Activity for config changes: " + attachedActivity());
isWaitingForActivityReattachment = true;
for (ActivityAware activityAware : activityAwarePlugins.values()) {
activityAware.onDetachedFromActivityForConfigChanges();
try {
isWaitingForActivityReattachment = true;
for (ActivityAware activityAware : activityAwarePlugins.values()) {
activityAware.onDetachedFromActivityForConfigChanges();
}
detachFromActivityInternal();
} finally {
Trace.endSection();
}
detachFromActivityInternal();
} else {
Log.e(TAG, "Attempted to detach plugins from an Activity when no Activity was attached.");
}
@@ -357,12 +384,18 @@ import java.util.Set;
@Override
public void detachFromActivity() {
if (isAttachedToActivity()) {
Log.v(TAG, "Detaching from an Activity: " + attachedActivity());
for (ActivityAware activityAware : activityAwarePlugins.values()) {
activityAware.onDetachedFromActivity();
}
Trace.beginSection("FlutterEngineConnectionRegistry#detachFromActivity");
detachFromActivityInternal();
try {
Log.v(TAG, "Detaching from an Activity: " + attachedActivity());
for (ActivityAware activityAware : activityAwarePlugins.values()) {
activityAware.onDetachedFromActivity();
}
detachFromActivityInternal();
} finally {
Trace.endSection();
}
} else {
Log.e(TAG, "Attempted to detach plugins from an Activity when no Activity was attached.");
}
@@ -381,12 +414,19 @@ import java.util.Set;
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResult) {
Log.v(TAG, "Forwarding onRequestPermissionsResult() to plugins.");
if (isAttachedToActivity()) {
return activityPluginBinding.onRequestPermissionsResult(
requestCode, permissions, grantResult);
Trace.beginSection("FlutterEngineConnectionRegistry#onRequestPermissionsResult");
try {
return activityPluginBinding.onRequestPermissionsResult(
requestCode, permissions, grantResult);
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to notify ActivityAware plugins of onRequestPermissionsResult, but no Activity was attached.");
"Attempted to notify ActivityAware plugins of onRequestPermissionsResult, but no Activity"
+ " was attached.");
return false;
}
}
@@ -395,11 +435,18 @@ import java.util.Set;
public boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
Log.v(TAG, "Forwarding onActivityResult() to plugins.");
if (isAttachedToActivity()) {
return activityPluginBinding.onActivityResult(requestCode, resultCode, data);
Trace.beginSection("FlutterEngineConnectionRegistry#onActivityResult");
try {
return activityPluginBinding.onActivityResult(requestCode, resultCode, data);
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to notify ActivityAware plugins of onActivityResult, but no Activity was attached.");
"Attempted to notify ActivityAware plugins of onActivityResult, but no Activity was"
+ " attached.");
return false;
}
}
@@ -408,11 +455,18 @@ import java.util.Set;
public void onNewIntent(@NonNull Intent intent) {
Log.v(TAG, "Forwarding onNewIntent() to plugins.");
if (isAttachedToActivity()) {
activityPluginBinding.onNewIntent(intent);
Trace.beginSection("FlutterEngineConnectionRegistry#onNewIntent");
try {
activityPluginBinding.onNewIntent(intent);
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to notify ActivityAware plugins of onNewIntent, but no Activity was attached.");
"Attempted to notify ActivityAware plugins of onNewIntent, but no Activity was"
+ " attached.");
}
}
@@ -420,11 +474,18 @@ import java.util.Set;
public void onUserLeaveHint() {
Log.v(TAG, "Forwarding onUserLeaveHint() to plugins.");
if (isAttachedToActivity()) {
activityPluginBinding.onUserLeaveHint();
Trace.beginSection("FlutterEngineConnectionRegistry#onUserLeaveHint");
try {
activityPluginBinding.onUserLeaveHint();
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to notify ActivityAware plugins of onUserLeaveHint, but no Activity was attached.");
"Attempted to notify ActivityAware plugins of onUserLeaveHint, but no Activity was"
+ " attached.");
}
}
@@ -432,11 +493,18 @@ import java.util.Set;
public void onSaveInstanceState(@NonNull Bundle bundle) {
Log.v(TAG, "Forwarding onSaveInstanceState() to plugins.");
if (isAttachedToActivity()) {
activityPluginBinding.onSaveInstanceState(bundle);
Trace.beginSection("FlutterEngineConnectionRegistry#onSaveInstanceState");
try {
activityPluginBinding.onSaveInstanceState(bundle);
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to notify ActivityAware plugins of onSaveInstanceState, but no Activity was attached.");
"Attempted to notify ActivityAware plugins of onSaveInstanceState, but no Activity was"
+ " attached.");
}
}
@@ -444,11 +512,18 @@ import java.util.Set;
public void onRestoreInstanceState(@Nullable Bundle bundle) {
Log.v(TAG, "Forwarding onRestoreInstanceState() to plugins.");
if (isAttachedToActivity()) {
activityPluginBinding.onRestoreInstanceState(bundle);
Trace.beginSection("FlutterEngineConnectionRegistry#onRestoreInstanceState");
try {
activityPluginBinding.onRestoreInstanceState(bundle);
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to notify ActivityAware plugins of onRestoreInstanceState, but no Activity was attached.");
"Attempted to notify ActivityAware plugins of onRestoreInstanceState, but no Activity was"
+ " attached.");
}
}
// ------- End ActivityControlSurface -----
@@ -461,30 +536,42 @@ import java.util.Set;
@Override
public void attachToService(
@NonNull Service service, @Nullable Lifecycle lifecycle, boolean isForeground) {
Trace.beginSection("FlutterEngineConnectionRegistry#attachToService");
Log.v(TAG, "Attaching to a Service: " + service);
// If we were already attached to an Android component, detach from it.
detachFromAppComponent();
this.service = service;
this.servicePluginBinding = new FlutterEngineServicePluginBinding(service, lifecycle);
try {
// If we were already attached to an Android component, detach from it.
detachFromAppComponent();
// Notify all ServiceAware plugins that they are now attached to a new Service.
for (ServiceAware serviceAware : serviceAwarePlugins.values()) {
serviceAware.onAttachedToService(servicePluginBinding);
this.service = service;
this.servicePluginBinding = new FlutterEngineServicePluginBinding(service, lifecycle);
// Notify all ServiceAware plugins that they are now attached to a new Service.
for (ServiceAware serviceAware : serviceAwarePlugins.values()) {
serviceAware.onAttachedToService(servicePluginBinding);
}
} finally {
Trace.endSection();
}
}
@Override
public void detachFromService() {
if (isAttachedToService()) {
Trace.beginSection("FlutterEngineConnectionRegistry#detachFromService");
Log.v(TAG, "Detaching from a Service: " + service);
// Notify all ServiceAware plugins that they are no longer attached to a Service.
for (ServiceAware serviceAware : serviceAwarePlugins.values()) {
serviceAware.onDetachedFromService();
}
service = null;
servicePluginBinding = null;
try {
// Notify all ServiceAware plugins that they are no longer attached to a Service.
for (ServiceAware serviceAware : serviceAwarePlugins.values()) {
serviceAware.onDetachedFromService();
}
service = null;
servicePluginBinding = null;
} finally {
Trace.endSection();
}
} else {
Log.e(TAG, "Attempted to detach plugins from a Service when no Service was attached.");
}
@@ -493,16 +580,28 @@ import java.util.Set;
@Override
public void onMoveToForeground() {
if (isAttachedToService()) {
Log.v(TAG, "Attached Service moved to foreground.");
servicePluginBinding.onMoveToForeground();
Trace.beginSection("FlutterEngineConnectionRegistry#onMoveToForeground");
try {
Log.v(TAG, "Attached Service moved to foreground.");
servicePluginBinding.onMoveToForeground();
} finally {
Trace.endSection();
}
}
}
@Override
public void onMoveToBackground() {
if (isAttachedToService()) {
Trace.beginSection("FlutterEngineConnectionRegistry#onMoveToBackground");
Log.v(TAG, "Attached Service moved to background.");
servicePluginBinding.onMoveToBackground();
try {
servicePluginBinding.onMoveToBackground();
} finally {
Trace.endSection();
}
}
}
// ----- End ServiceControlSurface ---
@@ -515,36 +614,50 @@ import java.util.Set;
@Override
public void attachToBroadcastReceiver(
@NonNull BroadcastReceiver broadcastReceiver, @NonNull Lifecycle lifecycle) {
Trace.beginSection("FlutterEngineConnectionRegistry#attachToBroadcastReceiver");
Log.v(TAG, "Attaching to BroadcastReceiver: " + broadcastReceiver);
// If we were already attached to an Android component, detach from it.
detachFromAppComponent();
this.broadcastReceiver = broadcastReceiver;
this.broadcastReceiverPluginBinding =
new FlutterEngineBroadcastReceiverPluginBinding(broadcastReceiver);
// TODO(mattcarroll): resolve possibility of different lifecycles between this and engine
// attachment
try {
// If we were already attached to an Android component, detach from it.
detachFromAppComponent();
// Notify all BroadcastReceiverAware plugins that they are now attached to a new
// BroadcastReceiver.
for (BroadcastReceiverAware broadcastReceiverAware : broadcastReceiverAwarePlugins.values()) {
broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding);
this.broadcastReceiver = broadcastReceiver;
this.broadcastReceiverPluginBinding =
new FlutterEngineBroadcastReceiverPluginBinding(broadcastReceiver);
// TODO(mattcarroll): resolve possibility of different lifecycles between this and engine
// attachment
// Notify all BroadcastReceiverAware plugins that they are now attached to a new
// BroadcastReceiver.
for (BroadcastReceiverAware broadcastReceiverAware : broadcastReceiverAwarePlugins.values()) {
broadcastReceiverAware.onAttachedToBroadcastReceiver(broadcastReceiverPluginBinding);
}
} finally {
Trace.endSection();
}
}
@Override
public void detachFromBroadcastReceiver() {
if (isAttachedToBroadcastReceiver()) {
Trace.beginSection("FlutterEngineConnectionRegistry#detachFromBroadcastReceiver");
Log.v(TAG, "Detaching from BroadcastReceiver: " + broadcastReceiver);
// Notify all BroadcastReceiverAware plugins that they are no longer attached to a
// BroadcastReceiver.
for (BroadcastReceiverAware broadcastReceiverAware : broadcastReceiverAwarePlugins.values()) {
broadcastReceiverAware.onDetachedFromBroadcastReceiver();
try {
// Notify all BroadcastReceiverAware plugins that they are no longer attached to a
// BroadcastReceiver.
for (BroadcastReceiverAware broadcastReceiverAware :
broadcastReceiverAwarePlugins.values()) {
broadcastReceiverAware.onDetachedFromBroadcastReceiver();
}
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to detach plugins from a BroadcastReceiver when no BroadcastReceiver was attached.");
"Attempted to detach plugins from a BroadcastReceiver when no BroadcastReceiver was"
+ " attached.");
}
}
// ----- End BroadcastReceiverControlSurface ----
@@ -557,35 +670,49 @@ import java.util.Set;
@Override
public void attachToContentProvider(
@NonNull ContentProvider contentProvider, @NonNull Lifecycle lifecycle) {
Trace.beginSection("FlutterEngineConnectionRegistry#attachToContentProvider");
Log.v(TAG, "Attaching to ContentProvider: " + contentProvider);
// If we were already attached to an Android component, detach from it.
detachFromAppComponent();
this.contentProvider = contentProvider;
this.contentProviderPluginBinding =
new FlutterEngineContentProviderPluginBinding(contentProvider);
// TODO(mattcarroll): resolve possibility of different lifecycles between this and engine
// attachment
try {
// If we were already attached to an Android component, detach from it.
detachFromAppComponent();
// Notify all ContentProviderAware plugins that they are now attached to a new ContentProvider.
for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) {
contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding);
this.contentProvider = contentProvider;
this.contentProviderPluginBinding =
new FlutterEngineContentProviderPluginBinding(contentProvider);
// TODO(mattcarroll): resolve possibility of different lifecycles between this and engine
// attachment
// Notify all ContentProviderAware plugins that they are now attached to a new
// ContentProvider.
for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) {
contentProviderAware.onAttachedToContentProvider(contentProviderPluginBinding);
}
} finally {
Trace.endSection();
}
}
@Override
public void detachFromContentProvider() {
if (isAttachedToContentProvider()) {
Trace.beginSection("FlutterEngineConnectionRegistry#detachFromContentProvider");
Log.v(TAG, "Detaching from ContentProvider: " + contentProvider);
// Notify all ContentProviderAware plugins that they are no longer attached to a
// ContentProvider.
for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) {
contentProviderAware.onDetachedFromContentProvider();
try {
// Notify all ContentProviderAware plugins that they are no longer attached to a
// ContentProvider.
for (ContentProviderAware contentProviderAware : contentProviderAwarePlugins.values()) {
contentProviderAware.onDetachedFromContentProvider();
}
} finally {
Trace.endSection();
}
} else {
Log.e(
TAG,
"Attempted to detach plugins from a ContentProvider when no ContentProvider was attached.");
"Attempted to detach plugins from a ContentProvider when no ContentProvider was"
+ " attached.");
}
}
// ----- End ContentProviderControlSurface -----

View File

@@ -8,6 +8,7 @@ import android.content.res.AssetManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.tracing.Trace;
import io.flutter.FlutterInjector;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterJNI;
@@ -83,7 +84,8 @@ public class DartExecutor implements BinaryMessenger {
public void onAttachedToJNI() {
Log.v(
TAG,
"Attached to JNI. Registering the platform message handler for this Dart execution context.");
"Attached to JNI. Registering the platform message handler for this Dart execution"
+ " context.");
flutterJNI.setPlatformMessageHandler(dartMessenger);
}
@@ -97,7 +99,8 @@ public class DartExecutor implements BinaryMessenger {
public void onDetachedFromJNI() {
Log.v(
TAG,
"Detached from JNI. De-registering the platform message handler for this Dart execution context.");
"Detached from JNI. De-registering the platform message handler for this Dart execution"
+ " context.");
flutterJNI.setPlatformMessageHandler(null);
}
@@ -123,15 +126,20 @@ public class DartExecutor implements BinaryMessenger {
return;
}
Trace.beginSection("DartExecutor#executeDartEntrypoint");
Log.v(TAG, "Executing Dart entrypoint: " + dartEntrypoint);
flutterJNI.runBundleAndSnapshotFromLibrary(
dartEntrypoint.pathToBundle,
dartEntrypoint.dartEntrypointFunctionName,
dartEntrypoint.dartEntrypointLibrary,
assetManager);
try {
flutterJNI.runBundleAndSnapshotFromLibrary(
dartEntrypoint.pathToBundle,
dartEntrypoint.dartEntrypointFunctionName,
dartEntrypoint.dartEntrypointLibrary,
assetManager);
isApplicationRunning = true;
isApplicationRunning = true;
} finally {
Trace.endSection();
}
}
/**
@@ -147,15 +155,20 @@ public class DartExecutor implements BinaryMessenger {
return;
}
Trace.beginSection("DartExecutor#executeDartCallback");
Log.v(TAG, "Executing Dart callback: " + dartCallback);
flutterJNI.runBundleAndSnapshotFromLibrary(
dartCallback.pathToBundle,
dartCallback.callbackHandle.callbackName,
dartCallback.callbackHandle.callbackLibraryPath,
dartCallback.androidAssetManager);
try {
flutterJNI.runBundleAndSnapshotFromLibrary(
dartCallback.pathToBundle,
dartCallback.callbackHandle.callbackName,
dartCallback.callbackHandle.callbackLibraryPath,
dartCallback.androidAssetManager);
isApplicationRunning = true;
isApplicationRunning = true;
} finally {
Trace.endSection();
}
}
/**

View File

@@ -7,6 +7,7 @@ package io.flutter.embedding.engine.dart;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.tracing.Trace;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.plugin.common.BinaryMessenger;
@@ -150,15 +151,21 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler {
@NonNull String channel,
@Nullable ByteBuffer message,
@Nullable BinaryMessenger.BinaryReply callback) {
Trace.beginSection("DartMessenger#send on " + channel);
Log.v(TAG, "Sending message with callback over channel '" + channel + "'");
int replyId = nextReplyId++;
if (callback != null) {
pendingReplies.put(replyId, callback);
}
if (message == null) {
flutterJNI.dispatchEmptyPlatformMessage(channel, replyId);
} else {
flutterJNI.dispatchPlatformMessage(channel, message, message.position(), replyId);
try {
int replyId = nextReplyId++;
if (callback != null) {
pendingReplies.put(replyId, callback);
}
if (message == null) {
flutterJNI.dispatchEmptyPlatformMessage(channel, replyId);
} else {
flutterJNI.dispatchPlatformMessage(channel, message, message.position(), replyId);
}
} finally {
Trace.endSection();
}
}
@@ -194,6 +201,7 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler {
final DartMessengerTaskQueue taskQueue = (handlerInfo != null) ? handlerInfo.taskQueue : null;
Runnable myRunnable =
() -> {
Trace.beginSection("DartMessenger#handleMessageFromDart on " + channel);
try {
invokeHandler(handlerInfo, message, replyId);
if (message != null && message.isDirect()) {
@@ -204,6 +212,7 @@ class DartMessenger implements BinaryMessenger, PlatformMessageHandler {
} finally {
// This is deleting the data underneath the message object.
flutterJNI.cleanupMessageData(messageData);
Trace.endSection();
}
};
@NonNull

View File

@@ -19,6 +19,7 @@ import android.view.Display;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.tracing.Trace;
import io.flutter.BuildConfig;
import io.flutter.FlutterInjector;
import io.flutter.Log;
@@ -136,51 +137,63 @@ public class FlutterLoader {
throw new IllegalStateException("startInitialization must be called on the main thread");
}
// Ensure that the context is actually the application context.
final Context appContext = applicationContext.getApplicationContext();
Trace.beginSection("FlutterLoader#startInitialization");
this.settings = settings;
try {
// Ensure that the context is actually the application context.
final Context appContext = applicationContext.getApplicationContext();
initStartTimestampMillis = SystemClock.uptimeMillis();
flutterApplicationInfo = ApplicationInfoLoader.load(appContext);
this.settings = settings;
float fps;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final DisplayManager dm = appContext.getSystemService(DisplayManager.class);
final Display primaryDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
fps = primaryDisplay.getRefreshRate();
} else {
fps =
((WindowManager) appContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay()
.getRefreshRate();
}
VsyncWaiter.getInstance(fps).init();
initStartTimestampMillis = SystemClock.uptimeMillis();
flutterApplicationInfo = ApplicationInfoLoader.load(appContext);
// Use a background thread for initialization tasks that require disk access.
Callable<InitResult> initTask =
new Callable<InitResult>() {
@Override
public InitResult call() {
ResourceExtractor resourceExtractor = initResources(appContext);
float fps;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final DisplayManager dm = appContext.getSystemService(DisplayManager.class);
final Display primaryDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
fps = primaryDisplay.getRefreshRate();
} else {
fps =
((WindowManager) appContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay()
.getRefreshRate();
}
VsyncWaiter.getInstance(fps).init();
flutterJNI.loadLibrary();
// Use a background thread for initialization tasks that require disk access.
Callable<InitResult> initTask =
new Callable<InitResult>() {
@Override
public InitResult call() {
Trace.beginSection("FlutterLoader initTask");
// Prefetch the default font manager as soon as possible on a background thread.
// It helps to reduce time cost of engine setup that blocks the platform thread.
executorService.execute(() -> flutterJNI.prefetchDefaultFontManager());
try {
ResourceExtractor resourceExtractor = initResources(appContext);
if (resourceExtractor != null) {
resourceExtractor.waitForCompletion();
flutterJNI.loadLibrary();
// Prefetch the default font manager as soon as possible on a background thread.
// It helps to reduce time cost of engine setup that blocks the platform thread.
executorService.execute(() -> flutterJNI.prefetchDefaultFontManager());
if (resourceExtractor != null) {
resourceExtractor.waitForCompletion();
}
return new InitResult(
PathUtils.getFilesDir(appContext),
PathUtils.getCacheDirectory(appContext),
PathUtils.getDataDirectory(appContext));
} finally {
Trace.endSection();
}
}
return new InitResult(
PathUtils.getFilesDir(appContext),
PathUtils.getCacheDirectory(appContext),
PathUtils.getDataDirectory(appContext));
}
};
initResultFuture = executorService.submit(initTask);
};
initResultFuture = executorService.submit(initTask);
} finally {
Trace.endSection();
}
}
/**
@@ -204,6 +217,8 @@ public class FlutterLoader {
throw new IllegalStateException(
"ensureInitializationComplete must be called after startInitialization");
}
Trace.beginSection("FlutterLoader#ensureInitializationComplete");
try {
InitResult result = initResultFuture.get();
@@ -298,6 +313,8 @@ public class FlutterLoader {
} catch (Exception e) {
Log.e(TAG, "Flutter initialization failed.", e);
throw new RuntimeException(e);
} finally {
Trace.endSection();
}
}

View File

@@ -41,6 +41,7 @@ android {
testImplementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
testImplementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
testImplementation "androidx.test:core:1.4.0"
testImplementation "androidx.tracing:tracing:1.0.0"
testImplementation "com.google.android.play:core:1.8.0"
testImplementation "com.ibm.icu:icu4j:69.1"
testImplementation "org.mockito:mockito-core:3.11.2"

View File

@@ -45,4 +45,5 @@ dependencies {
implementation files(project.property('flutter_jar'))
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0-alpha01'
implementation 'androidx.tracing:tracing:1.0.0'
}

View File

@@ -63,6 +63,7 @@ dependencies {
implementation 'com.facebook.testing.screenshot:layout-hierarchy-common:0.12.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.tracing:tracing:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.2.0-alpha01'
implementation "com.squareup.leakcanary:leakcanary-android:$leakcanary_version"

View File

@@ -41,6 +41,7 @@ androidx.test.espresso:espresso-idling-resource:3.2.0=androidTestImplementationD
androidx.test:monitor:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath
androidx.test:rules:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath
androidx.test:runner:1.2.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath
androidx.tracing:tracing:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.transition:transition:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.vectordrawable:vectordrawable-animated:1.1.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath
androidx.vectordrawable:vectordrawable:1.1.0=androidTestImplementationDependenciesMetadata,debugAndroidTestCompileClasspath,debugAndroidTestImplementationDependenciesMetadata,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugImplementationDependenciesMetadata,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,implementationDependenciesMetadata,releaseCompileClasspath,releaseImplementationDependenciesMetadata,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath

View File

@@ -49,5 +49,13 @@
"androidx.annotation.UiThread",
"androidx.annotation.VisibleForTesting"
]
},
{
"url": "https://maven.google.com/androidx/tracing/tracing/1.0.0/tracing-1.0.0.aar",
"out_file_name": "androidx_tracing.aar",
"maven_dependency": "androidx.tracing:tracing:1.0.0",
"provides": [
"androidx.tracing.Trace"
]
}
]