Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Upgraded Crashlytics to v2 of Flutter Plugins.
  • Loading branch information
gaaclarke committed Nov 4, 2019
commit 42960058487a7ebb43731bd3cbf44bd9d051930d
26 changes: 26 additions & 0 deletions packages/firebase_crashlytics/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,29 @@ dependencies {
}

apply from: file("./user-agent.gradle")

// TODO(<github-username>): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348
afterEvaluate {
def containsEmbeddingDependencies = false
for (def configuration : configurations.all) {
for (def dependency : configuration.dependencies) {
if (dependency.group == 'io.flutter' &&
dependency.name.startsWith('flutter_embedding') &&
dependency.isTransitive())
{
containsEmbeddingDependencies = true
break
}
}
}
if (!containsEmbeddingDependencies) {
android {
dependencies {
def lifecycle_version = "1.1.1"
compileOnly "android.arch.lifecycle:runtime:$lifecycle_version"
compileOnly "android.arch.lifecycle:common:$lifecycle_version"
compileOnly "android.arch.lifecycle:common-java8:$lifecycle_version"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@

package io.flutter.plugins.firebase.crashlytics.firebasecrashlytics;

import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
import com.crashlytics.android.Crashlytics;
import io.fabric.sdk.android.Fabric;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
Expand All @@ -17,21 +21,36 @@
import java.util.Map;

/** FirebaseCrashlyticsPlugin */
public class FirebaseCrashlyticsPlugin implements MethodCallHandler {

public class FirebaseCrashlyticsPlugin
implements FlutterPlugin, MethodCallHandler {
public static final String TAG = "CrashlyticsPlugin";

/** Plugin registration. */
public static void registerWith(Registrar registrar) {
final MethodChannel channel =
new MethodChannel(registrar.messenger(), "plugins.flutter.io/firebase_crashlytics");
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
// TODO: your plugin is now attached to a Flutter experience.
setup(binding.getBinaryMessenger(), binding.getApplicationContext());
}

@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
// TODO: your plugin is no longer attached to a Flutter experience.
}

private static void setup(BinaryMessenger binaryMessenger, Context context) {
final MethodChannel channel = new MethodChannel(
binaryMessenger, "plugins.flutter.io/firebase_crashlytics");
channel.setMethodCallHandler(new FirebaseCrashlyticsPlugin());

if (!Fabric.isInitialized()) {
Fabric.with(registrar.context(), new Crashlytics());
Fabric.with(context, new Crashlytics());
}
}

/** Plugin registration. */
public static void registerWith(Registrar registrar) {
setup(registrar.messenger(), registrar.context());
}

@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("Crashlytics#onError")) {
Expand All @@ -44,44 +63,52 @@ public void onMethodCall(MethodCall call, Result result) {
// Set keys.
List<Map<String, Object>> keys = call.argument("keys");
for (Map<String, Object> key : keys) {
switch ((String) key.get("type")) {
case "int":
Crashlytics.setInt((String) key.get("key"), (int) key.get("value"));
break;
case "double":
Crashlytics.setDouble((String) key.get("key"), (double) key.get("value"));
break;
case "string":
Crashlytics.setString((String) key.get("key"), (String) key.get("value"));
break;
case "boolean":
Crashlytics.setBool((String) key.get("key"), (boolean) key.get("value"));
break;
switch ((String)key.get("type")) {
case "int":
Crashlytics.setInt((String)key.get("key"), (int)key.get("value"));
break;
case "double":
Crashlytics.setDouble((String)key.get("key"),
(double)key.get("value"));
break;
case "string":
Crashlytics.setString((String)key.get("key"),
(String)key.get("value"));
break;
case "boolean":
Crashlytics.setBool((String)key.get("key"),
(boolean)key.get("value"));
break;
}
}

// Report crash.
String dartExceptionMessage = (String) call.argument("exception");
String dartExceptionMessage = (String)call.argument("exception");
Exception exception = new Exception(dartExceptionMessage);
List<Map<String, String>> errorElements = call.argument("stackTraceElements");
List<Map<String, String>> errorElements =
call.argument("stackTraceElements");
List<StackTraceElement> elements = new ArrayList<>();
for (Map<String, String> errorElement : errorElements) {
StackTraceElement stackTraceElement = generateStackTraceElement(errorElement);
StackTraceElement stackTraceElement =
generateStackTraceElement(errorElement);
if (stackTraceElement != null) {
elements.add(stackTraceElement);
}
}
exception.setStackTrace(elements.toArray(new StackTraceElement[elements.size()]));
exception.setStackTrace(
elements.toArray(new StackTraceElement[elements.size()]));

Crashlytics.setString("exception", (String) call.argument("exception"));
Crashlytics.setString("exception", (String)call.argument("exception"));

// Set a "reason" (to match iOS) to show where the exception was thrown.
final String context = call.argument("context");
if (context != null) Crashlytics.setString("reason", "thrown " + context);
if (context != null)
Crashlytics.setString("reason", "thrown " + context);

// Log information.
final String information = call.argument("information");
if (information != null && !information.isEmpty()) Crashlytics.log(information);
if (information != null && !information.isEmpty())
Crashlytics.log(information);

Crashlytics.logException(exception);
result.success("Error reported to Crashlytics.");
Expand All @@ -90,13 +117,13 @@ public void onMethodCall(MethodCall call, Result result) {
} else if (call.method.equals("Crashlytics#getVersion")) {
result.success(Crashlytics.getInstance().getVersion());
} else if (call.method.equals("Crashlytics#setUserEmail")) {
Crashlytics.setUserEmail((String) call.argument("email"));
Crashlytics.setUserEmail((String)call.argument("email"));
result.success(null);
} else if (call.method.equals("Crashlytics#setUserIdentifier")) {
Crashlytics.setUserIdentifier((String) call.argument("identifier"));
Crashlytics.setUserIdentifier((String)call.argument("identifier"));
result.success(null);
} else if (call.method.equals("Crashlytics#setUserName")) {
Crashlytics.setUserName((String) call.argument("name"));
Crashlytics.setUserName((String)call.argument("name"));
result.success(null);
} else {
result.notImplemented();
Expand All @@ -109,17 +136,20 @@ public void onMethodCall(MethodCall call, Result result) {
* @param errorElement Map representing the parts of a Dart error.
* @return Stack trace element to be used as part of an Exception stack trace.
*/
private StackTraceElement generateStackTraceElement(Map<String, String> errorElement) {
private StackTraceElement
generateStackTraceElement(Map<String, String> errorElement) {
try {
String fileName = errorElement.get("file");
String lineNumber = errorElement.get("line");
String className = errorElement.get("class");
String methodName = errorElement.get("method");

return new StackTraceElement(
className == null ? "" : className, methodName, fileName, Integer.parseInt(lineNumber));
return new StackTraceElement(className == null ? "" : className,
methodName, fileName,
Integer.parseInt(lineNumber));
} catch (Exception e) {
Log.e(TAG, "Unable to generate stack trace element from Dart side error.");
Log.e(TAG,
"Unable to generate stack trace element from Dart side error.");
return null;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ flutter {
}

dependencies {
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

apply plugin: 'io.fabric'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

package io.flutter.plugins.firebase.crashlytics.firebasecrashlytics;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.e2e.FlutterRunner;
import io.flutter.plugins.firebase.crashlytics.firebasecrashlyticsexample.EmbeddingV1Activity;
import org.junit.Rule;
import org.junit.runner.RunWith;

@RunWith(FlutterRunner.class)
public class EmbeddingV1ActivityTest {
@Rule
public ActivityTestRule<EmbeddingV1Activity> rule =
new ActivityTestRule<>(EmbeddingV1Activity.class);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

package io.flutter.plugins.firebase.crashlytics.firebasecrashlytics;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.e2e.FlutterRunner;
import io.flutter.plugins.firebase.crashlytics.firebasecrashlyticsexample.MainActivity;
import org.junit.Rule;
import org.junit.runner.RunWith;

@RunWith(FlutterRunner.class)
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> rule =
new ActivityTestRule<>(MainActivity.class);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
android:name="io.flutter.app.FlutterApplication"
android:label="firebase_crashlytics_example"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".EmbeddingV1Activity"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
Expand All @@ -27,9 +34,6 @@
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

package io.flutter.plugins.firebase.crashlytics.firebasecrashlyticsexample;

import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class EmbeddingV1Activity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package io.flutter.plugins.firebase.crashlytics.firebasecrashlyticsexample;

import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.firebase.crashlytics.firebasecrashlytics.FirebaseCrashlyticsPlugin;

public class MainActivity extends FlutterActivity {
// TODO(<github-username>): Remove this once v2 of GeneratedPluginRegistrant
// rolls to stable. https://github.com/flutter/flutter/issues/42694
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
public void configureFlutterEngine(FlutterEngine flutterEngine) {
flutterEngine.getPlugins().add(new FirebaseCrashlyticsPlugin());
}
}
1 change: 1 addition & 0 deletions packages/firebase_crashlytics/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies:
path: ../

dev_dependencies:
e2e: ^0.2.1
flutter_test:
sdk: flutter
flutter_driver:
Expand Down
5 changes: 3 additions & 2 deletions packages/firebase_crashlytics/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ author: Flutter Team <[email protected]>
homepage: https://github.com/FirebaseExtended/flutterfire/tree/master/packages/firebase_crashlytics

environment:
sdk: ">=2.0.0-dev.68.0 <3.0.0"
flutter: ">=1.5.0"
sdk: ">=2.0.0-dev.28.0 <3.0.0"
flutter: ">=1.9.1+hotfix.5 <2.0.0"

dependencies:
flutter:
sdk: flutter
stack_trace: ^1.9.3

dev_dependencies:
e2e: ^0.2.1
flutter_test:
sdk: flutter
test: ^1.5.1
Expand Down
11 changes: 11 additions & 0 deletions packages/firebase_crashlytics/test/firebase_crashlytics_e2e.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:e2e/e2e.dart';

void main() {
E2EWidgetsFlutterBinding.ensureInitialized();

testWidgets('some test', (WidgetTester tester) async {
// TODO: write test
expect(1, equals(2));
});
}