1
0
mirror of https://github.com/flutter/packages.git synced 2025-06-24 09:11:42 +08:00

[various] Sync lints with flutter/flutter ()

Applying the latest analysis_options.yaml from flutter/flutter to this
repo. Most fixes were auto-generated by `dart fix`.
This commit is contained in:
Michael Goderbauer
2024-01-03 15:16:49 -08:00
committed by GitHub
parent 6b2249f152
commit bb97da8ec6
282 changed files with 527 additions and 947 deletions
analysis_options.yaml
packages
animations
camera
cross_file/test
dynamic_layouts/lib/src
file_selector
file_selector_android
file_selector_web/test
flutter_adaptive_scaffold
flutter_markdown
flutter_migrate
go_router
go_router_builder
google_identity_services_web/test
google_maps_flutter
google_sign_in
image_picker
in_app_purchase
local_auth/local_auth_platform_interface
metrics_center/test
path_provider
path_provider_android/test
path_provider_windows/test
pigeon
platform
plugin_platform_interface
pointer_interceptor/pointer_interceptor
process
quick_actions
quick_actions/test
quick_actions_ios/test
rfw
shared_preferences/shared_preferences_web/example/integration_test
two_dimensional_scrollables
url_launcher
video_player
web_benchmarks
CHANGELOG.mdpubspec.yaml
testing/test_app/lib/benchmarks
webview_flutter
xdg_directories
script/tool/test

@ -1,13 +1,14 @@
# Specify analysis options. # Specify analysis options.
# #
# This file is a copy of analysis_options.yaml from flutter repo # This file is a copy of analysis_options.yaml from flutter repo
# as of 2022-07-27, but with some modifications marked with # as of 2023-12-18, but with some modifications marked with
# "DIFFERENT FROM FLUTTER/FLUTTER" below. The file is expected to # "DIFFERENT FROM FLUTTER/FLUTTER" below. The file is expected to
# be kept in sync with the master file from the flutter repo. # be kept in sync with the master file from the flutter repo.
analyzer: analyzer:
language: language:
strict-casts: true strict-casts: true
strict-inference: true
strict-raw-types: true strict-raw-types: true
errors: errors:
# allow self-reference to deprecated members (we do this because otherwise we have # allow self-reference to deprecated members (we do this because otherwise we have
@ -21,11 +22,10 @@ analyzer:
linter: linter:
rules: rules:
# This list is derived from the list of all available lints located at # This list is derived from the list of all available lints located at
# https://github.com/dart-lang/linter/blob/master/example/all.yaml # https://github.com/dart-lang/linter/blob/main/example/all.yaml
- always_declare_return_types - always_declare_return_types
- always_put_control_body_on_new_line - always_put_control_body_on_new_line
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
- always_require_non_null_named_parameters
- always_specify_types - always_specify_types
# - always_use_package_imports # we do this commonly # - always_use_package_imports # we do this commonly
- annotate_overrides - annotate_overrides
@ -33,7 +33,7 @@ linter:
- avoid_bool_literals_in_conditional_expressions - avoid_bool_literals_in_conditional_expressions
# - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023 # - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023
# - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023 # - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023
- avoid_classes_with_only_static_members # - avoid_classes_with_only_static_members # we do this commonly for `abstract final class`es
- avoid_double_and_int_checks - avoid_double_and_int_checks
- avoid_dynamic_calls - avoid_dynamic_calls
- avoid_empty_else - avoid_empty_else
@ -42,7 +42,7 @@ linter:
- avoid_field_initializers_in_const_classes - avoid_field_initializers_in_const_classes
# - avoid_final_parameters # incompatible with prefer_final_parameters # - avoid_final_parameters # incompatible with prefer_final_parameters
- avoid_function_literals_in_foreach_calls - avoid_function_literals_in_foreach_calls
- avoid_implementing_value_types # - avoid_implementing_value_types # see https://github.com/dart-lang/linter/issues/4558
- avoid_init_to_null - avoid_init_to_null
- avoid_js_rounded_ints - avoid_js_rounded_ints
# - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to
@ -54,8 +54,6 @@ linter:
- avoid_relative_lib_imports - avoid_relative_lib_imports
- avoid_renaming_method_parameters - avoid_renaming_method_parameters
- avoid_return_types_on_setters - avoid_return_types_on_setters
- avoid_returning_null
- avoid_returning_null_for_future
- avoid_returning_null_for_void - avoid_returning_null_for_void
# - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives # - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives
- avoid_setters_without_getters - avoid_setters_without_getters
@ -77,17 +75,19 @@ linter:
- cast_nullable_to_non_nullable - cast_nullable_to_non_nullable
# - close_sinks # not reliable enough # - close_sinks # not reliable enough
- collection_methods_unrelated_type - collection_methods_unrelated_type
# - combinators_ordering # DIFFERENT FROM FLUTTER/FLUTTER: This isn't available on stable yet. - combinators_ordering
# - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142
- conditional_uri_does_not_exist - conditional_uri_does_not_exist
# - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
- control_flow_in_finally - control_flow_in_finally
- curly_braces_in_flow_control_structures - curly_braces_in_flow_control_structures
- dangling_library_doc_comments
- depend_on_referenced_packages - depend_on_referenced_packages
- deprecated_consistency - deprecated_consistency
# - deprecated_member_use_from_same_package # we allow self-references to deprecated members
# - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib)
- directives_ordering - directives_ordering
# - discarded_futures # not yet tested # - discarded_futures # too many false positives, similar to unawaited_futures
# - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic
- empty_catches - empty_catches
- empty_constructor_bodies - empty_constructor_bodies
@ -98,21 +98,29 @@ linter:
- flutter_style_todos - flutter_style_todos
- hash_and_equals - hash_and_equals
- implementation_imports - implementation_imports
- implicit_call_tearoffs
- implicit_reopen
- invalid_case_patterns
# - join_return_with_assignment # not required by flutter style # - join_return_with_assignment # not required by flutter style
- leading_newlines_in_multiline_strings - leading_newlines_in_multiline_strings
- library_annotations
- library_names - library_names
- library_prefixes - library_prefixes
- library_private_types_in_public_api - library_private_types_in_public_api
# - lines_longer_than_80_chars # not required by flutter style # - lines_longer_than_80_chars # not required by flutter style
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453 - literal_only_boolean_expressions
# - matching_super_parameters # blocked on https://github.com/dart-lang/language/issues/2509
- missing_whitespace_between_adjacent_strings - missing_whitespace_between_adjacent_strings
- no_adjacent_strings_in_list - no_adjacent_strings_in_list
- no_default_cases - no_default_cases
- no_duplicate_case_values - no_duplicate_case_values
- no_leading_underscores_for_library_prefixes - no_leading_underscores_for_library_prefixes
- no_leading_underscores_for_local_identifiers - no_leading_underscores_for_local_identifiers
- no_literal_bool_comparisons
- no_logic_in_create_state - no_logic_in_create_state
- no_runtimeType_toString # DIFFERENT FROM FLUTTER/FLUTTER - no_runtimeType_toString # DIFFERENT FROM FLUTTER/FLUTTER
- no_self_assignments
- no_wildcard_variable_uses
- non_constant_identifier_names - non_constant_identifier_names
- noop_primitive_operations - noop_primitive_operations
- null_check_on_nullable_type_parameter - null_check_on_nullable_type_parameter
@ -137,12 +145,11 @@ linter:
# - prefer_constructors_over_static_methods # far too many false positives # - prefer_constructors_over_static_methods # far too many false positives
- prefer_contains - prefer_contains
# - prefer_double_quotes # opposite of prefer_single_quotes # - prefer_double_quotes # opposite of prefer_single_quotes
- prefer_equal_for_default_values
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
- prefer_final_fields - prefer_final_fields
- prefer_final_in_for_each - prefer_final_in_for_each
- prefer_final_locals - prefer_final_locals
# - prefer_final_parameters # we should enable this one day when it can be auto-fixed (https://github.com/dart-lang/linter/issues/3104), see also parameter_assignments # - prefer_final_parameters # adds too much verbosity
- prefer_for_elements_to_map_fromIterable - prefer_for_elements_to_map_fromIterable
- prefer_foreach - prefer_foreach
- prefer_function_declarations_over_variables - prefer_function_declarations_over_variables
@ -157,7 +164,7 @@ linter:
- prefer_is_not_empty - prefer_is_not_empty
- prefer_is_not_operator - prefer_is_not_operator
- prefer_iterable_whereType - prefer_iterable_whereType
# - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018 # - prefer_mixin # DIFFERENT FROM FLUTTER/FLUTTER: enable when v2.1.7 of plugin_platform_interface is the oldest supported version (which makes MockPlatformInterfaceMixin a mixin class)
# - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere # - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere
- prefer_null_aware_operators - prefer_null_aware_operators
- prefer_relative_imports - prefer_relative_imports
@ -168,10 +175,10 @@ linter:
- provide_deprecation_message - provide_deprecation_message
- public_member_api_docs # DIFFERENT FROM FLUTTER/FLUTTER - public_member_api_docs # DIFFERENT FROM FLUTTER/FLUTTER
- recursive_getters - recursive_getters
# - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441 # - require_trailing_commas # would be nice, but requires a lot of manual work: 10,000+ code locations would need to be reformatted by hand after bulk fix is applied
- secure_pubspec_urls - secure_pubspec_urls
- sized_box_for_whitespace - sized_box_for_whitespace
# - sized_box_shrink_expand # not yet tested - sized_box_shrink_expand
- slash_for_doc_comments - slash_for_doc_comments
- sort_child_properties_last - sort_child_properties_last
- sort_constructors_first - sort_constructors_first
@ -182,15 +189,18 @@ linter:
- tighten_type_of_initializing_formals - tighten_type_of_initializing_formals
# - type_annotate_public_apis # subset of always_specify_types # - type_annotate_public_apis # subset of always_specify_types
- type_init_formals - type_init_formals
- type_literal_in_constant_pattern
- unawaited_futures # DIFFERENT FROM FLUTTER/FLUTTER: It's disabled there for "too many false positives"; that's not an issue here, and missing awaits have caused production issues in plugins. - unawaited_futures # DIFFERENT FROM FLUTTER/FLUTTER: It's disabled there for "too many false positives"; that's not an issue here, and missing awaits have caused production issues in plugins.
- unnecessary_await_in_return - unnecessary_await_in_return
- unnecessary_brace_in_string_interps - unnecessary_brace_in_string_interps
- unnecessary_breaks
- unnecessary_const - unnecessary_const
- unnecessary_constructor_name - unnecessary_constructor_name
# - unnecessary_final # conflicts with prefer_final_locals # - unnecessary_final # conflicts with prefer_final_locals
- unnecessary_getters_setters - unnecessary_getters_setters
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
- unnecessary_late - unnecessary_late
- unnecessary_library_directive
- unnecessary_new - unnecessary_new
- unnecessary_null_aware_assignments - unnecessary_null_aware_assignments
- unnecessary_null_aware_operator_on_extension_on_nullable - unnecessary_null_aware_operator_on_extension_on_nullable
@ -205,12 +215,13 @@ linter:
- unnecessary_string_interpolations - unnecessary_string_interpolations
- unnecessary_this - unnecessary_this
- unnecessary_to_list_in_spreads - unnecessary_to_list_in_spreads
- unreachable_from_main
- unrelated_type_equality_checks - unrelated_type_equality_checks
- unsafe_html - unsafe_html
- use_build_context_synchronously - use_build_context_synchronously
# - use_colored_box # not yet tested - use_colored_box
# - use_decorated_box # not yet tested # - use_decorated_box # leads to bugs: DecoratedBox and Container are not equivalent (Container inserts extra padding)
# - use_enums # not yet tested - use_enums
- use_full_hex_values_for_flutter_colors - use_full_hex_values_for_flutter_colors
- use_function_type_syntax_for_parameters - use_function_type_syntax_for_parameters
- use_if_null_to_convert_nulls_to_bools - use_if_null_to_convert_nulls_to_bools
@ -222,6 +233,7 @@ linter:
- use_rethrow_when_possible - use_rethrow_when_possible
- use_setters_to_change_properties - use_setters_to_change_properties
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
- use_string_in_part_of_directives
- use_super_parameters - use_super_parameters
- use_test_throws_matchers - use_test_throws_matchers
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review

