added crash logging to CameraContainerBloc

This commit is contained in:
Vadim 2024-01-27 21:41:37 +01:00
parent dc9aa7bc1d
commit 210de80bd7
5 changed files with 33 additions and 24 deletions

View file

@ -7,6 +7,7 @@ import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/analytics/analytics.dart';
import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/platform_config.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
@ -22,6 +23,7 @@ part 'mock_bloc_container_camera.dart';
class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraContainerState> {
final MeteringInteractor _meteringInteractor;
final LightmeterAnalytics _analytics;
late final _WidgetsBindingObserver _observer;
CameraController? _cameraController;
@ -42,6 +44,7 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
CameraContainerBloc(
this._meteringInteractor,
MeteringCommunicationBloc communicationBloc,
this._analytics,
) : super(
communicationBloc,
const CameraInitState(),
@ -223,8 +226,8 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
Directory(file.path).deleteSync(recursive: true);
return await evFromImage(bytes);
} catch (e) {
log(e.toString());
} catch (e, stackTrace) {
_analytics.logCrash(e, stackTrace);
return null;
}
}

View file

@ -4,6 +4,7 @@ class MockCameraContainerBloc extends CameraContainerBloc {
MockCameraContainerBloc(
super._meteringInteractor,
super.communicationBloc,
super._analytics,
);
@override
@ -72,8 +73,8 @@ class MockCameraContainerBloc extends CameraContainerBloc {
try {
final bytes = (await rootBundle.load(PlatformConfig.cameraStubImage)).buffer.asUint8List();
return await evFromImage(bytes);
} catch (e) {
log(e.toString());
} catch (e, stackTrace) {
log(e.toString(), stackTrace: stackTrace);
return null;
}
}

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:lightmeter/data/models/exposure_pair.dart';
import 'package:lightmeter/platform_config.dart';
import 'package:lightmeter/providers/services_provider.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
import 'package:lightmeter/screens/metering/components/camera_container/bloc_container_camera.dart';
import 'package:lightmeter/screens/metering/components/camera_container/event_container_camera.dart';
@ -37,10 +38,12 @@ class CameraContainerProvider extends StatelessWidget {
? MockCameraContainerBloc(
MeteringInteractorProvider.of(context),
context.read<MeteringCommunicationBloc>(),
ServicesProvider.of(context).analytics,
)
: CameraContainerBloc(
MeteringInteractorProvider.of(context),
context.read<MeteringCommunicationBloc>(),
ServicesProvider.of(context).analytics,
))
..add(const RequestPermissionEvent()),
child: CameraContainer(

View file

@ -1,27 +1,20 @@
import 'dart:developer';
import 'dart:math' as math;
import 'dart:typed_data';
import 'package:exif/exif.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
Future<double?> evFromImage(Uint8List bytes) async {
try {
final tags = await readExifFromBytes(bytes);
final iso = double.tryParse("${tags["EXIF ISOSpeedRatings"]}");
final apertureValueRatio = (tags["EXIF FNumber"]?.values as IfdRatios?)?.ratios.first;
final speedValueRatio = (tags["EXIF ExposureTime"]?.values as IfdRatios?)?.ratios.first;
if (iso == null || apertureValueRatio == null || speedValueRatio == null) {
log('Error parsing EXIF: ${tags.keys}');
return null;
}
final aperture = apertureValueRatio.numerator / apertureValueRatio.denominator;
final speed = speedValueRatio.numerator / speedValueRatio.denominator;
return log2(math.pow(aperture, 2)) - log2(speed) - log2(iso / 100);
} catch (e) {
log(e.toString());
return null;
Future<double> evFromImage(Uint8List bytes) async {
final tags = await readExifFromBytes(bytes);
final iso = double.tryParse("${tags["EXIF ISOSpeedRatings"]}");
final apertureValueRatio = (tags["EXIF FNumber"]?.values as IfdRatios?)?.ratios.first;
final speedValueRatio = (tags["EXIF ExposureTime"]?.values as IfdRatios?)?.ratios.first;
if (iso == null || apertureValueRatio == null || speedValueRatio == null) {
throw 'Error parsing EXIF: ${tags.keys}';
}
final aperture = apertureValueRatio.numerator / apertureValueRatio.denominator;
final speed = speedValueRatio.numerator / speedValueRatio.denominator;
return log2(math.pow(aperture, 2)) - log2(speed) - log2(iso / 100);
}

View file

@ -2,6 +2,7 @@ import 'package:bloc_test/bloc_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lightmeter/data/analytics/analytics.dart';
import 'package:lightmeter/interactors/metering_interactor.dart';
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart' as communication_events;
@ -18,11 +19,14 @@ class _MockMeteringCommunicationBloc
extends MockBloc<communication_events.MeteringCommunicationEvent, communication_states.MeteringCommunicationState>
implements MeteringCommunicationBloc {}
class _MockLightmeterAnalytics extends Mock implements LightmeterAnalytics {}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
late _MockMeteringInteractor meteringInteractor;
late _MockMeteringCommunicationBloc communicationBloc;
late _MockLightmeterAnalytics analytics;
late CameraContainerBloc bloc;
const cameraMethodChannel = MethodChannel('plugins.flutter.io/camera');
@ -110,16 +114,21 @@ void main() {
setUpAll(() {
meteringInteractor = _MockMeteringInteractor();
communicationBloc = _MockMeteringCommunicationBloc();
communicationBloc = _MockMeteringCommunicationBloc();
when(() => meteringInteractor.cameraEvCalibration).thenReturn(0.0);
when(meteringInteractor.quickVibration).thenAnswer((_) async {});
analytics = _MockLightmeterAnalytics();
registerFallbackValue(StackTrace.empty);
when(() => analytics.logCrash(any<dynamic>(), any<StackTrace>())).thenAnswer((_) async {});
});
setUp(() {
bloc = CameraContainerBloc(
meteringInteractor,
communicationBloc,
analytics,
);
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(cameraMethodChannel, cameraMethodCallSuccessHandler);