diff --git a/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FirebasePerformancePlugin.java b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FirebasePerformancePlugin.java index 50dc0ada04aa..99a1d82d06e1 100644 --- a/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FirebasePerformancePlugin.java +++ b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FirebasePerformancePlugin.java @@ -5,160 +5,53 @@ package io.flutter.plugins.firebaseperformance; import android.util.SparseArray; -import com.google.firebase.perf.FirebasePerformance; -import com.google.firebase.perf.metrics.HttpMetric; -import com.google.firebase.perf.metrics.Trace; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.MethodChannel.MethodCallHandler; -import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.Registrar; -import java.util.Map; /** FirebasePerformancePlugin */ -public class FirebasePerformancePlugin implements MethodCallHandler { - private FirebasePerformance firebasePerformance; +public class FirebasePerformancePlugin implements MethodChannel.MethodCallHandler { + private static final String CHANNEL_NAME = "plugins.flutter.io/firebase_performance"; - private final SparseArray traces = new SparseArray<>(); - private final SparseArray httpMetrics = new SparseArray<>(); + private static final SparseArray handlers = new SparseArray<>(); public static void registerWith(Registrar registrar) { - final MethodChannel channel = - new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_performance"); + final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL_NAME); channel.setMethodCallHandler(new FirebasePerformancePlugin()); } - private FirebasePerformancePlugin() { - firebasePerformance = FirebasePerformance.getInstance(); - } - @Override - public void onMethodCall(MethodCall call, Result result) { - switch (call.method) { - case "FirebasePerformance#isPerformanceCollectionEnabled": - result.success(firebasePerformance.isPerformanceCollectionEnabled()); - break; - case "FirebasePerformance#setPerformanceCollectionEnabled": - final boolean enabled = (boolean) call.arguments; - firebasePerformance.setPerformanceCollectionEnabled(enabled); - result.success(null); - break; - case "Trace#start": - handleTraceStart(call, result); - break; - case "Trace#stop": - handleTraceStop(call, result); - break; - case "HttpMetric#start": - handleHttpMetricStart(call, result); - break; - case "HttpMetric#stop": - handleHttpMetricStop(call, result); - break; - default: + public void onMethodCall(MethodCall call, MethodChannel.Result result) { + if (call.method.equals("FirebasePerformance#instance")) { + FlutterFirebasePerformance.getInstance(call, result); + } else { + final MethodChannel.MethodCallHandler handler = getHandler(call); + + if (handler != null) { + handler.onMethodCall(call, result); + } else { result.notImplemented(); + } } } - private void handleTraceStart(MethodCall call, Result result) { - Integer handle = call.argument("handle"); - String name = call.argument("name"); - - Trace trace = firebasePerformance.newTrace(name); - - traces.put(handle, trace); - - trace.start(); - result.success(null); - } - - private void handleTraceStop(MethodCall call, Result result) { - Integer handle = call.argument("handle"); - Trace trace = traces.get(handle); - - Map metrics = call.argument("metrics"); - for (Map.Entry entry : metrics.entrySet()) { - trace.incrementMetric(entry.getKey(), entry.getValue()); - } - - Map attributes = call.argument("attributes"); - for (Map.Entry entry : attributes.entrySet()) { - trace.putAttribute(entry.getKey(), entry.getValue()); + static void addHandler(final int handle, final MethodChannel.MethodCallHandler handler) { + if (handlers.get(handle) != null) { + final String message = String.format("Object for handle already exists: %s", handle); + throw new IllegalArgumentException(message); } - trace.stop(); - traces.remove(handle); - result.success(null); + handlers.put(handle, handler); } - private void handleHttpMetricStart(MethodCall call, Result result) { - Integer handle = call.argument("handle"); - String url = call.argument("url"); - - int httpMethod = call.argument("httpMethod"); - String httpMethodStr; - switch (httpMethod) { - case 0: - httpMethodStr = FirebasePerformance.HttpMethod.CONNECT; - break; - case 1: - httpMethodStr = FirebasePerformance.HttpMethod.DELETE; - break; - case 2: - httpMethodStr = FirebasePerformance.HttpMethod.GET; - break; - case 3: - httpMethodStr = FirebasePerformance.HttpMethod.HEAD; - break; - case 4: - httpMethodStr = FirebasePerformance.HttpMethod.OPTIONS; - break; - case 5: - httpMethodStr = FirebasePerformance.HttpMethod.PATCH; - break; - case 6: - httpMethodStr = FirebasePerformance.HttpMethod.POST; - break; - case 7: - httpMethodStr = FirebasePerformance.HttpMethod.PUT; - break; - case 8: - httpMethodStr = FirebasePerformance.HttpMethod.TRACE; - break; - default: - httpMethodStr = null; - break; - } - - HttpMetric metric = firebasePerformance.newHttpMetric(url, httpMethodStr); - - httpMetrics.put(handle, metric); - - metric.start(); - result.success(null); + static void removeHandler(final int handle) { + handlers.remove(handle); } - private void handleHttpMetricStop(MethodCall call, Result result) { - Integer handle = call.argument("handle"); - HttpMetric metric = httpMetrics.get(handle); - - Integer httpResponseCode = call.argument("httpResponseCode"); - Number requestPayloadSize = call.argument("requestPayloadSize"); - String responseContentType = call.argument("responseContentType"); - Number responsePayloadSize = call.argument("responsePayloadSize"); - - if (requestPayloadSize != null) metric.setRequestPayloadSize(requestPayloadSize.longValue()); - if (httpResponseCode != null) metric.setHttpResponseCode(httpResponseCode); - if (responseContentType != null) metric.setResponseContentType(responseContentType); - if (responsePayloadSize != null) metric.setResponsePayloadSize(responsePayloadSize.longValue()); - - Map attributes = call.argument("attributes"); - for (Map.Entry entry : attributes.entrySet()) { - metric.putAttribute(entry.getKey(), entry.getValue()); - } + private static MethodChannel.MethodCallHandler getHandler(final MethodCall call) { + final Integer handle = call.argument("handle"); - metric.stop(); - httpMetrics.remove(handle); - result.success(null); + if (handle == null) return null; + return handlers.get(handle); } } diff --git a/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterFirebasePerformance.java b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterFirebasePerformance.java new file mode 100644 index 000000000000..ce04044a1ea8 --- /dev/null +++ b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterFirebasePerformance.java @@ -0,0 +1,107 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebaseperformance; + +import com.google.firebase.perf.FirebasePerformance; +import com.google.firebase.perf.metrics.HttpMetric; +import com.google.firebase.perf.metrics.Trace; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +public class FlutterFirebasePerformance implements MethodChannel.MethodCallHandler { + private static String parseHttpMethod(String httpMethod) { + switch (httpMethod) { + case "HttpMethod.Connect": + return FirebasePerformance.HttpMethod.CONNECT; + case "HttpMethod.Delete": + return FirebasePerformance.HttpMethod.DELETE; + case "HttpMethod.Get": + return FirebasePerformance.HttpMethod.GET; + case "HttpMethod.Head": + return FirebasePerformance.HttpMethod.HEAD; + case "HttpMethod.Options": + return FirebasePerformance.HttpMethod.OPTIONS; + case "HttpMethod.Patch": + return FirebasePerformance.HttpMethod.PATCH; + case "HttpMethod.Post": + return FirebasePerformance.HttpMethod.POST; + case "HttpMethod.Put": + return FirebasePerformance.HttpMethod.PUT; + case "HttpMethod.Trace": + return FirebasePerformance.HttpMethod.TRACE; + default: + throw new IllegalArgumentException(String.format("No HttpMethod for: %s", httpMethod)); + } + } + + private final FirebasePerformance performance; + + @SuppressWarnings("ConstantConditions") + static void getInstance(MethodCall call, MethodChannel.Result result) { + final Integer handle = call.argument("handle"); + FirebasePerformancePlugin.addHandler(handle, new FlutterFirebasePerformance()); + result.success(null); + } + + private FlutterFirebasePerformance() { + this.performance = FirebasePerformance.getInstance(); + } + + @Override + public void onMethodCall(MethodCall call, MethodChannel.Result result) { + switch (call.method) { + case "FirebasePerformance#isPerformanceCollectionEnabled": + isPerformanceCollectionEnabled(result); + break; + case "FirebasePerformance#setPerformanceCollectionEnabled": + setPerformanceCollectionEnabled(call, result); + break; + case "FirebasePerformance#newTrace": + newTrace(call, result); + break; + case "FirebasePerformance#newHttpMetric": + newHttpMetric(call, result); + break; + default: + result.notImplemented(); + } + } + + private void isPerformanceCollectionEnabled(MethodChannel.Result result) { + result.success(performance.isPerformanceCollectionEnabled()); + } + + @SuppressWarnings("ConstantConditions") + private void setPerformanceCollectionEnabled(MethodCall call, MethodChannel.Result result) { + final Boolean enable = call.argument("enable"); + performance.setPerformanceCollectionEnabled(enable); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void newTrace(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + final Trace trace = performance.newTrace(name); + + final Integer handle = call.argument("traceHandle"); + FirebasePerformancePlugin.addHandler(handle, new FlutterTrace(trace)); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void newHttpMetric(MethodCall call, MethodChannel.Result result) { + final String url = call.argument("url"); + final String httpMethod = call.argument("httpMethod"); + + final HttpMetric metric = performance.newHttpMetric(url, parseHttpMethod(httpMethod)); + + final Integer handle = call.argument("httpMetricHandle"); + FirebasePerformancePlugin.addHandler(handle, new FlutterHttpMetric(metric)); + + result.success(null); + } +} diff --git a/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterHttpMetric.java b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterHttpMetric.java new file mode 100644 index 000000000000..2e2f2e6e4ed3 --- /dev/null +++ b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterHttpMetric.java @@ -0,0 +1,116 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebaseperformance; + +import com.google.firebase.perf.metrics.HttpMetric; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +public class FlutterHttpMetric implements MethodChannel.MethodCallHandler { + private final HttpMetric httpMetric; + + FlutterHttpMetric(final HttpMetric metric) { + this.httpMetric = metric; + } + + @Override + public void onMethodCall(MethodCall call, MethodChannel.Result result) { + switch (call.method) { + case "HttpMetric#start": + start(result); + break; + case "HttpMetric#stop": + stop(call, result); + break; + case "HttpMetric#httpResponseCode": + setHttpResponseCode(call, result); + break; + case "HttpMetric#requestPayloadSize": + setRequestPayloadSize(call, result); + break; + case "HttpMetric#responseContentType": + setResponseContentType(call, result); + break; + case "HttpMetric#responsePayloadSize": + setResponsePayloadSize(call, result); + break; + case "PerformanceAttributes#putAttribute": + putAttribute(call, result); + break; + case "PerformanceAttributes#removeAttribute": + removeAttribute(call, result); + break; + case "PerformanceAttributes#getAttributes": + getAttributes(result); + break; + default: + result.notImplemented(); + } + } + + private void start(MethodChannel.Result result) { + httpMetric.start(); + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void stop(MethodCall call, MethodChannel.Result result) { + httpMetric.stop(); + + final Integer handle = call.argument("handle"); + FirebasePerformancePlugin.removeHandler(handle); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void setHttpResponseCode(MethodCall call, MethodChannel.Result result) { + final Integer httpResponseCode = call.argument("httpResponseCode"); + httpMetric.setHttpResponseCode(httpResponseCode); + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void setRequestPayloadSize(MethodCall call, MethodChannel.Result result) { + final Number payloadSize = call.argument("requestPayloadSize"); + httpMetric.setRequestPayloadSize(payloadSize.longValue()); + result.success(null); + } + + private void setResponseContentType(MethodCall call, MethodChannel.Result result) { + final String contentType = call.argument("responseContentType"); + httpMetric.setResponseContentType(contentType); + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void setResponsePayloadSize(MethodCall call, MethodChannel.Result result) { + final Number payloadSize = call.argument("responsePayloadSize"); + httpMetric.setResponsePayloadSize(payloadSize.longValue()); + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void putAttribute(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + final String value = call.argument("value"); + + httpMetric.putAttribute(name, value); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void removeAttribute(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + httpMetric.removeAttribute(name); + + result.success(null); + } + + private void getAttributes(MethodChannel.Result result) { + result.success(httpMetric.getAttributes()); + } +} diff --git a/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterTrace.java b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterTrace.java new file mode 100644 index 000000000000..0bcb54f34834 --- /dev/null +++ b/packages/firebase_performance/android/src/main/java/io/flutter/plugins/firebaseperformance/FlutterTrace.java @@ -0,0 +1,111 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.firebaseperformance; + +import com.google.firebase.perf.metrics.Trace; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +public class FlutterTrace implements MethodChannel.MethodCallHandler { + private final Trace trace; + + FlutterTrace(final Trace trace) { + this.trace = trace; + } + + @Override + public void onMethodCall(MethodCall call, MethodChannel.Result result) { + switch (call.method) { + case "Trace#start": + start(result); + break; + case "Trace#stop": + stop(call, result); + break; + case "Trace#setMetric": + setMetric(call, result); + break; + case "Trace#incrementMetric": + incrementMetric(call, result); + break; + case "Trace#getMetric": + getMetric(call, result); + break; + case "PerformanceAttributes#putAttribute": + putAttribute(call, result); + break; + case "PerformanceAttributes#removeAttribute": + removeAttribute(call, result); + break; + case "PerformanceAttributes#getAttributes": + getAttributes(result); + break; + default: + result.notImplemented(); + } + } + + private void start(MethodChannel.Result result) { + trace.start(); + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void stop(MethodCall call, MethodChannel.Result result) { + trace.stop(); + + final Integer handle = call.argument("handle"); + FirebasePerformancePlugin.removeHandler(handle); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void setMetric(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + final Number value = call.argument("value"); + trace.putMetric(name, value.longValue()); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void incrementMetric(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + final Number value = call.argument("value"); + trace.incrementMetric(name, value.longValue()); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void getMetric(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + + result.success(trace.getLongMetric(name)); + } + + @SuppressWarnings("ConstantConditions") + private void putAttribute(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + final String value = call.argument("value"); + + trace.putAttribute(name, value); + + result.success(null); + } + + @SuppressWarnings("ConstantConditions") + private void removeAttribute(MethodCall call, MethodChannel.Result result) { + final String name = call.argument("name"); + trace.removeAttribute(name); + + result.success(null); + } + + private void getAttributes(MethodChannel.Result result) { + result.success(trace.getAttributes()); + } +}