Add traces to Android embedding (flutter/engine#29230)
This commit is contained in:
@@ -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 -----
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user