@ -1,3 +1,7 @@
## 2.0.11
* Fixes new lint warnings.
## 2.0.10 ## 2.0.10
* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.

@ -312,7 +312,7 @@ class _ExampleCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: Container( child: ColoredBox(
color: Colors.black38, color: Colors.black38,
child: Center( child: Center(
child: Image.asset( child: Image.asset(

@ -79,7 +79,7 @@ class _ExampleCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: Container( child: ColoredBox(
color: Colors.black26, color: Colors.black26,
child: Padding( child: Padding(
padding: const EdgeInsets.all(30.0), padding: const EdgeInsets.all(30.0),

@ -201,7 +201,7 @@ class FadeThroughTransition extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return _ZoomedFadeInFadeOut( return _ZoomedFadeInFadeOut(
animation: animation, animation: animation,
child: Container( child: ColoredBox(
color: fillColor ?? Theme.of(context).canvasColor, color: fillColor ?? Theme.of(context).canvasColor,
child: _ZoomedFadeInFadeOut( child: _ZoomedFadeInFadeOut(
animation: ReverseAnimation(secondaryAnimation), animation: ReverseAnimation(secondaryAnimation),

@ -604,10 +604,8 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
switch (status) { switch (status) {
case AnimationStatus.dismissed: case AnimationStatus.dismissed:
_toggleHideable(hide: false); _toggleHideable(hide: false);
break;
case AnimationStatus.completed: case AnimationStatus.completed:
_toggleHideable(hide: true); _toggleHideable(hide: true);
break;
case AnimationStatus.forward: case AnimationStatus.forward:
case AnimationStatus.reverse: case AnimationStatus.reverse:
break; break;
@ -699,11 +697,9 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
case AnimationStatus.completed: case AnimationStatus.completed:
case AnimationStatus.dismissed: case AnimationStatus.dismissed:
isInProgress = false; isInProgress = false;
break;
case AnimationStatus.forward: case AnimationStatus.forward:
case AnimationStatus.reverse: case AnimationStatus.reverse:
isInProgress = true; isInProgress = true;
break;
case null: case null:
break; break;
} }
@ -711,11 +707,9 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
case AnimationStatus.completed: case AnimationStatus.completed:
case AnimationStatus.dismissed: case AnimationStatus.dismissed:
wasInProgress = false; wasInProgress = false;
break;
case AnimationStatus.forward: case AnimationStatus.forward:
case AnimationStatus.reverse: case AnimationStatus.reverse:
wasInProgress = true; wasInProgress = true;
break;
case null: case null:
break; break;
} }
@ -769,7 +763,6 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
openOpacityTween = _openOpacityTween; openOpacityTween = _openOpacityTween;
colorTween = _colorTween; colorTween = _colorTween;
scrimTween = _scrimFadeInTween; scrimTween = _scrimFadeInTween;
break;
case AnimationStatus.reverse: case AnimationStatus.reverse:
if (_transitionWasInterrupted) { if (_transitionWasInterrupted) {
closedOpacityTween = _closedOpacityTween; closedOpacityTween = _closedOpacityTween;
@ -782,10 +775,8 @@ class _OpenContainerRoute<T> extends ModalRoute<T> {
openOpacityTween = _openOpacityTween.flipped; openOpacityTween = _openOpacityTween.flipped;
colorTween = _colorTween.flipped; colorTween = _colorTween.flipped;
scrimTween = _scrimFadeOutTween; scrimTween = _scrimFadeOutTween;
break;
case AnimationStatus.completed: case AnimationStatus.completed:
assert(false); // Unreachable. assert(false); // Unreachable.
break;
} }
assert(colorTween != null); assert(colorTween != null);
assert(closedOpacityTween != null); assert(closedOpacityTween != null);

@ -410,7 +410,7 @@ class _ExitTransition extends StatelessWidget {
return FadeTransition( return FadeTransition(
opacity: _fadeOutTransition.animate(animation), opacity: _fadeOutTransition.animate(animation),
child: Container( child: ColoredBox(
color: fillColor, color: fillColor,
child: AnimatedBuilder( child: AnimatedBuilder(
animation: animation, animation: animation,
@ -432,7 +432,7 @@ class _ExitTransition extends StatelessWidget {
return FadeTransition( return FadeTransition(
opacity: _fadeOutTransition.animate(animation), opacity: _fadeOutTransition.animate(animation),
child: Container( child: ColoredBox(
color: fillColor, color: fillColor,
child: AnimatedBuilder( child: AnimatedBuilder(
animation: animation, animation: animation,
@ -449,7 +449,7 @@ class _ExitTransition extends StatelessWidget {
case SharedAxisTransitionType.scaled: case SharedAxisTransitionType.scaled:
return FadeTransition( return FadeTransition(
opacity: _fadeOutTransition.animate(animation), opacity: _fadeOutTransition.animate(animation),
child: Container( child: ColoredBox(
color: fillColor, color: fillColor,
child: ScaleTransition( child: ScaleTransition(
scale: (!reverse ? _scaleUpTransition : _scaleDownTransition) scale: (!reverse ? _scaleUpTransition : _scaleDownTransition)

@ -2,7 +2,7 @@ name: animations
description: Fancy pre-built animations that can easily be integrated into any Flutter application. description: Fancy pre-built animations that can easily be integrated into any Flutter application.
repository: https://github.com/flutter/packages/tree/main/packages/animations repository: https://github.com/flutter/packages/tree/main/packages/animations
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+animations%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+animations%22
version: 2.0.10 version: 2.0.11
environment: environment:
sdk: ">=3.2.0 <4.0.0" sdk: ">=3.2.0 <4.0.0"

@ -522,12 +522,12 @@ void main() {
expect(find.text(bottomRoute), findsOneWidget); expect(find.text(bottomRoute), findsOneWidget);
Finder fillContainerFinder = find Finder fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/')), of: find.byKey(const ValueKey<String?>('/')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, expect(tester.widget<ColoredBox>(fillContainerFinder).color,
defaultFillColor); defaultFillColor);
navigator.currentState!.pushNamed(topRoute); navigator.currentState!.pushNamed(topRoute);
@ -536,12 +536,12 @@ void main() {
fillContainerFinder = find fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/a')), of: find.byKey(const ValueKey<String?>('/a')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, expect(tester.widget<ColoredBox>(fillContainerFinder).color,
defaultFillColor); defaultFillColor);
}); });
@ -561,12 +561,13 @@ void main() {
expect(find.text(bottomRoute), findsOneWidget); expect(find.text(bottomRoute), findsOneWidget);
Finder fillContainerFinder = find Finder fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/')), of: find.byKey(const ValueKey<String?>('/')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green); expect(
tester.widget<ColoredBox>(fillContainerFinder).color, Colors.green);
navigator.currentState!.pushNamed(topRoute); navigator.currentState!.pushNamed(topRoute);
await tester.pump(); await tester.pump();
@ -574,12 +575,13 @@ void main() {
fillContainerFinder = find fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/a')), of: find.byKey(const ValueKey<String?>('/a')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green); expect(
tester.widget<ColoredBox>(fillContainerFinder).color, Colors.green);
}); });
testWidgets('should keep state', (WidgetTester tester) async { testWidgets('should keep state', (WidgetTester tester) async {
@ -1165,12 +1167,12 @@ void main() {
expect(find.text(bottomRoute), findsOneWidget); expect(find.text(bottomRoute), findsOneWidget);
Finder fillContainerFinder = find Finder fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/')), of: find.byKey(const ValueKey<String?>('/')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, expect(tester.widget<ColoredBox>(fillContainerFinder).color,
defaultFillColor); defaultFillColor);
navigator.currentState!.pushNamed(topRoute); navigator.currentState!.pushNamed(topRoute);
@ -1179,12 +1181,12 @@ void main() {
fillContainerFinder = find fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/a')), of: find.byKey(const ValueKey<String?>('/a')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, expect(tester.widget<ColoredBox>(fillContainerFinder).color,
defaultFillColor); defaultFillColor);
}); });
@ -1204,12 +1206,13 @@ void main() {
expect(find.text(bottomRoute), findsOneWidget); expect(find.text(bottomRoute), findsOneWidget);
Finder fillContainerFinder = find Finder fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/')), of: find.byKey(const ValueKey<String?>('/')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green); expect(
tester.widget<ColoredBox>(fillContainerFinder).color, Colors.green);
navigator.currentState!.pushNamed(topRoute); navigator.currentState!.pushNamed(topRoute);
await tester.pump(); await tester.pump();
@ -1217,12 +1220,13 @@ void main() {
fillContainerFinder = find fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/a')), of: find.byKey(const ValueKey<String?>('/a')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green); expect(
tester.widget<ColoredBox>(fillContainerFinder).color, Colors.green);
}); });
testWidgets('should keep state', (WidgetTester tester) async { testWidgets('should keep state', (WidgetTester tester) async {
@ -1701,12 +1705,12 @@ void main() {
expect(find.text(bottomRoute), findsOneWidget); expect(find.text(bottomRoute), findsOneWidget);
Finder fillContainerFinder = find Finder fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/')), of: find.byKey(const ValueKey<String?>('/')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, expect(tester.widget<ColoredBox>(fillContainerFinder).color,
defaultFillColor); defaultFillColor);
navigator.currentState!.pushNamed(topRoute); navigator.currentState!.pushNamed(topRoute);
@ -1715,12 +1719,12 @@ void main() {
fillContainerFinder = find fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/a')), of: find.byKey(const ValueKey<String?>('/a')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, expect(tester.widget<ColoredBox>(fillContainerFinder).color,
defaultFillColor); defaultFillColor);
}); });
@ -1740,12 +1744,13 @@ void main() {
expect(find.text(bottomRoute), findsOneWidget); expect(find.text(bottomRoute), findsOneWidget);
Finder fillContainerFinder = find Finder fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/')), of: find.byKey(const ValueKey<String?>('/')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green); expect(
tester.widget<ColoredBox>(fillContainerFinder).color, Colors.green);
navigator.currentState!.pushNamed(topRoute); navigator.currentState!.pushNamed(topRoute);
await tester.pump(); await tester.pump();
@ -1753,12 +1758,13 @@ void main() {
fillContainerFinder = find fillContainerFinder = find
.ancestor( .ancestor(
matching: find.byType(Container), matching: find.byType(ColoredBox),
of: find.byKey(const ValueKey<String?>('/a')), of: find.byKey(const ValueKey<String?>('/a')),
) )
.last; .last;
expect(fillContainerFinder, findsOneWidget); expect(fillContainerFinder, findsOneWidget);
expect(tester.widget<Container>(fillContainerFinder).color, Colors.green); expect(
tester.widget<ColoredBox>(fillContainerFinder).color, Colors.green);
}); });
testWidgets('should keep state', (WidgetTester tester) async { testWidgets('should keep state', (WidgetTester tester) async {

@ -1,3 +1,7 @@
## 0.10.5+8
* Fixes new lint warnings.
## 0.10.5+7 ## 0.10.5+7
* Updates example app to use non-deprecated video_player method. * Updates example app to use non-deprecated video_player method.

@ -378,7 +378,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _exposureModeControlRowAnimation, sizeFactor: _exposureModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -461,7 +461,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _focusModeControlRowAnimation, sizeFactor: _focusModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -673,26 +673,20 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
switch (e.code) { switch (e.code) {
case 'CameraAccessDenied': case 'CameraAccessDenied':
showInSnackBar('You have denied camera access.'); showInSnackBar('You have denied camera access.');
break;
case 'CameraAccessDeniedWithoutPrompt': case 'CameraAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable camera access.'); showInSnackBar('Please go to Settings app to enable camera access.');
break;
case 'CameraAccessRestricted': case 'CameraAccessRestricted':
// iOS only // iOS only
showInSnackBar('Camera access is restricted.'); showInSnackBar('Camera access is restricted.');
break;
case 'AudioAccessDenied': case 'AudioAccessDenied':
showInSnackBar('You have denied audio access.'); showInSnackBar('You have denied audio access.');
break;
case 'AudioAccessDeniedWithoutPrompt': case 'AudioAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable audio access.'); showInSnackBar('Please go to Settings app to enable audio access.');
break;
case 'AudioAccessRestricted': case 'AudioAccessRestricted':
// iOS only // iOS only
showInSnackBar('Audio access is restricted.'); showInSnackBar('Audio access is restricted.');
break;
default: default:
_showCameraException(e); _showCameraException(e);
break; break;

@ -7,12 +7,12 @@ export 'package:camera_platform_interface/camera_platform_interface.dart'
CameraDescription, CameraDescription,
CameraException, CameraException,
CameraLensDirection, CameraLensDirection,
FlashMode,
ExposureMode, ExposureMode,
FlashMode,
FocusMode, FocusMode,
ImageFormatGroup,
ResolutionPreset, ResolutionPreset,
XFile, XFile;
ImageFormatGroup;
export 'src/camera_controller.dart'; export 'src/camera_controller.dart';
export 'src/camera_image.dart'; export 'src/camera_image.dart';

@ -19,7 +19,7 @@ import '../camera.dart';
// TODO(stuartmorgan): Fix this naming the next time there's a breaking change // TODO(stuartmorgan): Fix this naming the next time there's a breaking change
// to this package. // to this package.
// ignore: camel_case_types // ignore: camel_case_types
typedef onLatestImageAvailable = Function(CameraImage image); typedef onLatestImageAvailable = void Function(CameraImage image);
/// Completes with a list of available cameras. /// Completes with a list of available cameras.
/// ///
@ -530,7 +530,7 @@ class CameraController extends ValueNotifier<CameraValue> {
); );
} }
Function(CameraImageData image)? streamCallback; void Function(CameraImageData image)? streamCallback;
if (onAvailable != null) { if (onAvailable != null) {
streamCallback = (CameraImageData imageData) { streamCallback = (CameraImageData imageData) {
onAvailable(CameraImage.fromPlatformInterface(imageData)); onAvailable(CameraImage.fromPlatformInterface(imageData));

@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
Dart. Dart.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera repository: https://github.com/flutter/packages/tree/main/packages/camera/camera
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.10.5+7 version: 0.10.5+8
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -28,7 +28,7 @@ void main() {
ResolutionPreset.max); ResolutionPreset.max);
expect( expect(
() => cameraController.startImageStream((CameraImage image) => null), () => cameraController.startImageStream((CameraImage image) {}),
throwsA( throwsA(
isA<CameraException>() isA<CameraException>()
.having( .having(
@ -60,7 +60,7 @@ void main() {
cameraController.value.copyWith(isRecordingVideo: true); cameraController.value.copyWith(isRecordingVideo: true);
expect( expect(
() => cameraController.startImageStream((CameraImage image) => null), () => cameraController.startImageStream((CameraImage image) {}),
throwsA(isA<CameraException>().having( throwsA(isA<CameraException>().having(
(CameraException error) => error.description, (CameraException error) => error.description,
'A video recording is already started.', 'A video recording is already started.',
@ -81,7 +81,7 @@ void main() {
cameraController.value = cameraController.value =
cameraController.value.copyWith(isStreamingImages: true); cameraController.value.copyWith(isStreamingImages: true);
expect( expect(
() => cameraController.startImageStream((CameraImage image) => null), () => cameraController.startImageStream((CameraImage image) {}),
throwsA(isA<CameraException>().having( throwsA(isA<CameraException>().having(
(CameraException error) => error.description, (CameraException error) => error.description,
'A camera has started streaming images.', 'A camera has started streaming images.',
@ -98,7 +98,7 @@ void main() {
ResolutionPreset.max); ResolutionPreset.max);
await cameraController.initialize(); await cameraController.initialize();
await cameraController.startImageStream((CameraImage image) => null); await cameraController.startImageStream((CameraImage image) {});
expect(mockPlatform.streamCallLog, expect(mockPlatform.streamCallLog,
<String>['onStreamedFrameAvailable', 'listen']); <String>['onStreamedFrameAvailable', 'listen']);
@ -157,7 +157,7 @@ void main() {
sensorOrientation: 90), sensorOrientation: 90),
ResolutionPreset.max); ResolutionPreset.max);
await cameraController.initialize(); await cameraController.initialize();
await cameraController.startImageStream((CameraImage image) => null); await cameraController.startImageStream((CameraImage image) {});
await cameraController.stopImageStream(); await cameraController.stopImageStream();
expect(mockPlatform.streamCallLog, expect(mockPlatform.streamCallLog,
@ -175,7 +175,7 @@ void main() {
await cameraController.initialize(); await cameraController.initialize();
await cameraController.startVideoRecording( await cameraController.startVideoRecording(
onAvailable: (CameraImage image) => null); onAvailable: (CameraImage image) {});
expect( expect(
mockPlatform.streamCallLog.contains('startVideoCapturing with stream'), mockPlatform.streamCallLog.contains('startVideoCapturing with stream'),

@ -1,3 +1,7 @@
## 0.10.8+16
* Fixes new lint warnings.
## 0.10.8+15 ## 0.10.8+15
* Updates example app to use non-deprecated video_player method. * Updates example app to use non-deprecated video_player method.

@ -306,7 +306,7 @@ class CameraController extends ValueNotifier<CameraValue> {
/// Start streaming images from platform camera. /// Start streaming images from platform camera.
Future<void> startImageStream( Future<void> startImageStream(
Function(CameraImageData image) onAvailable) async { void Function(CameraImageData image) onAvailable) async {
_imageStreamSubscription = CameraPlatform.instance _imageStreamSubscription = CameraPlatform.instance
.onStreamedFrameAvailable(_cameraId) .onStreamedFrameAvailable(_cameraId)
.listen((CameraImageData imageData) { .listen((CameraImageData imageData) {
@ -327,7 +327,7 @@ class CameraController extends ValueNotifier<CameraValue> {
/// The video is returned as a [XFile] after calling [stopVideoRecording]. /// The video is returned as a [XFile] after calling [stopVideoRecording].
/// Throws a [CameraException] if the capture fails. /// Throws a [CameraException] if the capture fails.
Future<void> startVideoRecording( Future<void> startVideoRecording(
{Function(CameraImageData image)? streamCallback}) async { {void Function(CameraImageData image)? streamCallback}) async {
await CameraPlatform.instance.startVideoCapturing( await CameraPlatform.instance.startVideoCapturing(
VideoCaptureOptions(_cameraId, streamCallback: streamCallback)); VideoCaptureOptions(_cameraId, streamCallback: streamCallback));
value = value.copyWith( value = value.copyWith(

@ -381,7 +381,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _exposureModeControlRowAnimation, sizeFactor: _exposureModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -465,7 +465,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _focusModeControlRowAnimation, sizeFactor: _focusModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -677,30 +677,23 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
switch (e.code) { switch (e.code) {
case 'CameraAccessDenied': case 'CameraAccessDenied':
showInSnackBar('You have denied camera access.'); showInSnackBar('You have denied camera access.');
break;
case 'CameraAccessDeniedWithoutPrompt': case 'CameraAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable camera access.'); showInSnackBar('Please go to Settings app to enable camera access.');
break;
case 'CameraAccessRestricted': case 'CameraAccessRestricted':
// iOS only // iOS only
showInSnackBar('Camera access is restricted.'); showInSnackBar('Camera access is restricted.');
break;
case 'AudioAccessDenied': case 'AudioAccessDenied':
showInSnackBar('You have denied audio access.'); showInSnackBar('You have denied audio access.');
break;
case 'AudioAccessDeniedWithoutPrompt': case 'AudioAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable audio access.'); showInSnackBar('Please go to Settings app to enable audio access.');
break;
case 'AudioAccessRestricted': case 'AudioAccessRestricted':
// iOS only // iOS only
showInSnackBar('Audio access is restricted.'); showInSnackBar('Audio access is restricted.');
break;
case 'cameraPermission': case 'cameraPermission':
// Android & web only // Android & web only
showInSnackBar('Unknown permission error.'); showInSnackBar('Unknown permission error.');
break;
default: default:
_showCameraException(e); _showCameraException(e);
break; break;

@ -308,7 +308,7 @@ class AndroidCamera extends CameraPlatform {
} }
StreamController<CameraImageData> _installStreamController( StreamController<CameraImageData> _installStreamController(
{Function()? onListen}) { {void Function()? onListen}) {
_frameStreamController = StreamController<CameraImageData>( _frameStreamController = StreamController<CameraImageData>(
onListen: onListen ?? () {}, onListen: onListen ?? () {},
onPause: _onFrameStreamPauseResume, onPause: _onFrameStreamPauseResume,
@ -574,7 +574,6 @@ class AndroidCamera extends CameraPlatform {
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
_deviceEventStreamController.add(DeviceOrientationChangedEvent( _deviceEventStreamController.add(DeviceOrientationChangedEvent(
deserializeDeviceOrientation(arguments['orientation']! as String))); deserializeDeviceOrientation(arguments['orientation']! as String)));
break;
default: default:
throw MissingPluginException(); throw MissingPluginException();
} }
@ -598,7 +597,6 @@ class AndroidCamera extends CameraPlatform {
deserializeFocusMode(arguments['focusMode']! as String), deserializeFocusMode(arguments['focusMode']! as String),
arguments['focusPointSupported']! as bool, arguments['focusPointSupported']! as bool,
)); ));
break;
case 'resolution_changed': case 'resolution_changed':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(CameraResolutionChangedEvent( cameraEventStreamController.add(CameraResolutionChangedEvent(
@ -606,12 +604,10 @@ class AndroidCamera extends CameraPlatform {
arguments['captureWidth']! as double, arguments['captureWidth']! as double,
arguments['captureHeight']! as double, arguments['captureHeight']! as double,
)); ));
break;
case 'camera_closing': case 'camera_closing':
cameraEventStreamController.add(CameraClosingEvent( cameraEventStreamController.add(CameraClosingEvent(
cameraId, cameraId,
)); ));
break;
case 'video_recorded': case 'video_recorded':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(VideoRecordedEvent( cameraEventStreamController.add(VideoRecordedEvent(
@ -621,14 +617,12 @@ class AndroidCamera extends CameraPlatform {
? Duration(milliseconds: arguments['maxVideoDuration']! as int) ? Duration(milliseconds: arguments['maxVideoDuration']! as int)
: null, : null,
)); ));
break;
case 'error': case 'error':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(CameraErrorEvent( cameraEventStreamController.add(CameraErrorEvent(
cameraId, cameraId,
arguments['description']! as String, arguments['description']! as String,
)); ));
break;
default: default:
throw MissingPluginException(); throw MissingPluginException();
} }

@ -3,7 +3,7 @@ description: Android implementation of the camera plugin.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.10.8+15 version: 0.10.8+16
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -1,3 +1,7 @@
## 0.5.0+26
* Fixes new lint warnings.
## 0.5.0+25 ## 0.5.0+25
* Implements `lockCaptureOrientation` and `unlockCaptureOrientation`. * Implements `lockCaptureOrientation` and `unlockCaptureOrientation`.

@ -19,7 +19,7 @@ import 'camera_image.dart';
// TODO(stuartmorgan): Fix this naming the next time there's a breaking change // TODO(stuartmorgan): Fix this naming the next time there's a breaking change
// to this package. // to this package.
// ignore: camel_case_types // ignore: camel_case_types
typedef onLatestImageAvailable = Function(CameraImage image); typedef onLatestImageAvailable = void Function(CameraImage image);
/// Completes with a list of available cameras. /// Completes with a list of available cameras.
/// ///
@ -492,7 +492,7 @@ class CameraController extends ValueNotifier<CameraValue> {
); );
} }
Function(CameraImageData image)? streamCallback; void Function(CameraImageData image)? streamCallback;
if (onAvailable != null) { if (onAvailable != null) {
streamCallback = (CameraImageData imageData) { streamCallback = (CameraImageData imageData) {
onAvailable(CameraImage.fromPlatformInterface(imageData)); onAvailable(CameraImage.fromPlatformInterface(imageData));

@ -380,7 +380,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _exposureModeControlRowAnimation, sizeFactor: _exposureModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -454,7 +454,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _focusModeControlRowAnimation, sizeFactor: _focusModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -660,26 +660,20 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
switch (e.code) { switch (e.code) {
case 'CameraAccessDenied': case 'CameraAccessDenied':
showInSnackBar('You have denied camera access.'); showInSnackBar('You have denied camera access.');
break;
case 'CameraAccessDeniedWithoutPrompt': case 'CameraAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable camera access.'); showInSnackBar('Please go to Settings app to enable camera access.');
break;
case 'CameraAccessRestricted': case 'CameraAccessRestricted':
// iOS only // iOS only
showInSnackBar('Camera access is restricted.'); showInSnackBar('Camera access is restricted.');
break;
case 'AudioAccessDenied': case 'AudioAccessDenied':
showInSnackBar('You have denied audio access.'); showInSnackBar('You have denied audio access.');
break;
case 'AudioAccessDeniedWithoutPrompt': case 'AudioAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable audio access.'); showInSnackBar('Please go to Settings app to enable audio access.');
break;
case 'AudioAccessRestricted': case 'AudioAccessRestricted':
// iOS only // iOS only
showInSnackBar('Audio access is restricted.'); showInSnackBar('Audio access is restricted.');
break;
default: default:
_showCameraException(e); _showCameraException(e);
break; break;

@ -587,13 +587,10 @@ class AndroidCameraCameraX extends CameraPlatform {
switch (mode) { switch (mode) {
case FlashMode.off: case FlashMode.off:
_currentFlashMode = ImageCapture.flashModeOff; _currentFlashMode = ImageCapture.flashModeOff;
break;
case FlashMode.auto: case FlashMode.auto:
_currentFlashMode = ImageCapture.flashModeAuto; _currentFlashMode = ImageCapture.flashModeAuto;
break;
case FlashMode.always: case FlashMode.always:
_currentFlashMode = ImageCapture.flashModeOn; _currentFlashMode = ImageCapture.flashModeOn;
break;
case FlashMode.torch: case FlashMode.torch:
_currentFlashMode = null; _currentFlashMode = null;
if (torchEnabled) { if (torchEnabled) {
@ -603,7 +600,6 @@ class AndroidCameraCameraX extends CameraPlatform {
cameraControl = await camera!.getCameraControl(); cameraControl = await camera!.getCameraControl();
await cameraControl.enableTorch(true); await cameraControl.enableTorch(true);
torchEnabled = true; torchEnabled = true;
break;
} }
} }
@ -913,19 +909,14 @@ class AndroidCameraCameraX extends CameraPlatform {
switch (preset) { switch (preset) {
case ResolutionPreset.low: case ResolutionPreset.low:
boundSize = const Size(320, 240); boundSize = const Size(320, 240);
break;
case ResolutionPreset.medium: case ResolutionPreset.medium:
boundSize = const Size(720, 480); boundSize = const Size(720, 480);
break;
case ResolutionPreset.high: case ResolutionPreset.high:
boundSize = const Size(1280, 720); boundSize = const Size(1280, 720);
break;
case ResolutionPreset.veryHigh: case ResolutionPreset.veryHigh:
boundSize = const Size(1920, 1080); boundSize = const Size(1920, 1080);
break;
case ResolutionPreset.ultraHigh: case ResolutionPreset.ultraHigh:
boundSize = const Size(3840, 2160); boundSize = const Size(3840, 2160);
break;
case ResolutionPreset.max: case ResolutionPreset.max:
// Automatically set strategy to choose highest available. // Automatically set strategy to choose highest available.
resolutionStrategy = resolutionStrategy =
@ -954,19 +945,14 @@ class AndroidCameraCameraX extends CameraPlatform {
// 240p is not supported by CameraX. // 240p is not supported by CameraX.
case ResolutionPreset.medium: case ResolutionPreset.medium:
videoQuality = VideoQuality.SD; videoQuality = VideoQuality.SD;
break;
case ResolutionPreset.high: case ResolutionPreset.high:
videoQuality = VideoQuality.HD; videoQuality = VideoQuality.HD;
break;
case ResolutionPreset.veryHigh: case ResolutionPreset.veryHigh:
videoQuality = VideoQuality.FHD; videoQuality = VideoQuality.FHD;
break;
case ResolutionPreset.ultraHigh: case ResolutionPreset.ultraHigh:
videoQuality = VideoQuality.UHD; videoQuality = VideoQuality.UHD;
break;
case ResolutionPreset.max: case ResolutionPreset.max:
videoQuality = VideoQuality.highest; videoQuality = VideoQuality.highest;
break;
case null: case null:
// If no preset is specified, default to CameraX's default behavior // If no preset is specified, default to CameraX's default behavior
// for each UseCase. // for each UseCase.

@ -39,30 +39,23 @@ class CameraStateError extends JavaObject {
case CameraState.errorCameraInUse: case CameraState.errorCameraInUse:
description = description =
'The camera was already in use, possibly by a higher-priority camera client.'; 'The camera was already in use, possibly by a higher-priority camera client.';
break;
case CameraState.errorMaxCamerasInUse: case CameraState.errorMaxCamerasInUse:
description = description =
'The limit number of open cameras has been reached, and more cameras cannot be opened until other instances are closed.'; 'The limit number of open cameras has been reached, and more cameras cannot be opened until other instances are closed.';
break;
case CameraState.errorOtherRecoverableError: case CameraState.errorOtherRecoverableError:
description = description =
'The camera device has encountered a recoverable error. CameraX will attempt to recover from the error.'; 'The camera device has encountered a recoverable error. CameraX will attempt to recover from the error.';
break;
case CameraState.errorStreamConfig: case CameraState.errorStreamConfig:
description = 'Configuring the camera has failed.'; description = 'Configuring the camera has failed.';
break;
case CameraState.errorCameraDisabled: case CameraState.errorCameraDisabled:
description = description =
'The camera device could not be opened due to a device policy. Thia may be caused by a client from a background process attempting to open the camera.'; 'The camera device could not be opened due to a device policy. Thia may be caused by a client from a background process attempting to open the camera.';
break;
case CameraState.errorCameraFatalError: case CameraState.errorCameraFatalError:
description = description =
'The camera was closed due to a fatal error. This may require the Android device be shut down and restarted to restore camera function or may indicate a persistent camera hardware problem.'; 'The camera was closed due to a fatal error. This may require the Android device be shut down and restarted to restore camera function or may indicate a persistent camera hardware problem.';
break;
case CameraState.errorDoNotDisturbModeEnabled: case CameraState.errorDoNotDisturbModeEnabled:
description = description =
'The camera could not be opened because "Do Not Disturb" mode is enabled. Please disable this mode, and try opening the camera again.'; 'The camera could not be opened because "Do Not Disturb" mode is enabled. Please disable this mode, and try opening the camera again.';
break;
default: default:
description = description =
'There was an unspecified issue with the current camera state.'; 'There was an unspecified issue with the current camera state.';

@ -104,14 +104,12 @@ class _LiveDataHostApiImpl extends LiveDataHostApi {
LiveData<T> instance) async { LiveData<T> instance) async {
LiveDataSupportedTypeData? typeData; LiveDataSupportedTypeData? typeData;
switch (T) { switch (T) {
case CameraState: case const (CameraState):
typeData = typeData =
LiveDataSupportedTypeData(value: LiveDataSupportedType.cameraState); LiveDataSupportedTypeData(value: LiveDataSupportedType.cameraState);
break; case const (ZoomState):
case ZoomState:
typeData = typeData =
LiveDataSupportedTypeData(value: LiveDataSupportedType.zoomState); LiveDataSupportedTypeData(value: LiveDataSupportedType.zoomState);
break;
default: default:
throw ArgumentError(LiveData.unsupportedLiveDataTypeErrorMessage); throw ArgumentError(LiveData.unsupportedLiveDataTypeErrorMessage);
} }

@ -2,7 +2,7 @@ name: camera_android_camerax
description: Android implementation of the camera plugin using the CameraX library. description: Android implementation of the camera plugin using the CameraX library.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.5.0+25 version: 0.5.0+26
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -487,23 +487,17 @@ void main() {
switch (resolutionPreset) { switch (resolutionPreset) {
case ResolutionPreset.low: case ResolutionPreset.low:
expectedBoundSize = const Size(320, 240); expectedBoundSize = const Size(320, 240);
break;
case ResolutionPreset.medium: case ResolutionPreset.medium:
expectedBoundSize = const Size(720, 480); expectedBoundSize = const Size(720, 480);
break;
case ResolutionPreset.high: case ResolutionPreset.high:
expectedBoundSize = const Size(1280, 720); expectedBoundSize = const Size(1280, 720);
break;
case ResolutionPreset.veryHigh: case ResolutionPreset.veryHigh:
expectedBoundSize = const Size(1920, 1080); expectedBoundSize = const Size(1920, 1080);
break;
case ResolutionPreset.ultraHigh: case ResolutionPreset.ultraHigh:
expectedBoundSize = const Size(3840, 2160); expectedBoundSize = const Size(3840, 2160);
break;
case ResolutionPreset.max: case ResolutionPreset.max:
expectedResolutionStrategy = expectedResolutionStrategy =
ResolutionStrategy.detachedHighestAvailableStrategy(); ResolutionStrategy.detachedHighestAvailableStrategy();
break;
} }
// We expect the strategy to be the highest available or correspond to the // We expect the strategy to be the highest available or correspond to the
@ -629,19 +623,14 @@ void main() {
// 240p is not supported by CameraX. // 240p is not supported by CameraX.
case ResolutionPreset.medium: case ResolutionPreset.medium:
expectedVideoQuality = VideoQuality.SD; expectedVideoQuality = VideoQuality.SD;
break;
case ResolutionPreset.high: case ResolutionPreset.high:
expectedVideoQuality = VideoQuality.HD; expectedVideoQuality = VideoQuality.HD;
break;
case ResolutionPreset.veryHigh: case ResolutionPreset.veryHigh:
expectedVideoQuality = VideoQuality.FHD; expectedVideoQuality = VideoQuality.FHD;
break;
case ResolutionPreset.ultraHigh: case ResolutionPreset.ultraHigh:
expectedVideoQuality = VideoQuality.UHD; expectedVideoQuality = VideoQuality.UHD;
break;
case ResolutionPreset.max: case ResolutionPreset.max:
expectedVideoQuality = VideoQuality.highest; expectedVideoQuality = VideoQuality.highest;
break;
} }
const VideoResolutionFallbackRule expectedFallbackRule = const VideoResolutionFallbackRule expectedFallbackRule =
@ -1494,16 +1483,12 @@ void main() {
switch (flashMode) { switch (flashMode) {
case FlashMode.off: case FlashMode.off:
expectedFlashMode = ImageCapture.flashModeOff; expectedFlashMode = ImageCapture.flashModeOff;
break;
case FlashMode.auto: case FlashMode.auto:
expectedFlashMode = ImageCapture.flashModeAuto; expectedFlashMode = ImageCapture.flashModeAuto;
break;
case FlashMode.always: case FlashMode.always:
expectedFlashMode = ImageCapture.flashModeOn; expectedFlashMode = ImageCapture.flashModeOn;
break;
case FlashMode.torch: case FlashMode.torch:
expectedFlashMode = null; expectedFlashMode = null;
break;
} }
if (expectedFlashMode == null) { if (expectedFlashMode == null) {
@ -1557,11 +1542,9 @@ void main() {
case FlashMode.always: case FlashMode.always:
verify(mockCameraControl.enableTorch(false)); verify(mockCameraControl.enableTorch(false));
expect(camera.torchEnabled, isFalse); expect(camera.torchEnabled, isFalse);
break;
case FlashMode.torch: case FlashMode.torch:
verifyNever(mockCameraControl.enableTorch(true)); verifyNever(mockCameraControl.enableTorch(true));
expect(camera.torchEnabled, true); expect(camera.torchEnabled, true);
break;
} }
} }
}); });

@ -1,3 +1,7 @@
## 0.9.13+9
* Fixes new lint warnings.
## 0.9.13+8 ## 0.9.13+8
* Updates example app to use non-deprecated video_player method. * Updates example app to use non-deprecated video_player method.

@ -306,7 +306,7 @@ class CameraController extends ValueNotifier<CameraValue> {
/// Start streaming images from platform camera. /// Start streaming images from platform camera.
Future<void> startImageStream( Future<void> startImageStream(
Function(CameraImageData image) onAvailable) async { void Function(CameraImageData image) onAvailable) async {
_imageStreamSubscription = CameraPlatform.instance _imageStreamSubscription = CameraPlatform.instance
.onStreamedFrameAvailable(_cameraId) .onStreamedFrameAvailable(_cameraId)
.listen((CameraImageData imageData) { .listen((CameraImageData imageData) {
@ -327,7 +327,7 @@ class CameraController extends ValueNotifier<CameraValue> {
/// The video is returned as a [XFile] after calling [stopVideoRecording]. /// The video is returned as a [XFile] after calling [stopVideoRecording].
/// Throws a [CameraException] if the capture fails. /// Throws a [CameraException] if the capture fails.
Future<void> startVideoRecording( Future<void> startVideoRecording(
{Function(CameraImageData image)? streamCallback}) async { {void Function(CameraImageData image)? streamCallback}) async {
await CameraPlatform.instance.startVideoCapturing( await CameraPlatform.instance.startVideoCapturing(
VideoCaptureOptions(_cameraId, streamCallback: streamCallback)); VideoCaptureOptions(_cameraId, streamCallback: streamCallback));
value = value.copyWith( value = value.copyWith(

@ -381,7 +381,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _exposureModeControlRowAnimation, sizeFactor: _exposureModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -465,7 +465,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
return SizeTransition( return SizeTransition(
sizeFactor: _focusModeControlRowAnimation, sizeFactor: _focusModeControlRowAnimation,
child: ClipRect( child: ClipRect(
child: Container( child: ColoredBox(
color: Colors.grey.shade50, color: Colors.grey.shade50,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -677,30 +677,23 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
switch (e.code) { switch (e.code) {
case 'CameraAccessDenied': case 'CameraAccessDenied':
showInSnackBar('You have denied camera access.'); showInSnackBar('You have denied camera access.');
break;
case 'CameraAccessDeniedWithoutPrompt': case 'CameraAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable camera access.'); showInSnackBar('Please go to Settings app to enable camera access.');
break;
case 'CameraAccessRestricted': case 'CameraAccessRestricted':
// iOS only // iOS only
showInSnackBar('Camera access is restricted.'); showInSnackBar('Camera access is restricted.');
break;
case 'AudioAccessDenied': case 'AudioAccessDenied':
showInSnackBar('You have denied audio access.'); showInSnackBar('You have denied audio access.');
break;
case 'AudioAccessDeniedWithoutPrompt': case 'AudioAccessDeniedWithoutPrompt':
// iOS only // iOS only
showInSnackBar('Please go to Settings app to enable audio access.'); showInSnackBar('Please go to Settings app to enable audio access.');
break;
case 'AudioAccessRestricted': case 'AudioAccessRestricted':
// iOS only // iOS only
showInSnackBar('Audio access is restricted.'); showInSnackBar('Audio access is restricted.');
break;
case 'cameraPermission': case 'cameraPermission':
// Android & web only // Android & web only
showInSnackBar('Unknown permission error.'); showInSnackBar('Unknown permission error.');
break;
default: default:
_showCameraException(e); _showCameraException(e);
break; break;

@ -310,7 +310,7 @@ class AVFoundationCamera extends CameraPlatform {
} }
StreamController<CameraImageData> _createStreamController( StreamController<CameraImageData> _createStreamController(
{Function()? onListen}) { {void Function()? onListen}) {
return StreamController<CameraImageData>( return StreamController<CameraImageData>(
onListen: onListen ?? () {}, onListen: onListen ?? () {},
onPause: _onFrameStreamPauseResume, onPause: _onFrameStreamPauseResume,
@ -580,7 +580,6 @@ class AVFoundationCamera extends CameraPlatform {
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
_deviceEventStreamController.add(DeviceOrientationChangedEvent( _deviceEventStreamController.add(DeviceOrientationChangedEvent(
deserializeDeviceOrientation(arguments['orientation']! as String))); deserializeDeviceOrientation(arguments['orientation']! as String)));
break;
default: default:
throw MissingPluginException(); throw MissingPluginException();
} }
@ -604,7 +603,6 @@ class AVFoundationCamera extends CameraPlatform {
deserializeFocusMode(arguments['focusMode']! as String), deserializeFocusMode(arguments['focusMode']! as String),
arguments['focusPointSupported']! as bool, arguments['focusPointSupported']! as bool,
)); ));
break;
case 'resolution_changed': case 'resolution_changed':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(CameraResolutionChangedEvent( cameraEventStreamController.add(CameraResolutionChangedEvent(
@ -612,12 +610,10 @@ class AVFoundationCamera extends CameraPlatform {
arguments['captureWidth']! as double, arguments['captureWidth']! as double,
arguments['captureHeight']! as double, arguments['captureHeight']! as double,
)); ));
break;
case 'camera_closing': case 'camera_closing':
cameraEventStreamController.add(CameraClosingEvent( cameraEventStreamController.add(CameraClosingEvent(
cameraId, cameraId,
)); ));
break;
case 'video_recorded': case 'video_recorded':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(VideoRecordedEvent( cameraEventStreamController.add(VideoRecordedEvent(
@ -627,14 +623,12 @@ class AVFoundationCamera extends CameraPlatform {
? Duration(milliseconds: arguments['maxVideoDuration']! as int) ? Duration(milliseconds: arguments['maxVideoDuration']! as int)
: null, : null,
)); ));
break;
case 'error': case 'error':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(CameraErrorEvent( cameraEventStreamController.add(CameraErrorEvent(
cameraId, cameraId,
arguments['description']! as String, arguments['description']! as String,
)); ));
break;
default: default:
throw MissingPluginException(); throw MissingPluginException();
} }

@ -2,7 +2,7 @@ name: camera_avfoundation
description: iOS implementation of the camera plugin. description: iOS implementation of the camera plugin.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.9.13+8 version: 0.9.13+9
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -1,3 +1,7 @@
## 2.7.1
* Fixes new lint warnings.
## 2.7.0 ## 2.7.0
* Adds support for setting the image file format. See `CameraPlatform.setImageFileFormat`. * Adds support for setting the image file format. See `CameraPlatform.setImageFileFormat`.

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/// Expose XFile // Expose XFile
export 'package:cross_file/cross_file.dart'; export 'package:cross_file/cross_file.dart';
export 'src/events/camera_event.dart'; export 'src/events/camera_event.dart';

@ -314,7 +314,7 @@ class MethodChannelCamera extends CameraPlatform {
} }
StreamController<CameraImageData> _installStreamController( StreamController<CameraImageData> _installStreamController(
{Function()? onListen}) { {void Function()? onListen}) {
_frameStreamController = StreamController<CameraImageData>( _frameStreamController = StreamController<CameraImageData>(
onListen: onListen ?? () {}, onListen: onListen ?? () {},
onPause: _onFrameStreamPauseResume, onPause: _onFrameStreamPauseResume,
@ -587,7 +587,6 @@ class MethodChannelCamera extends CameraPlatform {
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
deviceEventStreamController.add(DeviceOrientationChangedEvent( deviceEventStreamController.add(DeviceOrientationChangedEvent(
deserializeDeviceOrientation(arguments['orientation']! as String))); deserializeDeviceOrientation(arguments['orientation']! as String)));
break;
default: default:
throw MissingPluginException(); throw MissingPluginException();
} }
@ -611,7 +610,6 @@ class MethodChannelCamera extends CameraPlatform {
deserializeFocusMode(arguments['focusMode']! as String), deserializeFocusMode(arguments['focusMode']! as String),
arguments['focusPointSupported']! as bool, arguments['focusPointSupported']! as bool,
)); ));
break;
case 'resolution_changed': case 'resolution_changed':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(CameraResolutionChangedEvent( cameraEventStreamController.add(CameraResolutionChangedEvent(
@ -619,12 +617,10 @@ class MethodChannelCamera extends CameraPlatform {
arguments['captureWidth']! as double, arguments['captureWidth']! as double,
arguments['captureHeight']! as double, arguments['captureHeight']! as double,
)); ));
break;
case 'camera_closing': case 'camera_closing':
cameraEventStreamController.add(CameraClosingEvent( cameraEventStreamController.add(CameraClosingEvent(
cameraId, cameraId,
)); ));
break;
case 'video_recorded': case 'video_recorded':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(VideoRecordedEvent( cameraEventStreamController.add(VideoRecordedEvent(
@ -634,14 +630,12 @@ class MethodChannelCamera extends CameraPlatform {
? Duration(milliseconds: arguments['maxVideoDuration']! as int) ? Duration(milliseconds: arguments['maxVideoDuration']! as int)
: null, : null,
)); ));
break;
case 'error': case 'error':
final Map<String, Object?> arguments = _getArgumentDictionary(call); final Map<String, Object?> arguments = _getArgumentDictionary(call);
cameraEventStreamController.add(CameraErrorEvent( cameraEventStreamController.add(CameraErrorEvent(
cameraId, cameraId,
arguments['description']! as String, arguments['description']! as String,
)); ));
break;
default: default:
throw MissingPluginException(); throw MissingPluginException();
} }

@ -32,7 +32,7 @@ class VideoCaptureOptions {
/// ///
/// If set, then each image captured by the camera will be /// If set, then each image captured by the camera will be
/// passed to this callback. /// passed to this callback.
final Function(CameraImageData image)? streamCallback; final void Function(CameraImageData image)? streamCallback;
/// Configuration options for streaming. /// Configuration options for streaming.
/// ///

@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/camera/camera
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a # NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 2.7.0 version: 2.7.1
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -1,6 +1,7 @@
## NEXT ## 0.3.2+4
* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0.
* Fixes new lint warnings.
## 0.3.2+3 ## 0.3.2+3

@ -913,5 +913,3 @@ void main() {
}); });
}); });
} }
class JSNoSuchMethodError implements Exception {}

@ -2,6 +2,4 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
library camera_web;
export 'src/camera_web.dart'; export 'src/camera_web.dart';

@ -145,21 +145,21 @@ class VideoConstraints {
/// ///
/// Specifies whether the requested camera should be facing away /// Specifies whether the requested camera should be facing away
/// or toward the user. /// or toward the user.
class CameraType { enum CameraType {
/// The camera is facing away from the user, viewing their environment.
/// This includes the back camera on a smartphone.
environment._('environment'),
/// The camera is facing toward the user.
/// This includes the front camera on a smartphone.
user._('user');
const CameraType._(this._type); const CameraType._(this._type);
final String _type; final String _type;
@override @override
String toString() => _type; String toString() => _type;
/// The camera is facing away from the user, viewing their environment.
/// This includes the back camera on a smartphone.
static const CameraType environment = CameraType._('environment');
/// The camera is facing toward the user.
/// This includes the front camera on a smartphone.
static const CameraType user = CameraType._('user');
} }
/// Indicates the direction in which the desired camera should be pointing. /// Indicates the direction in which the desired camera should be pointing.

@ -2,7 +2,7 @@ name: camera_web
description: A Flutter plugin for getting information about and controlling the camera on Web. description: A Flutter plugin for getting information about and controlling the camera on Web.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_web repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.3.2+3 version: 0.3.2+4
environment: environment:
sdk: ">=3.1.0 <4.0.0" sdk: ">=3.1.0 <4.0.0"

@ -1,6 +1,7 @@
## NEXT ## 0.2.1+9
* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0.
* Fixes new lint warnings.
## 0.2.1+8 ## 0.2.1+8

@ -397,7 +397,6 @@ class CameraWindows extends CameraPlatform {
cameraId, cameraId,
), ),
); );
break;
case 'video_recorded': case 'video_recorded':
final Map<String, Object?> arguments = final Map<String, Object?> arguments =
(call.arguments as Map<Object?, Object?>).cast<String, Object?>(); (call.arguments as Map<Object?, Object?>).cast<String, Object?>();
@ -410,7 +409,6 @@ class CameraWindows extends CameraPlatform {
maxDuration != null ? Duration(milliseconds: maxDuration) : null, maxDuration != null ? Duration(milliseconds: maxDuration) : null,
), ),
); );
break;
case 'error': case 'error':
final Map<String, Object?> arguments = final Map<String, Object?> arguments =
(call.arguments as Map<Object?, Object?>).cast<String, Object?>(); (call.arguments as Map<Object?, Object?>).cast<String, Object?>();
@ -420,7 +418,6 @@ class CameraWindows extends CameraPlatform {
arguments['description']! as String, arguments['description']! as String,
), ),
); );
break;
default: default:
throw UnimplementedError(); throw UnimplementedError();
} }

@ -2,7 +2,7 @@ name: camera_windows
description: A Flutter plugin for getting information about and controlling the camera on Windows. description: A Flutter plugin for getting information about and controlling the camera on Windows.
repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_windows repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_windows
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.2.1+8 version: 0.2.1+9
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
@TestOn('chrome') // Uses web-only Flutter SDK @TestOn('chrome') // Uses web-only Flutter SDK
library;
import 'dart:convert'; import 'dart:convert';
import 'dart:js_interop'; import 'dart:js_interop';

@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
@TestOn('vm') // Uses dart:io @TestOn('vm') // Uses dart:io
library;
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';

@ -113,10 +113,8 @@ class SliverGridWrappingTileLayout extends DynamicSliverGridLayout {
switch (scrollDirection) { switch (scrollDirection) {
case Axis.vertical: case Axis.vertical:
addedSize = currentSizeUsed + childSize.width + crossAxisSpacing; addedSize = currentSizeUsed + childSize.width + crossAxisSpacing;
break;
case Axis.horizontal: case Axis.horizontal:
addedSize = currentSizeUsed + childSize.height + mainAxisSpacing; addedSize = currentSizeUsed + childSize.height + mainAxisSpacing;
break;
} }
if (addedSize > crossAxisExtent && _model.last.currentSizeUsed > 0.0) { if (addedSize > crossAxisExtent && _model.last.currentSizeUsed > 0.0) {
@ -130,7 +128,6 @@ class SliverGridWrappingTileLayout extends DynamicSliverGridLayout {
scrollOffset + _model.last.maxSliver + mainAxisSpacing, scrollOffset + _model.last.maxSliver + mainAxisSpacing,
), ),
); );
break;
case Axis.horizontal: case Axis.horizontal:
_model.add( _model.add(
_RunMetrics( _RunMetrics(
@ -140,7 +137,6 @@ class SliverGridWrappingTileLayout extends DynamicSliverGridLayout {
scrollOffset + _model.last.maxSliver + crossAxisSpacing, scrollOffset + _model.last.maxSliver + crossAxisSpacing,
), ),
); );
break;
} }
return DynamicSliverGridGeometry( return DynamicSliverGridGeometry(
@ -158,12 +154,10 @@ class SliverGridWrappingTileLayout extends DynamicSliverGridLayout {
if (childSize.height + mainAxisSpacing > _model.last.maxSliver) { if (childSize.height + mainAxisSpacing > _model.last.maxSliver) {
_model.last.maxSliver = childSize.height + mainAxisSpacing; _model.last.maxSliver = childSize.height + mainAxisSpacing;
} }
break;
case Axis.horizontal: case Axis.horizontal:
if (childSize.width + crossAxisSpacing > _model.last.maxSliver) { if (childSize.width + crossAxisSpacing > _model.last.maxSliver) {
_model.last.maxSliver = childSize.width + crossAxisSpacing; _model.last.maxSliver = childSize.width + crossAxisSpacing;
} }
break;
} }
return DynamicSliverGridGeometry( return DynamicSliverGridGeometry(

@ -1,6 +1,7 @@
## NEXT ## 0.5.0+5
* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0.
* Fixes new lint warnings.
## 0.5.0+4 ## 0.5.0+4

@ -8,6 +8,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart'; import 'package:integration_test/integration_test.dart';
/// Entry point for integration tests that require espresso. /// Entry point for integration tests that require espresso.
@pragma('vm:entry-point')
void integrationTestMain() { void integrationTestMain() {
enableFlutterDriverExtension(); enableFlutterDriverExtension();
app.main(); app.main();

@ -13,6 +13,7 @@ import 'open_multiple_images_page.dart';
import 'open_text_page.dart'; import 'open_text_page.dart';
/// Entry point for integration tests that require espresso. /// Entry point for integration tests that require espresso.
@pragma('vm:entry-point')
void integrationTestMain() { void integrationTestMain() {
enableFlutterDriverExtension(); enableFlutterDriverExtension();
main(); main();

@ -2,7 +2,7 @@ name: file_selector_android
description: Android implementation of the file_selector package. description: Android implementation of the file_selector package.
repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_android repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
version: 0.5.0+4 version: 0.5.0+5
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
@TestOn('chrome') // web-only package. @TestOn('chrome') // web-only package.
library;
import 'package:file_selector_platform_interface/file_selector_platform_interface.dart'; import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
import 'package:file_selector_web/src/utils.dart'; import 'package:file_selector_web/src/utils.dart';

@ -1,3 +1,7 @@
## 0.1.7+2
* Fixes new lint warnings.
## 0.1.7+1 ## 0.1.7+1
* Adds pub topics to package metadata. * Adds pub topics to package metadata.

@ -156,7 +156,8 @@ return AdaptiveLayout(
}, },
leading: const Icon(Icons.menu), leading: const Icon(Icons.menu),
destinations: destinations destinations: destinations
.map((_) => AdaptiveScaffold.toRailDestination(_)) .map((NavigationDestination destination) =>
AdaptiveScaffold.toRailDestination(destination))
.toList(), .toList(),
backgroundColor: navRailTheme.backgroundColor, backgroundColor: navRailTheme.backgroundColor,
selectedIconTheme: navRailTheme.selectedIconTheme, selectedIconTheme: navRailTheme.selectedIconTheme,
@ -187,7 +188,8 @@ return AdaptiveLayout(
], ],
), ),
destinations: destinations destinations: destinations
.map((_) => AdaptiveScaffold.toRailDestination(_)) .map((NavigationDestination destination) =>
AdaptiveScaffold.toRailDestination(destination))
.toList(), .toList(),
trailing: trailingNavRail, trailing: trailingNavRail,
backgroundColor: navRailTheme.backgroundColor, backgroundColor: navRailTheme.backgroundColor,

@ -175,7 +175,8 @@ class _MyHomePageState extends State<MyHomePage> {
}, },
leading: const Icon(Icons.menu), leading: const Icon(Icons.menu),
destinations: destinations destinations: destinations
.map((_) => AdaptiveScaffold.toRailDestination(_)) .map((NavigationDestination destination) =>
AdaptiveScaffold.toRailDestination(destination))
.toList(), .toList(),
backgroundColor: navRailTheme.backgroundColor, backgroundColor: navRailTheme.backgroundColor,
selectedIconTheme: navRailTheme.selectedIconTheme, selectedIconTheme: navRailTheme.selectedIconTheme,
@ -206,7 +207,8 @@ class _MyHomePageState extends State<MyHomePage> {
], ],
), ),
destinations: destinations destinations: destinations
.map((_) => AdaptiveScaffold.toRailDestination(_)) .map((NavigationDestination destination) =>
AdaptiveScaffold.toRailDestination(destination))
.toList(), .toList(),
trailing: trailingNavRail, trailing: trailingNavRail,
backgroundColor: navRailTheme.backgroundColor, backgroundColor: navRailTheme.backgroundColor,

@ -313,8 +313,9 @@ class _MyHomePageState extends State<MyHomePage>
selectedIndex: _navigationIndex, selectedIndex: _navigationIndex,
trailing: trailingNavRail, trailing: trailingNavRail,
extended: true, extended: true,
destinations: destinations.map((_) { destinations:
return AdaptiveScaffold.toRailDestination(_); destinations.map((NavigationDestination destination) {
return AdaptiveScaffold.toRailDestination(destination);
}).toList(), }).toList(),
), ),
), ),

@ -228,7 +228,7 @@ class AdaptiveScaffold extends StatefulWidget {
final PreferredSizeWidget? appBar; final PreferredSizeWidget? appBar;
/// Callback function for when the index of a [NavigationRail] changes. /// Callback function for when the index of a [NavigationRail] changes.
final Function(int)? onSelectedIndexChange; final void Function(int)? onSelectedIndexChange;
/// The width used for the internal [NavigationRail] at the medium [Breakpoint]. /// The width used for the internal [NavigationRail] at the medium [Breakpoint].
final double navigationRailWidth; final double navigationRailWidth;
@ -267,7 +267,7 @@ class AdaptiveScaffold extends StatefulWidget {
EdgeInsetsGeometry padding = const EdgeInsets.all(8.0), EdgeInsetsGeometry padding = const EdgeInsets.all(8.0),
Widget? leading, Widget? leading,
Widget? trailing, Widget? trailing,
Function(int)? onDestinationSelected, void Function(int)? onDestinationSelected,
double? groupAlignment, double? groupAlignment,
IconThemeData? selectedIconTheme, IconThemeData? selectedIconTheme,
IconThemeData? unselectedIconTheme, IconThemeData? unselectedIconTheme,
@ -514,7 +514,8 @@ class _AdaptiveScaffoldState extends State<AdaptiveScaffold> {
trailing: widget.trailingNavRail, trailing: widget.trailingNavRail,
selectedIndex: widget.selectedIndex, selectedIndex: widget.selectedIndex,
destinations: widget.destinations destinations: widget.destinations
.map((_) => AdaptiveScaffold.toRailDestination(_)) .map((NavigationDestination destination) =>
AdaptiveScaffold.toRailDestination(destination))
.toList(), .toList(),
onDestinationSelected: widget.onSelectedIndexChange, onDestinationSelected: widget.onSelectedIndexChange,
), ),
@ -534,7 +535,8 @@ class _AdaptiveScaffoldState extends State<AdaptiveScaffold> {
trailing: widget.trailingNavRail, trailing: widget.trailingNavRail,
selectedIndex: widget.selectedIndex, selectedIndex: widget.selectedIndex,
destinations: widget.destinations destinations: widget.destinations
.map((_) => AdaptiveScaffold.toRailDestination(_)) .map((NavigationDestination destination) =>
AdaptiveScaffold.toRailDestination(destination))
.toList(), .toList(),
onDestinationSelected: widget.onSelectedIndexChange, onDestinationSelected: widget.onSelectedIndexChange,
backgroundColor: navRailTheme.backgroundColor, backgroundColor: navRailTheme.backgroundColor,
@ -553,7 +555,8 @@ class _AdaptiveScaffoldState extends State<AdaptiveScaffold> {
trailing: widget.trailingNavRail, trailing: widget.trailingNavRail,
selectedIndex: widget.selectedIndex, selectedIndex: widget.selectedIndex,
destinations: widget.destinations destinations: widget.destinations
.map((_) => AdaptiveScaffold.toRailDestination(_)) .map((NavigationDestination destination) =>
AdaptiveScaffold.toRailDestination(destination))
.toList(), .toList(),
onDestinationSelected: widget.onSelectedIndexChange, onDestinationSelected: widget.onSelectedIndexChange,
backgroundColor: navRailTheme.backgroundColor, backgroundColor: navRailTheme.backgroundColor,

@ -1,6 +1,6 @@
name: flutter_adaptive_scaffold name: flutter_adaptive_scaffold
description: Widgets to easily build adaptive layouts, including navigation elements. description: Widgets to easily build adaptive layouts, including navigation elements.
version: 0.1.7+1 version: 0.1.7+2
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22
repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold

@ -374,7 +374,8 @@ void main() {
home: MediaQuery( home: MediaQuery(
data: const MediaQueryData(size: Size(700, 900)), data: const MediaQueryData(size: Size(700, 900)),
child: StatefulBuilder( child: StatefulBuilder(
builder: (BuildContext context, Function(Function()) setState) { builder: (BuildContext context,
void Function(void Function()) setState) {
return AdaptiveScaffold( return AdaptiveScaffold(
destinations: destinations, destinations: destinations,
selectedIndex: selectedDestination, selectedIndex: selectedDestination,

@ -1,4 +1,4 @@
## NEXT ## 0.6.18+3
* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0.
* Fixes lint warnings. * Fixes lint warnings.

@ -54,6 +54,7 @@
/// parsing of Markdown syntax and building of the formatted output. The demos /// parsing of Markdown syntax and building of the formatted output. The demos
/// in this example app illustrate some of the potentials of the /// in this example app illustrate some of the potentials of the
/// flutter_markdown package. /// flutter_markdown package.
library;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'screens/demo_screen.dart'; import 'screens/demo_screen.dart';

@ -40,7 +40,7 @@ class HomeScreen extends StatelessWidget {
title: const Text('Markdown Demos'), title: const Text('Markdown Demos'),
), ),
body: SafeArea( body: SafeArea(
child: Container( child: ColoredBox(
color: Colors.black12, color: Colors.black12,
child: ListView( child: ListView(
children: <Widget>[ children: <Widget>[

@ -54,11 +54,9 @@ final MarkdownStyleSheet Function(BuildContext, MarkdownStyleSheetBaseTheme?)
result = (Platform.isIOS || Platform.isMacOS) result = (Platform.isIOS || Platform.isMacOS)
? MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context)) ? MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context))
: MarkdownStyleSheet.fromTheme(Theme.of(context)); : MarkdownStyleSheet.fromTheme(Theme.of(context));
break;
case MarkdownStyleSheetBaseTheme.cupertino: case MarkdownStyleSheetBaseTheme.cupertino:
result = result =
MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context)); MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context));
break;
case MarkdownStyleSheetBaseTheme.material: case MarkdownStyleSheetBaseTheme.material:
// ignore: no_default_cases // ignore: no_default_cases
default: default:

@ -57,11 +57,9 @@ final MarkdownStyleSheet Function(BuildContext, MarkdownStyleSheetBaseTheme?)
result = userAgent.contains('Mac OS X') result = userAgent.contains('Mac OS X')
? MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context)) ? MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context))
: MarkdownStyleSheet.fromTheme(Theme.of(context)); : MarkdownStyleSheet.fromTheme(Theme.of(context));
break;
case MarkdownStyleSheetBaseTheme.cupertino: case MarkdownStyleSheetBaseTheme.cupertino:
result = result =
MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context)); MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context));
break;
case MarkdownStyleSheetBaseTheme.material: case MarkdownStyleSheetBaseTheme.material:
default: // ignore: no_default_cases default: // ignore: no_default_cases
result = MarkdownStyleSheet.fromTheme(Theme.of(context)); result = MarkdownStyleSheet.fromTheme(Theme.of(context));

@ -501,13 +501,10 @@ class MarkdownBuilder implements md.NodeVisitor {
switch (alignAttribute) { switch (alignAttribute) {
case 'left': case 'left':
align = TextAlign.left; align = TextAlign.left;
break;
case 'center': case 'center':
align = TextAlign.center; align = TextAlign.center;
break;
case 'right': case 'right':
align = TextAlign.right; align = TextAlign.right;
break;
} }
} }
final Widget child = _buildTableCell( final Widget child = _buildTableCell(

@ -4,7 +4,7 @@ description: A Markdown renderer for Flutter. Create rich text output,
formatted with simple Markdown tags. formatted with simple Markdown tags.
repository: https://github.com/flutter/packages/tree/main/packages/flutter_markdown repository: https://github.com/flutter/packages/tree/main/packages/flutter_markdown
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_markdown%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_markdown%22
version: 0.6.18+2 version: 0.6.18+3
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
library flutter_markdown.all_test;
import 'blockquote_test.dart' as blockquote_test; import 'blockquote_test.dart' as blockquote_test;
import 'custom_syntax_test.dart' as custome_syntax_test; import 'custom_syntax_test.dart' as custome_syntax_test;
import 'emphasis_test.dart' as emphasis_test; import 'emphasis_test.dart' as emphasis_test;

@ -44,11 +44,11 @@ MockHttpClient createMockImageHttpClient(SecurityContext? _) {
// image tests that request an image. // image tests that request an image.
StreamSubscription<List<int>> imageStream(Invocation invocation) { StreamSubscription<List<int>> imageStream(Invocation invocation) {
final void Function(List<int>)? onData = final void Function(List<int>)? onData =
invocation.positionalArguments[0] as Function(List<int>)?; invocation.positionalArguments[0] as void Function(List<int>)?;
final void Function()? onDone = final void Function()? onDone =
invocation.namedArguments[#onDone] as Function()?; invocation.namedArguments[#onDone] as void Function()?;
final void Function(Object, [StackTrace?])? onError = final void Function(Object, [StackTrace?])? onError = invocation
invocation.namedArguments[#onError] as Function(Object, [StackTrace?])?; .namedArguments[#onError] as void Function(Object, [StackTrace?])?;
final bool? cancelOnError = final bool? cancelOnError =
invocation.namedArguments[#cancelOnError] as bool?; invocation.namedArguments[#cancelOnError] as bool?;

@ -2,29 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/// This file serves as the single point of entry into the `dart:io` APIs // This file serves as the single point of entry into the `dart:io` APIs
/// within Flutter tools. // within Flutter tools.
/// //
/// In order to make Flutter tools more testable, we use the `FileSystem` APIs // In order to make Flutter tools more testable, we use the `FileSystem` APIs
/// in `package:file` rather than using the `dart:io` file APIs directly (see // in `package:file` rather than using the `dart:io` file APIs directly (see
/// `file_system.dart`). Doing so allows us to swap out local file system // `file_system.dart`). Doing so allows us to swap out local file system
/// access with mockable (or in-memory) file systems, making our tests hermetic // access with mockable (or in-memory) file systems, making our tests hermetic
/// vis-a-vis file system access. // vis-a-vis file system access.
/// //
/// We also use `package:platform` to provide an abstraction away from the // We also use `package:platform` to provide an abstraction away from the
/// static methods in the `dart:io` `Platform` class (see `platform.dart`). As // static methods in the `dart:io` `Platform` class (see `platform.dart`). As
/// such, do not export Platform from this file! // such, do not export Platform from this file!
/// //
/// To ensure that all file system and platform API access within Flutter tools // To ensure that all file system and platform API access within Flutter tools
/// goes through the proper APIs, we forbid direct imports of `dart:io` (via a // goes through the proper APIs, we forbid direct imports of `dart:io` (via a
/// test), forcing all callers to instead import this file, which exports the // test), forcing all callers to instead import this file, which exports the
/// blessed subset of `dart:io` that is legal to use in Flutter tools. // blessed subset of `dart:io` that is legal to use in Flutter tools.
/// //
/// Because of the nature of this file, it is important that **platform and file // Because of the nature of this file, it is important that **platform and file
/// APIs not be exported from `dart:io` in this file**! Moreover, be careful // APIs not be exported from `dart:io` in this file**! Moreover, be careful
/// about any additional exports that you add to this file, as doing so will // about any additional exports that you add to this file, as doing so will
/// increase the API surface that we have to test in Flutter tools, and the APIs // increase the API surface that we have to test in Flutter tools, and the APIs
/// in `dart:io` can sometimes be hard to use in tests. // in `dart:io` can sometimes be hard to use in tests.
// We allow `print()` in this file as a fallback for writing to the terminal via // We allow `print()` in this file as a fallback for writing to the terminal via
// regular stdout/stderr/stdio paths. Everything else in the flutter_tools // regular stdout/stderr/stdio paths. Everything else in the flutter_tools

@ -278,30 +278,6 @@ class FileSystemUtils {
i += 1; i += 1;
} }
} }
/// Escapes [path].
///
/// On Windows it replaces all '\' with '\\'. On other platforms, it returns the
/// path unchanged.
String escapePath(String path) =>
isWindows ? path.replaceAll(r'\', r'\\') : path;
/// Returns true if the file system [entity] has not been modified since the
/// latest modification to [referenceFile].
///
/// Returns true, if [entity] does not exist.
///
/// Returns false, if [entity] exists, but [referenceFile] does not.
bool isOlderThanReference({
required FileSystemEntity entity,
required File referenceFile,
}) {
if (!entity.existsSync()) {
return true;
}
return referenceFile.existsSync() &&
referenceFile.statSync().modified.isAfter(entity.statSync().modified);
}
} }
/// Creates `destDir` if needed, then recursively copies `srcDir` to /// Creates `destDir` if needed, then recursively copies `srcDir` to

@ -12,12 +12,6 @@ import 'package:test/fake.dart';
import '../src/common.dart'; import '../src/common.dart';
import '../src/fakes.dart'; import '../src/fakes.dart';
// final Platform _kNoAnsiPlatform = FakePlatform();
final String red = RegExp.escape(AnsiTerminal.red);
final String bold = RegExp.escape(AnsiTerminal.bold);
final String resetBold = RegExp.escape(AnsiTerminal.resetBold);
final String resetColor = RegExp.escape(AnsiTerminal.resetColor);
void main() { void main() {
testWithoutContext('correct logger instance is created', () { testWithoutContext('correct logger instance is created', () {
final LoggerFactory loggerFactory = LoggerFactory( final LoggerFactory loggerFactory = LoggerFactory(
@ -645,13 +639,6 @@ void main() {
}); });
} }
/// A fake [Logger] that throws the [Invocation] for any method call.
class FakeLogger implements Logger {
@override
dynamic noSuchMethod(Invocation invocation) =>
throw invocation; // ignore: only_throw_errors
}
class FakeStdout extends Fake implements Stdout { class FakeStdout extends Fake implements Stdout {
FakeStdout({required this.syncError, this.completeWithError = false}); FakeStdout({required this.syncError, this.completeWithError = false});

@ -58,7 +58,6 @@ String getFlutterRoot() {
switch (io.Platform.script.scheme) { switch (io.Platform.script.scheme) {
case 'file': case 'file':
scriptUri = io.Platform.script; scriptUri = io.Platform.script;
break;
case 'data': case 'data':
final RegExp flutterTools = RegExp( final RegExp flutterTools = RegExp(
r'(file://[^"]*[/\\]flutter_tools[/\\][^"]+\.dart)', r'(file://[^"]*[/\\]flutter_tools[/\\][^"]+\.dart)',
@ -69,7 +68,6 @@ String getFlutterRoot() {
throw invalidScript(); throw invalidScript();
} }
scriptUri = Uri.parse(match.group(1)!); scriptUri = Uri.parse(match.group(1)!);
break;
default: default:
throw invalidScript(); throw invalidScript();
} }

@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
@Timeout(Duration(seconds: 600)) @Timeout(Duration(seconds: 600))
library;
import 'dart:io'; import 'dart:io';
import 'package:file/file.dart'; import 'package:file/file.dart';

@ -1,3 +1,7 @@
## 13.0.1
* Fixes new lint warnings.
## 13.0.0 ## 13.0.0
- Refactors `RouteMatchList` and imperative APIs. - Refactors `RouteMatchList` and imperative APIs.

@ -37,15 +37,12 @@ class _BooksScreenState extends State<BooksScreen>
switch (widget.kind) { switch (widget.kind) {
case 'popular': case 'popular':
_tabController.index = 0; _tabController.index = 0;
break;
case 'new': case 'new':
_tabController.index = 1; _tabController.index = 1;
break;
case 'all': case 'all':
_tabController.index = 2; _tabController.index = 2;
break;
} }
} }
@ -105,10 +102,8 @@ class _BooksScreenState extends State<BooksScreen>
switch (index) { switch (index) {
case 1: case 1:
context.go('/books/new'); context.go('/books/new');
break;
case 2: case 2:
context.go('/books/all'); context.go('/books/all');
break;
case 0: case 0:
default: default:
context.go('/books/popular'); context.go('/books/popular');

@ -43,13 +43,10 @@ class BookstoreScaffold extends StatelessWidget {
switch (ScaffoldTab.values[idx]) { switch (ScaffoldTab.values[idx]) {
case ScaffoldTab.books: case ScaffoldTab.books:
context.go('/books'); context.go('/books');
break;
case ScaffoldTab.authors: case ScaffoldTab.authors:
context.go('/authors'); context.go('/authors');
break;
case ScaffoldTab.settings: case ScaffoldTab.settings:
context.go('/settings'); context.go('/settings');
break;
} }
}, },
destinations: const <AdaptiveScaffoldDestination>[ destinations: const <AdaptiveScaffoldDestination>[

@ -127,11 +127,11 @@ class _MyExtraEncoder extends Converter<Object?, Object?> {
if (input == null) { if (input == null) {
return null; return null;
} }
switch (input.runtimeType) { switch (input) {
case ComplexData1: case ComplexData1 _:
return <Object?>['ComplexData1', (input as ComplexData1).data]; return <Object?>['ComplexData1', input.data];
case ComplexData2: case ComplexData2 _:
return <Object?>['ComplexData2', (input as ComplexData2).data]; return <Object?>['ComplexData2', input.data];
default: default:
throw FormatException('Cannot encode type ${input.runtimeType}'); throw FormatException('Cannot encode type ${input.runtimeType}');
} }

@ -329,7 +329,7 @@ class DetailsScreenState extends State<DetailsScreen> {
body: _build(context), body: _build(context),
); );
} else { } else {
return Container( return ColoredBox(
color: Theme.of(context).scaffoldBackgroundColor, color: Theme.of(context).scaffoldBackgroundColor,
child: _build(context), child: _build(context),
); );

@ -20,28 +20,25 @@ class Family {
/// Person data class. /// Person data class.
class Person { class Person {
/// Creates a person. /// Creates a person.
const Person({required this.name, required this.age}); const Person({required this.name});
/// The first name of the person. /// The first name of the person.
final String name; final String name;
/// The age of the person.
final int age;
} }
const Map<String, Family> _families = <String, Family>{ const Map<String, Family> _families = <String, Family>{
'f1': Family( 'f1': Family(
name: 'Doe', name: 'Doe',
people: <String, Person>{ people: <String, Person>{
'p1': Person(name: 'Jane', age: 23), 'p1': Person(name: 'Jane'),
'p2': Person(name: 'John', age: 6), 'p2': Person(name: 'John'),
}, },
), ),
'f2': Family( 'f2': Family(
name: 'Wong', name: 'Wong',
people: <String, Person>{ people: <String, Person>{
'p1': Person(name: 'June', age: 51), 'p1': Person(name: 'June'),
'p2': Person(name: 'Xin', age: 44), 'p2': Person(name: 'Xin'),
}, },
), ),
}; };

@ -141,7 +141,7 @@ class ExampleTransitionsScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) => Scaffold( Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: Text('${App.title}: $kind')), appBar: AppBar(title: Text('${App.title}: $kind')),
body: Container( body: ColoredBox(
color: color, color: color,
child: Center( child: Center(
child: Column( child: Column(

@ -28,28 +28,25 @@ class Family {
/// Person data class. /// Person data class.
class Person { class Person {
/// Creates a person. /// Creates a person.
const Person({required this.name, required this.age}); const Person({required this.name});
/// The first name of the person. /// The first name of the person.
final String name; final String name;
/// The age of the person.
final int age;
} }
const Map<String, Family> _families = <String, Family>{ const Map<String, Family> _families = <String, Family>{
'f1': Family( 'f1': Family(
name: 'Doe', name: 'Doe',
people: <String, Person>{ people: <String, Person>{
'p1': Person(name: 'Jane', age: 23), 'p1': Person(name: 'Jane'),
'p2': Person(name: 'John', age: 6), 'p2': Person(name: 'John'),
}, },
), ),
'f2': Family( 'f2': Family(
name: 'Wong', name: 'Wong',
people: <String, Person>{ people: <String, Person>{
'p1': Person(name: 'June', age: 51), 'p1': Person(name: 'June'),
'p2': Person(name: 'Xin', age: 44), 'p2': Person(name: 'Xin'),
}, },
), ),
}; };

@ -169,13 +169,10 @@ class ScaffoldWithNavBar extends StatelessWidget {
switch (index) { switch (index) {
case 0: case 0:
GoRouter.of(context).go('/a'); GoRouter.of(context).go('/a');
break;
case 1: case 1:
GoRouter.of(context).go('/b'); GoRouter.of(context).go('/b');
break;
case 2: case 2:
GoRouter.of(context).go('/c'); GoRouter.of(context).go('/c');
break;
} }
} }
} }

@ -276,7 +276,7 @@ class DetailsScreenState extends State<DetailsScreen> {
body: _build(context), body: _build(context),
); );
} else { } else {
return Container( return ColoredBox(
color: Theme.of(context).scaffoldBackgroundColor, color: Theme.of(context).scaffoldBackgroundColor,
child: _build(context), child: _build(context),
); );

@ -115,13 +115,10 @@ class GoRouteInformationProvider extends RouteInformationProvider
return; return;
} }
replace = _valueInEngine == _kEmptyRouteInformation; replace = _valueInEngine == _kEmptyRouteInformation;
break;
case RouteInformationReportingType.neglect: case RouteInformationReportingType.neglect:
replace = true; replace = true;
break;
case RouteInformationReportingType.navigate: case RouteInformationReportingType.navigate:
replace = false; replace = false;
break;
} }
SystemNavigator.selectMultiEntryHistory(); SystemNavigator.selectMultiEntryHistory();
SystemNavigator.routeInformationUpdated( SystemNavigator.routeInformationUpdated(

@ -113,7 +113,7 @@ extension GoRouterHelper on BuildContext {
/// * [pushReplacement] which replaces the top-most page of the page stack but /// * [pushReplacement] which replaces the top-most page of the page stack but
/// always uses a new page key. /// always uses a new page key.
void replace(String location, {Object? extra}) => void replace(String location, {Object? extra}) =>
GoRouter.of(this).replace(location, extra: extra); GoRouter.of(this).replace<Object?>(location, extra: extra);
/// Replaces the top-most page with the named route and optional parameters, /// Replaces the top-most page with the named route and optional parameters,
/// preserving the page key. /// preserving the page key.
@ -132,7 +132,7 @@ extension GoRouterHelper on BuildContext {
Map<String, dynamic> queryParameters = const <String, dynamic>{}, Map<String, dynamic> queryParameters = const <String, dynamic>{},
Object? extra, Object? extra,
}) => }) =>
GoRouter.of(this).replaceNamed(name, GoRouter.of(this).replaceNamed<Object?>(name,
pathParameters: pathParameters, pathParameters: pathParameters,
queryParameters: queryParameters, queryParameters: queryParameters,
extra: extra); extra: extra);

@ -1,7 +1,7 @@
name: go_router name: go_router
description: A declarative router for Flutter based on Navigation 2 supporting description: A declarative router for Flutter based on Navigation 2 supporting
deep linking, data-driven routes and more deep linking, data-driven routes and more
version: 13.0.0 version: 13.0.1
repository: https://github.com/flutter/packages/tree/main/packages/go_router repository: https://github.com/flutter/packages/tree/main/packages/go_router
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22

@ -430,7 +430,7 @@ void main() {
final RouteMatchBase first = final RouteMatchBase first =
goRouter.routerDelegate.currentConfiguration.matches.first; goRouter.routerDelegate.currentConfiguration.matches.first;
final RouteMatch last = goRouter.routerDelegate.currentConfiguration.last; final RouteMatch last = goRouter.routerDelegate.currentConfiguration.last;
goRouter.replace('/page-1'); goRouter.replace<void>('/page-1');
expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2); expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2);
expect( expect(
goRouter.routerDelegate.currentConfiguration.matches.first, goRouter.routerDelegate.currentConfiguration.matches.first,
@ -470,7 +470,7 @@ void main() {
final ValueKey<String> prev = final ValueKey<String> prev =
goRouter.routerDelegate.currentConfiguration.matches.last.pageKey; goRouter.routerDelegate.currentConfiguration.matches.last.pageKey;
goRouter.replace('/a'); goRouter.replace<void>('/a');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2); expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2);
@ -498,7 +498,7 @@ void main() {
final ValueKey<String> prev = final ValueKey<String> prev =
goRouter.routerDelegate.currentConfiguration.matches.last.pageKey; goRouter.routerDelegate.currentConfiguration.matches.last.pageKey;
goRouter.replace('/'); goRouter.replace<void>('/');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2); expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2);
@ -551,7 +551,7 @@ void main() {
final RouteMatchBase first = final RouteMatchBase first =
goRouter.routerDelegate.currentConfiguration.matches.first; goRouter.routerDelegate.currentConfiguration.matches.first;
final RouteMatch last = goRouter.routerDelegate.currentConfiguration.last; final RouteMatch last = goRouter.routerDelegate.currentConfiguration.last;
goRouter.replaceNamed('page1'); goRouter.replaceNamed<void>('page1');
expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2); expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2);
expect( expect(
goRouter.routerDelegate.currentConfiguration.matches.first, goRouter.routerDelegate.currentConfiguration.matches.first,
@ -591,7 +591,7 @@ void main() {
final ValueKey<String> prev = final ValueKey<String> prev =
goRouter.routerDelegate.currentConfiguration.matches.last.pageKey; goRouter.routerDelegate.currentConfiguration.matches.last.pageKey;
goRouter.replaceNamed('page0'); goRouter.replaceNamed<void>('page0');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2); expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2);
@ -619,7 +619,7 @@ void main() {
final ValueKey<String> prev = final ValueKey<String> prev =
goRouter.routerDelegate.currentConfiguration.matches.last.pageKey; goRouter.routerDelegate.currentConfiguration.matches.last.pageKey;
goRouter.replaceNamed('home'); goRouter.replaceNamed<void>('home');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2); expect(goRouter.routerDelegate.currentConfiguration.matches.length, 2);

@ -51,15 +51,3 @@ Widget widgetsAppBuilder({required Widget home}) {
color: Colors.white, color: Colors.white,
); );
} }
class DummyStatefulWidget extends StatefulWidget {
const DummyStatefulWidget({super.key});
@override
State<DummyStatefulWidget> createState() => _DummyStatefulWidgetState();
}
class _DummyStatefulWidgetState extends State<DummyStatefulWidget> {
@override
Widget build(BuildContext context) => Container();
}

@ -284,7 +284,7 @@ void main() {
expect(find.byKey(home), findsNothing); expect(find.byKey(home), findsNothing);
expect(find.byKey(settings), findsOneWidget); expect(find.byKey(settings), findsOneWidget);
showDialog( showDialog<void>(
context: navKey.currentContext!, context: navKey.currentContext!,
builder: (_) => DummyScreen(key: dialog), builder: (_) => DummyScreen(key: dialog),
); );
@ -296,7 +296,7 @@ void main() {
expect(find.byKey(dialog), findsNothing); expect(find.byKey(dialog), findsNothing);
expect(find.byKey(settings), findsOneWidget); expect(find.byKey(settings), findsOneWidget);
showDialog( showDialog<void>(
context: navKey.currentContext!, context: navKey.currentContext!,
builder: (_) => DummyScreen(key: dialog), builder: (_) => DummyScreen(key: dialog),
); );
@ -4427,7 +4427,7 @@ void main() {
expect(router.canPop(), isFalse); expect(router.canPop(), isFalse);
expect(find.text('A Screen'), findsOneWidget); expect(find.text('A Screen'), findsOneWidget);
expect(find.text('Shell'), findsOneWidget); expect(find.text('Shell'), findsOneWidget);
showDialog( showDialog<void>(
context: root.currentContext!, context: root.currentContext!,
builder: (_) => const Text('A dialog')); builder: (_) => const Text('A dialog'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();

@ -39,7 +39,7 @@ void main() {
expect(find.text('shell'), findsOneWidget); expect(find.text('shell'), findsOneWidget);
expect(find.byKey(a), findsOneWidget); expect(find.byKey(a), findsOneWidget);
router.replace('/b'); router.replace<void>('/b');
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('shell'), findsOneWidget); expect(find.text('shell'), findsOneWidget);
expect(find.byKey(a), findsNothing); expect(find.byKey(a), findsNothing);

@ -1,3 +1,7 @@
## 2.4.1
* Fixes new lint warnings.
## 2.4.0 ## 2.4.0
* Adds support for passing observers to the ShellRoute for the nested Navigator. * Adds support for passing observers to the ShellRoute for the nested Navigator.

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs, unreachable_from_main
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs, unreachable_from_main
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs, unreachable_from_main
import 'dart:async'; import 'dart:async';
@ -179,7 +179,7 @@ class HomeScreen extends StatelessWidget {
PopupMenuItem<String>( PopupMenuItem<String>(
value: '1', value: '1',
child: const Text('Push w/o return value'), child: const Text('Push w/o return value'),
onTap: () => const PersonRoute('f1', 1).push(context), onTap: () => const PersonRoute('f1', 1).push<void>(context),
), ),
PopupMenuItem<String>( PopupMenuItem<String>(
value: '2', value: '2',

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs, unreachable_from_main
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -105,10 +105,8 @@ class MyShellRouteScreen extends StatelessWidget {
switch (index) { switch (index) {
case 0: case 0:
const FooRouteData().go(context); const FooRouteData().go(context);
break;
case 1: case 1:
const BarRouteData().go(context); const BarRouteData().go(context);
break;
} }
}, },
), ),

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs, unreachable_from_main
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -87,10 +87,8 @@ class MyShellRouteScreen extends StatelessWidget {
switch (index) { switch (index) {
case 0: case 0:
const HomeRouteData().go(context); const HomeRouteData().go(context);
break;
case 1: case 1:
const UsersRouteData().go(context); const UsersRouteData().go(context);
break;
} }
}, },
), ),

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs, unreachable_from_main
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -90,10 +90,8 @@ class MyShellRouteScreen extends StatelessWidget {
switch (index) { switch (index) {
case 0: case 0:
const HomeRouteData().go(context); const HomeRouteData().go(context);
break;
case 1: case 1:
const UsersRouteData().go(context); const UsersRouteData().go(context);
break;
} }
}, },
), ),

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs, unreachable_from_main
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';

Some files were not shown because too many files have changed in this diff Show More