diff --git a/.ci.yaml b/.ci.yaml index 865c7f65ee5fc..81ee200c76886 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -1227,7 +1227,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: analyzer_benchmark - scheduler: luci - name: Linux_android android_defines_test recipe: devicelab/devicelab_drone @@ -1237,7 +1236,6 @@ targets: tags: > ["devicelab" ,"android", "linux"] task_name: android_defines_test - scheduler: luci - name: Linux_android android_obfuscate_test recipe: devicelab/devicelab_drone @@ -1247,7 +1245,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: android_obfuscate_test - scheduler: luci - name: Linux_android android_semantics_integration_test recipe: devicelab/devicelab_drone @@ -1257,7 +1254,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: android_semantics_integration_test - scheduler: luci - name: Linux_android android_stack_size_test recipe: devicelab/devicelab_drone @@ -1267,7 +1263,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: android_stack_size_test - scheduler: luci - name: Linux_android android_view_scroll_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1277,7 +1272,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: android_view_scroll_perf__timeline_summary - scheduler: luci - name: Linux_android animated_image_gc_perf recipe: devicelab/devicelab_drone @@ -1287,7 +1281,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: animated_image_gc_perf - scheduler: luci - name: Linux_android animated_complex_opacity_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1306,7 +1299,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: animated_placeholder_perf__e2e_summary - scheduler: luci - name: Linux_android backdrop_filter_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1316,7 +1308,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: backdrop_filter_perf__e2e_summary - scheduler: luci - name: Linux_samsung_s10 backdrop_filter_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1326,7 +1317,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: backdrop_filter_perf__timeline_summary - scheduler: luci - name: Linux_android basic_material_app_android__compile recipe: devicelab/devicelab_drone @@ -1336,7 +1326,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: basic_material_app_android__compile - scheduler: luci - name: Linux_android channels_integration_test recipe: devicelab/devicelab_drone @@ -1346,7 +1335,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: channels_integration_test - scheduler: luci - name: Linux_android clipper_cache_perf__e2e_summary bringup: true @@ -1366,7 +1354,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: color_filter_and_fade_perf__e2e_summary - scheduler: luci - name: Linux_android color_filter_cache_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1376,7 +1363,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: color_filter_cache_perf__e2e_summary - scheduler: luci - name: Linux_android raster_cache_use_memory_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1386,7 +1372,6 @@ targets: tags: > ["devicelab","android","linux"] task_name: raster_cache_use_memory_perf__e2e_summary - scheduler: luci - name: Linux_android shader_mask_cache_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1396,7 +1381,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: shader_mask_cache_perf__e2e_summary - scheduler: luci - name: Linux_android complex_layout_android__compile recipe: devicelab/devicelab_drone @@ -1410,7 +1394,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android complex_layout_android__scroll_smoothness recipe: devicelab/devicelab_drone @@ -1424,7 +1407,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android complex_layout_scroll_perf__devtools_memory recipe: devicelab/devicelab_drone @@ -1438,7 +1420,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android complex_layout_scroll_perf__memory recipe: devicelab/devicelab_drone @@ -1452,7 +1433,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android complex_layout_scroll_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1466,7 +1446,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_samsung_s10 complex_layout_scroll_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1480,7 +1459,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android complex_layout_semantics_perf recipe: devicelab/devicelab_drone @@ -1494,7 +1472,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android complex_layout__start_up recipe: devicelab/devicelab_drone @@ -1508,7 +1485,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android cubic_bezier_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1518,7 +1494,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: cubic_bezier_perf__e2e_summary - scheduler: luci - name: Linux_android cubic_bezier_perf_sksl_warmup__e2e_summary recipe: devicelab/devicelab_drone @@ -1528,7 +1503,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: cubic_bezier_perf_sksl_warmup__e2e_summary - scheduler: luci - name: Linux_samsung_s10 cubic_bezier_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1538,7 +1512,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: cubic_bezier_perf__timeline_summary - scheduler: luci - name: Linux_android cull_opacity_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1548,7 +1521,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: cull_opacity_perf__e2e_summary - scheduler: luci - name: Linux_samsung_s10 cull_opacity_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1558,7 +1530,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: cull_opacity_perf__timeline_summary - scheduler: luci - name: Linux_android devtools_profile_start_test recipe: devicelab/devicelab_drone @@ -1568,7 +1539,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: devtools_profile_start_test - scheduler: luci - name: Linux_android drive_perf_debug_warning recipe: devicelab/devicelab_drone @@ -1578,7 +1548,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: drive_perf_debug_warning - scheduler: luci - name: Linux_android embedded_android_views_integration_test recipe: devicelab/devicelab_drone @@ -1588,7 +1557,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: embedded_android_views_integration_test - scheduler: luci - name: Linux_android external_ui_integration_test recipe: devicelab/devicelab_drone @@ -1598,7 +1566,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: external_ui_integration_test - scheduler: luci - name: Linux_android fading_child_animation_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1608,7 +1575,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: fading_child_animation_perf__timeline_summary - scheduler: luci - name: Linux_android fast_scroll_heavy_gridview__memory recipe: devicelab/devicelab_drone @@ -1618,7 +1584,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: fast_scroll_heavy_gridview__memory - scheduler: luci - name: Linux_android fast_scroll_large_images__memory recipe: devicelab/devicelab_drone @@ -1628,7 +1593,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: fast_scroll_large_images__memory - scheduler: luci - name: Linux_android flavors_test recipe: devicelab/devicelab_drone @@ -1638,7 +1602,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flavors_test - scheduler: luci - name: Linux_android flutter_engine_group_performance recipe: devicelab/devicelab_drone @@ -1648,7 +1611,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_engine_group_performance - scheduler: luci - name: Linux_android flutter_gallery__back_button_memory recipe: devicelab/devicelab_drone @@ -1658,7 +1620,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__back_button_memory - scheduler: luci - name: Linux_android flutter_gallery__image_cache_memory recipe: devicelab/devicelab_drone @@ -1668,7 +1629,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__image_cache_memory - scheduler: luci - name: Linux_android flutter_gallery__memory_nav recipe: devicelab/devicelab_drone @@ -1678,7 +1638,6 @@ targets: tags: > ["devicelab" ,"android", "linux"] task_name: flutter_gallery__memory_nav - scheduler: luci - name: Linux_android flutter_gallery__start_up recipe: devicelab/devicelab_drone @@ -1688,7 +1647,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__start_up - scheduler: luci - name: Linux_android flutter_gallery__start_up_delayed recipe: devicelab/devicelab_drone @@ -1698,7 +1656,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__start_up_delayed - scheduler: luci - name: Linux_android flutter_gallery_android__compile recipe: devicelab/devicelab_drone @@ -1708,7 +1665,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery_android__compile - scheduler: luci - name: Linux_android flutter_gallery_v2_chrome_run_test recipe: devicelab/devicelab_drone @@ -1718,7 +1674,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery_v2_chrome_run_test - scheduler: luci - name: Linux_android flutter_gallery_v2_web_compile_test recipe: devicelab/devicelab_drone @@ -1728,7 +1683,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery_v2_web_compile_test - scheduler: luci - name: Linux_android flutter_test_performance recipe: devicelab/devicelab_drone @@ -1738,7 +1692,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_test_performance - scheduler: luci - name: Linux_android flutter_view__start_up recipe: devicelab/devicelab_drone @@ -1748,7 +1701,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_view__start_up - scheduler: luci - name: Linux_android frame_policy_delay_test_android recipe: devicelab/devicelab_drone @@ -1758,7 +1710,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: frame_policy_delay_test_android - scheduler: luci - name: Linux_android fullscreen_textfield_perf recipe: devicelab/devicelab_drone @@ -1768,7 +1719,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: fullscreen_textfield_perf - scheduler: luci - name: Linux_android fullscreen_textfield_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1778,7 +1728,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: fullscreen_textfield_perf__e2e_summary - scheduler: luci - name: Linux_android hello_world__memory recipe: devicelab/devicelab_drone @@ -1788,7 +1737,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: hello_world__memory - scheduler: luci - name: Linux_android home_scroll_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1798,7 +1746,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: home_scroll_perf__timeline_summary - scheduler: luci - name: Linux_android hot_mode_dev_cycle_linux__benchmark recipe: devicelab/devicelab_drone @@ -1809,7 +1756,6 @@ targets: task_name: hot_mode_dev_cycle_linux__benchmark runIf: - dev/** - scheduler: luci - name: Linux_android hybrid_android_views_integration_test recipe: devicelab/devicelab_drone @@ -1819,7 +1765,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: hybrid_android_views_integration_test - scheduler: luci - name: Linux_android image_list_jit_reported_duration recipe: devicelab/devicelab_drone @@ -1829,7 +1774,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: image_list_jit_reported_duration - scheduler: luci - name: Linux_android imagefiltered_transform_animation_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1839,7 +1783,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: imagefiltered_transform_animation_perf__timeline_summary - scheduler: luci - name: Linux_samsung_s10 imagefiltered_transform_animation_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -1849,7 +1792,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: imagefiltered_transform_animation_perf__timeline_summary - scheduler: luci - name: Linux_android image_list_reported_duration recipe: devicelab/devicelab_drone @@ -1859,7 +1801,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: image_list_reported_duration - scheduler: luci - name: Linux_android integration_ui_driver recipe: devicelab/devicelab_drone @@ -1869,7 +1810,6 @@ targets: tags: > ["devicelab" ,"android", "linux"] task_name: integration_ui_driver - scheduler: luci - name: Linux_android integration_ui_keyboard_resize recipe: devicelab/devicelab_drone @@ -1879,7 +1819,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: integration_ui_keyboard_resize - scheduler: luci - name: Linux_android integration_ui_screenshot recipe: devicelab/devicelab_drone @@ -1889,7 +1828,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: integration_ui_screenshot - scheduler: luci - name: Linux_android integration_ui_textfield recipe: devicelab/devicelab_drone @@ -1899,7 +1837,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: integration_ui_textfield - scheduler: luci - name: Linux_android large_image_changer_perf_android recipe: devicelab/devicelab_drone @@ -1909,7 +1846,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: large_image_changer_perf_android - scheduler: luci - name: Linux_android linux_chrome_dev_mode recipe: devicelab/devicelab_drone @@ -1919,7 +1855,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: linux_chrome_dev_mode - scheduler: luci - name: Linux_android multi_widget_construction_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1929,7 +1864,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: multi_widget_construction_perf__e2e_summary - scheduler: luci - name: Linux_android list_text_layout_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1939,7 +1873,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: list_text_layout_perf__e2e_summary - bringup: true - name: Linux_android list_text_layout_impeller_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -1949,7 +1882,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: list_text_layout_impeller_perf__e2e_summary - bringup: true - name: Linux_android new_gallery__crane_perf recipe: devicelab/devicelab_drone @@ -1959,7 +1891,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: new_gallery__crane_perf - scheduler: luci - name: Linux_android old_gallery__transition_perf bringup: true @@ -1979,7 +1910,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: new_gallery__transition_perf - scheduler: luci - name: Linux_android flutter_gallery__transition_perf recipe: devicelab/devicelab_drone @@ -1989,7 +1919,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__transition_perf - scheduler: luci - name: Linux_android flutter_gallery__transition_perf_e2e recipe: devicelab/devicelab_drone @@ -1999,7 +1928,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__transition_perf_e2e - scheduler: luci - name: Linux_android flutter_gallery__transition_perf_hybrid recipe: devicelab/devicelab_drone @@ -2009,7 +1937,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__transition_perf_hybrid - scheduler: luci - name: Linux_android flutter_gallery__transition_perf_with_semantics recipe: devicelab/devicelab_drone @@ -2019,7 +1946,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery__transition_perf_with_semantics - scheduler: luci - name: Linux_android flutter_gallery_sksl_warmup__transition_perf recipe: devicelab/devicelab_drone @@ -2029,7 +1955,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery_sksl_warmup__transition_perf - scheduler: luci - name: Linux_android flutter_gallery_sksl_warmup__transition_perf_e2e recipe: devicelab/devicelab_drone @@ -2039,7 +1964,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: flutter_gallery_sksl_warmup__transition_perf_e2e - scheduler: luci - name: Linux_samsung_s10 new_gallery__transition_perf recipe: devicelab/devicelab_drone @@ -2049,7 +1973,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: new_gallery__transition_perf - scheduler: luci - name: Linux_android new_gallery_impeller__transition_perf recipe: devicelab/devicelab_drone @@ -2079,7 +2002,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: picture_cache_perf__e2e_summary - scheduler: luci - name: Linux_samsung_s10 picture_cache_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -2089,7 +2011,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: picture_cache_perf__timeline_summary - scheduler: luci - name: Linux_android android_picture_cache_complexity_scoring_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -2099,7 +2020,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: android_picture_cache_complexity_scoring_perf__timeline_summary - scheduler: luci - name: Linux_android platform_channels_benchmarks recipe: devicelab/devicelab_drone @@ -2109,7 +2029,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: platform_channels_benchmarks - scheduler: luci - name: Linux_android platform_channel_sample_test recipe: devicelab/devicelab_drone @@ -2119,7 +2038,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: platform_channel_sample_test - scheduler: luci - name: Linux_android platform_interaction_test recipe: devicelab/devicelab_drone @@ -2129,7 +2047,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: platform_interaction_test - scheduler: luci - name: Linux_android platform_views_scroll_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -2139,7 +2056,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: platform_views_scroll_perf__timeline_summary - scheduler: luci - name: Linux_samsung_s10 platform_views_scroll_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -2149,7 +2065,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: platform_views_scroll_perf__timeline_summary - scheduler: luci - name: Linux_android platform_view__start_up recipe: devicelab/devicelab_drone @@ -2159,7 +2074,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: platform_view__start_up - scheduler: luci - name: Linux_android routing_test recipe: devicelab/devicelab_drone @@ -2169,7 +2083,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: routing_test - scheduler: luci - name: Linux_android service_extensions_test recipe: devicelab/devicelab_drone @@ -2179,7 +2092,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: service_extensions_test - scheduler: luci - name: Linux_android textfield_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2189,7 +2101,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: textfield_perf__e2e_summary - scheduler: luci - name: Linux_samsung_s10 textfield_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -2199,7 +2110,6 @@ targets: tags: > ["devicelab", "android", "linux", "samsung", "s10"] task_name: textfield_perf__timeline_summary - scheduler: luci - name: Linux_android tiles_scroll_perf__timeline_summary recipe: devicelab/devicelab_drone @@ -2213,7 +2123,6 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Linux_android web_size__compile_test recipe: devicelab/devicelab_drone @@ -2223,7 +2132,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: web_size__compile_test - scheduler: luci - name: Linux_android opacity_peephole_one_rect_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2233,7 +2141,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: opacity_peephole_one_rect_perf__e2e_summary - scheduler: luci - name: Linux_android opacity_peephole_col_of_rows_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2243,7 +2150,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: opacity_peephole_col_of_rows_perf__e2e_summary - scheduler: luci - name: Linux_android opacity_peephole_opacity_of_grid_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2253,7 +2159,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: opacity_peephole_opacity_of_grid_perf__e2e_summary - scheduler: luci - name: Linux_android opacity_peephole_grid_of_opacity_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2263,7 +2168,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: opacity_peephole_grid_of_opacity_perf__e2e_summary - scheduler: luci - name: Linux_android opacity_peephole_fade_transition_text_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2273,7 +2177,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: opacity_peephole_fade_transition_text_perf__e2e_summary - scheduler: luci - name: Linux_android opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2283,7 +2186,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary - scheduler: luci - name: Linux_android opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2293,7 +2195,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary - scheduler: luci - name: Linux_android gradient_dynamic_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2312,7 +2213,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: gradient_consistent_perf__e2e_summary - scheduler: luci - name: Linux_android gradient_static_perf__e2e_summary recipe: devicelab/devicelab_drone @@ -2322,7 +2222,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: gradient_static_perf__e2e_summary - scheduler: luci - name: Linux_android android_choreographer_do_frame_test recipe: devicelab/devicelab_drone @@ -2332,7 +2231,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: android_choreographer_do_frame_test - scheduler: luci - name: Linux_android android_lifecycles_test bringup: true @@ -2343,7 +2241,6 @@ targets: tags: > ["devicelab", "android", "linux"] task_name: android_lifecycles_test - scheduler: luci - name: Staging_build_linux analyze presubmit: false @@ -3018,7 +2915,6 @@ targets: - packages/flutter_tools/** - bin/** - .ci.yaml - scheduler: luci - name: Mac_android hello_world_android__compile recipe: devicelab/devicelab_drone @@ -3028,7 +2924,6 @@ targets: tags: > ["devicelab", "android", "mac"] task_name: hello_world_android__compile - scheduler: luci - name: Mac_arm64_android hello_world_android__compile recipe: devicelab/devicelab_drone @@ -3038,7 +2933,6 @@ targets: tags: > ["devicelab", "android", "mac", "arm64"] task_name: hello_world_android__compile - scheduler: luci - name: Mac_android hot_mode_dev_cycle__benchmark recipe: devicelab/devicelab_drone @@ -3048,7 +2942,6 @@ targets: tags: > ["devicelab", "android", "mac"] task_name: hot_mode_dev_cycle__benchmark - scheduler: luci - name: Mac_android integration_test_test recipe: devicelab/devicelab_drone @@ -3058,7 +2951,6 @@ targets: tags: > ["devicelab", "android", "mac"] task_name: integration_test_test - scheduler: luci - name: Mac_arm64_android integration_test_test recipe: devicelab/devicelab_drone @@ -3077,7 +2969,6 @@ targets: tags: > ["devicelab", "android", "mac"] task_name: integration_ui_frame_number - scheduler: luci - name: Mac_android microbenchmarks recipe: devicelab/devicelab_drone @@ -3087,7 +2978,6 @@ targets: tags: > ["devicelab", "android", "mac"] task_name: microbenchmarks - scheduler: luci - name: Mac_android run_release_test recipe: devicelab/devicelab_drone @@ -3099,7 +2989,6 @@ targets: tags: > ["devicelab", "android", "mac"] task_name: run_release_test - scheduler: luci - name: Mac_arm64_android run_release_test recipe: devicelab/devicelab_drone @@ -3111,7 +3000,6 @@ targets: tags: > ["devicelab", "android", "mac", "arm64"] task_name: run_release_test - scheduler: luci - name: Mac_android flutter_gallery_mac__start_up recipe: devicelab/devicelab_drone @@ -3121,7 +3009,6 @@ targets: tags: > ["devicelab", "android", "mac"] task_name: flutter_gallery_mac__start_up - scheduler: luci - name: Mac_ios animation_with_microtasks_perf_ios__timeline_summary recipe: devicelab/devicelab_drone @@ -3643,6 +3530,10 @@ targets: presubmit: false timeout: 60 properties: + dependencies: >- + [ + {"dependency": "xcode", "version": "13a233"} + ] tags: > ["devicelab", "hostonly"] task_name: native_platform_view_ui_tests_ios @@ -4188,7 +4079,6 @@ targets: tags: > ["devicelab", "android", "windows"] task_name: basic_material_app_win__compile - scheduler: luci - name: Windows_android channels_integration_test_win recipe: devicelab/devicelab_drone @@ -4198,7 +4088,6 @@ targets: tags: > ["devicelab", "android", "windows"] task_name: channels_integration_test_win - scheduler: luci - name: Windows_android complex_layout_win__compile recipe: devicelab/devicelab_drone @@ -4212,17 +4101,16 @@ targets: [ {"dependency": "open_jdk", "version": "11"} ] - scheduler: luci - name: Windows_android flavors_test_win recipe: devicelab/devicelab_drone + bringup: true # Flaky: https://github.com/flutter/flutter/issues/107681 presubmit: false timeout: 60 properties: tags: > ["devicelab", "android", "windows"] task_name: flavors_test_win - scheduler: luci - name: Windows_android flutter_gallery_win__compile recipe: devicelab/devicelab_drone @@ -4232,7 +4120,6 @@ targets: tags: > ["devicelab", "android", "windows"] task_name: flutter_gallery_win__compile - scheduler: luci - name: Windows_android hot_mode_dev_cycle_win__benchmark recipe: devicelab/devicelab_drone @@ -4242,7 +4129,6 @@ targets: tags: > ["devicelab", "android", "windows"] task_name: hot_mode_dev_cycle_win__benchmark - scheduler: luci - name: Windows_android windows_chrome_dev_mode recipe: devicelab/devicelab_drone @@ -4252,4 +4138,3 @@ targets: tags: > ["devicelab", "android", "windows"] task_name: windows_chrome_dev_mode - scheduler: luci diff --git a/.github/ISSUE_TEMPLATE/7_cherry_pick.yml b/.github/ISSUE_TEMPLATE/7_cherry_pick.yml index 4e6e4c4c5d4ee..8b0f66b2f7d90 100644 --- a/.github/ISSUE_TEMPLATE/7_cherry_pick.yml +++ b/.github/ISSUE_TEMPLATE/7_cherry_pick.yml @@ -27,6 +27,15 @@ body: - beta validations: required: true + - type: input + id: pr_link + attributes: + label: pr_link + description: >- + Link to an open PR that cherrypick's this into the target release branch. + The current branches can be found under release-caniddate-branch.version for [beta](https://github.com/flutter/flutter/blob/beta/bin/internal/release-candidate-branch.version) and [stable](https://github.com/flutter/flutter/blob/stable/bin/internal/release-candidate-branch.version) + validations: + required: true - type: input id: impacted_users attributes: diff --git a/analysis_options.yaml b/analysis_options.yaml index c884b4afffc2d..6680f5c4f6595 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -94,6 +94,7 @@ linter: # - cascade_invocations # doesn't match the typical style of this repo - cast_nullable_to_non_nullable # - close_sinks # not reliable enough + - combinators_ordering # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 # - conditional_uri_does_not_exist # not yet tested # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 @@ -103,6 +104,7 @@ linter: - deprecated_consistency # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) - directives_ordering + # - discarded_futures # not yet tested # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic - empty_catches - empty_constructor_bodies @@ -113,7 +115,6 @@ linter: - flutter_style_todos - hash_and_equals - implementation_imports - # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 - iterable_contains_unrelated_type # - join_return_with_assignment # not required by flutter style - leading_newlines_in_multiline_strings @@ -211,6 +212,7 @@ linter: - unnecessary_late - unnecessary_new - unnecessary_null_aware_assignments + - unnecessary_null_aware_operator_on_extension_on_nullable - unnecessary_null_checks - unnecessary_null_in_if_null_operators - unnecessary_nullable_for_final_variable_declarations @@ -221,6 +223,7 @@ linter: - unnecessary_string_escapes - unnecessary_string_interpolations - unnecessary_this + - unnecessary_to_list_in_spreads - unrelated_type_equality_checks - unsafe_html - use_build_context_synchronously diff --git a/bin/internal/engine.version b/bin/internal/engine.version index 92956ab29f8a9..210070603680f 100644 --- a/bin/internal/engine.version +++ b/bin/internal/engine.version @@ -1 +1 @@ -257b05fda9bf30993d2b0cc11932c740c52386a3 +7d173c544f6f4e568a8267a41034fe3695077c76 diff --git a/bin/internal/flutter_plugins.version b/bin/internal/flutter_plugins.version index f22abed73d392..2eb24333bc0da 100644 --- a/bin/internal/flutter_plugins.version +++ b/bin/internal/flutter_plugins.version @@ -1 +1 @@ -1d2cc3aa286ce6b8fb8abded23e54b0dae2628ef +28eff0a8c167d146d73d62aa21a7d93d95bc2578 diff --git a/bin/internal/fuchsia-mac.version b/bin/internal/fuchsia-mac.version index 06f407e9f1ae5..cd7e92e953433 100644 --- a/bin/internal/fuchsia-mac.version +++ b/bin/internal/fuchsia-mac.version @@ -1 +1 @@ -P-UIastCYMR2-tuUVa8hZoycryHWmDuDG0FkAJX5NdEC +EsvgHFU05HD8n0Vdwf1T6066K6rwJNWZh-NS15SG5XgC diff --git a/dev/benchmarks/macrobenchmarks/macos/Podfile b/dev/benchmarks/macrobenchmarks/macos/Podfile index dade8dfad0dcf..fe733905db657 100644 --- a/dev/benchmarks/macrobenchmarks/macos/Podfile +++ b/dev/benchmarks/macrobenchmarks/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.13' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/dev/benchmarks/macrobenchmarks/macos/Runner.xcodeproj/project.pbxproj b/dev/benchmarks/macrobenchmarks/macos/Runner.xcodeproj/project.pbxproj index 8581681a2126c..c219f2103aa87 100644 --- a/dev/benchmarks/macrobenchmarks/macos/Runner.xcodeproj/project.pbxproj +++ b/dev/benchmarks/macrobenchmarks/macos/Runner.xcodeproj/project.pbxproj @@ -399,7 +399,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -478,7 +478,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -525,7 +525,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/dev/benchmarks/macrobenchmarks/pubspec.yaml b/dev/benchmarks/macrobenchmarks/pubspec.yaml index f855aebdd5842..86994e4038d3d 100644 --- a/dev/benchmarks/macrobenchmarks/pubspec.yaml +++ b/dev/benchmarks/macrobenchmarks/pubspec.yaml @@ -18,7 +18,7 @@ dependencies: # flutter update-packages --force-upgrade flutter_gallery_assets: 1.0.2 - url_launcher: 6.1.4 + url_launcher: 6.1.5 archive: 3.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" async: 2.9.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -219,4 +219,4 @@ flutter: fonts: - asset: packages/flutter_gallery_assets/fonts/GalleryIcons.ttf -# PUBSPEC CHECKSUM: fd62 +# PUBSPEC CHECKSUM: 8b63 diff --git a/dev/benchmarks/test_apps/stocks/lib/main.dart b/dev/benchmarks/test_apps/stocks/lib/main.dart index e2334f763029e..8128be0dc6a4a 100644 --- a/dev/benchmarks/test_apps/stocks/lib/main.dart +++ b/dev/benchmarks/test_apps/stocks/lib/main.dart @@ -6,10 +6,10 @@ library stocks; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart' show - debugPaintSizeEnabled, debugPaintBaselinesEnabled, debugPaintLayerBordersEnabled, debugPaintPointersEnabled, + debugPaintSizeEnabled, debugRepaintRainbowEnabled; import 'i18n/stock_strings.dart'; diff --git a/dev/benchmarks/test_apps/stocks/lib/stock_home.dart b/dev/benchmarks/test_apps/stocks/lib/stock_home.dart index 72f8f67b5d237..197db62964e8f 100644 --- a/dev/benchmarks/test_apps/stocks/lib/stock_home.dart +++ b/dev/benchmarks/test_apps/stocks/lib/stock_home.dart @@ -4,7 +4,7 @@ import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart' show debugDumpRenderTree, debugDumpLayerTree, debugDumpSemanticsTree, DebugSemanticsDumpOrder; +import 'package:flutter/rendering.dart' show DebugSemanticsDumpOrder, debugDumpLayerTree, debugDumpRenderTree, debugDumpSemanticsTree; import 'package:flutter/scheduler.dart' show timeDilation; import 'i18n/stock_strings.dart'; diff --git a/dev/bots/prepare_package.dart b/dev/bots/prepare_package.dart index 8e4cb813407e9..fdd07a945aa66 100644 --- a/dev/bots/prepare_package.dart +++ b/dev/bots/prepare_package.dart @@ -12,7 +12,7 @@ import 'package:crypto/crypto.dart'; import 'package:crypto/src/digest_sink.dart'; import 'package:http/http.dart' as http; import 'package:path/path.dart' as path; -import 'package:platform/platform.dart' show Platform, LocalPlatform; +import 'package:platform/platform.dart' show LocalPlatform, Platform; import 'package:process/process.dart'; const String gobMirror = diff --git a/dev/bots/unpublish_package.dart b/dev/bots/unpublish_package.dart index 92ecf11716330..b8c79bc27b85e 100644 --- a/dev/bots/unpublish_package.dart +++ b/dev/bots/unpublish_package.dart @@ -17,7 +17,7 @@ import 'dart:io' hide Platform; import 'package:args/args.dart'; import 'package:path/path.dart' as path; -import 'package:platform/platform.dart' show Platform, LocalPlatform; +import 'package:platform/platform.dart' show LocalPlatform, Platform; import 'package:process/process.dart'; const String gsBase = 'gs://flutter_infra_release'; diff --git a/dev/conductor/core/lib/src/codesign.dart b/dev/conductor/core/lib/src/codesign.dart index eb3468766a861..eb9a49ab43ade 100644 --- a/dev/conductor/core/lib/src/codesign.dart +++ b/dev/conductor/core/lib/src/codesign.dart @@ -188,6 +188,7 @@ class CodesignCommand extends Command { 'artifacts/engine/darwin-x64/FlutterMacOS.framework/Versions/A/FlutterMacOS', 'artifacts/engine/darwin-x64/font-subset', 'artifacts/engine/darwin-x64/impellerc', + 'artifacts/engine/darwin-x64/libpath_ops.dylib', 'artifacts/engine/darwin-x64/libtessellator.dylib', 'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64/Flutter.framework/Flutter', 'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter', diff --git a/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart b/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart index 40196efd8c32b..8c4602c86867c 100644 --- a/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart +++ b/dev/devicelab/bin/tasks/native_platform_view_ui_tests_ios.dart @@ -10,6 +10,7 @@ import 'package:flutter_devicelab/framework/utils.dart'; import 'package:path/path.dart' as path; Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.ios; await task(() async { final String projectDirectory = '${flutterDirectory.path}/dev/integration_tests/ios_platform_view_tests'; diff --git a/dev/devicelab/lib/framework/browser.dart b/dev/devicelab/lib/framework/browser.dart index 293a3e4469b44..03de1085e75b9 100644 --- a/dev/devicelab/lib/framework/browser.dart +++ b/dev/devicelab/lib/framework/browser.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:convert' show json, utf8, LineSplitter, JsonEncoder; +import 'dart:convert' show JsonEncoder, LineSplitter, json, utf8; import 'dart:io' as io; import 'dart:math' as math; diff --git a/dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart b/dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart index a597b0f9c637f..d9a1f3ea8cc5b 100644 --- a/dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart +++ b/dev/devicelab/lib/tasks/entrypoint_dart_registrant.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' show Process, ProcessSignal, Directory, File; +import 'dart:io' show Directory, File, Process, ProcessSignal; import '../framework/devices.dart'; import '../framework/framework.dart'; diff --git a/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart b/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart index 48d233c402007..5884297eda456 100644 --- a/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart +++ b/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io' show Process, Directory; +import 'dart:io' show Directory, Process; import 'package:path/path.dart' as path; diff --git a/dev/integration_tests/flutter_gallery/macos/Podfile b/dev/integration_tests/flutter_gallery/macos/Podfile index e8da8332969a1..85ce400a93014 100644 --- a/dev/integration_tests/flutter_gallery/macos/Podfile +++ b/dev/integration_tests/flutter_gallery/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.13' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/dev/integration_tests/flutter_gallery/macos/Podfile.lock b/dev/integration_tests/flutter_gallery/macos/Podfile.lock index ddad43d5ebaac..318a6dfff2d0f 100644 --- a/dev/integration_tests/flutter_gallery/macos/Podfile.lock +++ b/dev/integration_tests/flutter_gallery/macos/Podfile.lock @@ -26,10 +26,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: connectivity_macos: 5dae6ee11d320fac7c05f0d08bd08fc32b5514d9 - FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 + FlutterMacOS: ff8bbbdbe83c20fe0f90a7cc96f00cf753baf5cc Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - url_launcher_macos: 45af3d61de06997666568a7149c1be98b41c95d4 + url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3 -PODFILE CHECKSUM: b5c36ba411e4471a03727d0463fa17be341876c1 +PODFILE CHECKSUM: 8719e666d6ae56e47eb36dbc2c8341bbe936a0e6 -COCOAPODS: 1.11.2 +COCOAPODS: 1.11.3 diff --git a/dev/integration_tests/flutter_gallery/macos/Runner.xcodeproj/project.pbxproj b/dev/integration_tests/flutter_gallery/macos/Runner.xcodeproj/project.pbxproj index 018c7bec8a176..9d0f27a632c21 100644 --- a/dev/integration_tests/flutter_gallery/macos/Runner.xcodeproj/project.pbxproj +++ b/dev/integration_tests/flutter_gallery/macos/Runner.xcodeproj/project.pbxproj @@ -506,7 +506,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -585,7 +585,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -632,7 +632,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/dev/integration_tests/flutter_gallery/pubspec.yaml b/dev/integration_tests/flutter_gallery/pubspec.yaml index 6e0268bdf03b7..5d37701884b29 100644 --- a/dev/integration_tests/flutter_gallery/pubspec.yaml +++ b/dev/integration_tests/flutter_gallery/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: intl: 0.17.0 connectivity: 3.0.6 string_scanner: 1.1.1 - url_launcher: 6.1.4 + url_launcher: 6.1.5 cupertino_icons: 1.0.5 video_player: 2.2.11 scoped_model: @@ -276,4 +276,4 @@ flutter: - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf -# PUBSPEC CHECKSUM: 28de +# PUBSPEC CHECKSUM: 5adf diff --git a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml index f30918743b5e2..bb222c631c8c9 100644 --- a/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml +++ b/dev/integration_tests/gradle_deprecated_settings/pubspec.yaml @@ -7,12 +7,12 @@ environment: dependencies: flutter: sdk: flutter - camera: 0.9.8+1 + camera: 0.10.0 - camera_android: 0.9.8+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + camera_android: 0.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_avfoundation: 0.9.8+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" camera_platform_interface: 2.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - camera_web: 0.2.1+6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + camera_web: 0.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" characters: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" collection: 1.16.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" cross_file: 0.3.3+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -31,4 +31,4 @@ dependencies: flutter: uses-material-design: true -# PUBSPEC CHECKSUM: 81be +# PUBSPEC CHECKSUM: 3ee2 diff --git a/dev/integration_tests/ui/macos/Podfile b/dev/integration_tests/ui/macos/Podfile index dade8dfad0dcf..fe733905db657 100644 --- a/dev/integration_tests/ui/macos/Podfile +++ b/dev/integration_tests/ui/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.13' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/dev/integration_tests/ui/macos/Runner.xcodeproj/project.pbxproj b/dev/integration_tests/ui/macos/Runner.xcodeproj/project.pbxproj index aa8628ba995b5..4be2635eb548d 100644 --- a/dev/integration_tests/ui/macos/Runner.xcodeproj/project.pbxproj +++ b/dev/integration_tests/ui/macos/Runner.xcodeproj/project.pbxproj @@ -386,7 +386,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -465,7 +465,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -512,7 +512,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/dev/manual_tests/macos/Runner.xcodeproj/project.pbxproj b/dev/manual_tests/macos/Runner.xcodeproj/project.pbxproj index 1a4b4e8bace73..c24604d263f71 100644 --- a/dev/manual_tests/macos/Runner.xcodeproj/project.pbxproj +++ b/dev/manual_tests/macos/Runner.xcodeproj/project.pbxproj @@ -344,7 +344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -423,7 +423,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -470,7 +470,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/dev/tools/examples_smoke_test.dart b/dev/tools/examples_smoke_test.dart index bf974e8550f76..cfa2a5e0b07b0 100644 --- a/dev/tools/examples_smoke_test.dart +++ b/dev/tools/examples_smoke_test.dart @@ -9,7 +9,7 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' show stdout, stderr, exitCode, Process, ProcessException; +import 'dart:io' show Process, ProcessException, exitCode, stderr, stdout; import 'package:file/file.dart'; import 'package:file/local.dart'; diff --git a/examples/hello_world/macos/Runner.xcodeproj/project.pbxproj b/examples/hello_world/macos/Runner.xcodeproj/project.pbxproj index f4083e1e6f7b4..a202f1042adb2 100644 --- a/examples/hello_world/macos/Runner.xcodeproj/project.pbxproj +++ b/examples/hello_world/macos/Runner.xcodeproj/project.pbxproj @@ -344,7 +344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -423,7 +423,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -470,7 +470,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/examples/image_list/macos/Runner.xcodeproj/project.pbxproj b/examples/image_list/macos/Runner.xcodeproj/project.pbxproj index 65e1baa895ba6..b5cd08891afc0 100644 --- a/examples/image_list/macos/Runner.xcodeproj/project.pbxproj +++ b/examples/image_list/macos/Runner.xcodeproj/project.pbxproj @@ -344,7 +344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -423,7 +423,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -470,7 +470,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/examples/layers/macos/Runner.xcodeproj/project.pbxproj b/examples/layers/macos/Runner.xcodeproj/project.pbxproj index bb1f36ef69f2a..6d9718e3b3e64 100644 --- a/examples/layers/macos/Runner.xcodeproj/project.pbxproj +++ b/examples/layers/macos/Runner.xcodeproj/project.pbxproj @@ -344,7 +344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -422,7 +422,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -469,7 +469,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/packages/flutter/lib/painting.dart b/packages/flutter/lib/painting.dart index ddd3aee58ce91..572391a93d570 100644 --- a/packages/flutter/lib/painting.dart +++ b/packages/flutter/lib/painting.dart @@ -17,7 +17,7 @@ /// painting boxes. library painting; -export 'dart:ui' show Shadow, PlaceholderAlignment, TextHeightBehavior, TextLeadingDistribution; +export 'dart:ui' show PlaceholderAlignment, Shadow, TextHeightBehavior, TextLeadingDistribution; export 'src/painting/alignment.dart'; export 'src/painting/basic_types.dart'; diff --git a/packages/flutter/lib/rendering.dart b/packages/flutter/lib/rendering.dart index 2bda350eba1b7..b0029c160fca6 100644 --- a/packages/flutter/lib/rendering.dart +++ b/packages/flutter/lib/rendering.dart @@ -22,11 +22,11 @@ library rendering; export 'package:flutter/foundation.dart' show - VoidCallback, + DiagnosticLevel, ValueChanged, ValueGetter, ValueSetter, - DiagnosticLevel; + VoidCallback; export 'package:flutter/semantics.dart'; export 'package:vector_math/vector_math_64.dart' show Matrix4; diff --git a/packages/flutter/lib/src/cupertino/colors.dart b/packages/flutter/lib/src/cupertino/colors.dart index 329a39d4bbd17..41fe80ea0fd14 100644 --- a/packages/flutter/lib/src/cupertino/colors.dart +++ b/packages/flutter/lib/src/cupertino/colors.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show Color, Brightness; +import 'dart:ui' show Brightness, Color; import '../../foundation.dart'; import '../widgets/basic.dart'; diff --git a/packages/flutter/lib/src/cupertino/context_menu.dart b/packages/flutter/lib/src/cupertino/context_menu.dart index f74ab0b46429a..9dc484033eeff 100644 --- a/packages/flutter/lib/src/cupertino/context_menu.dart +++ b/packages/flutter/lib/src/cupertino/context_menu.dart @@ -6,7 +6,7 @@ import 'dart:math' as math; import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; -import 'package:flutter/gestures.dart' show kMinFlingVelocity, kLongPressTimeout; +import 'package:flutter/gestures.dart' show kLongPressTimeout, kMinFlingVelocity; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; diff --git a/packages/flutter/lib/src/cupertino/route.dart b/packages/flutter/lib/src/cupertino/route.dart index f7908506e9a97..be5a629da3724 100644 --- a/packages/flutter/lib/src/cupertino/route.dart +++ b/packages/flutter/lib/src/cupertino/route.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:math'; -import 'dart:ui' show lerpDouble, ImageFilter; +import 'dart:ui' show ImageFilter, lerpDouble; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flutter/lib/src/cupertino/search_field.dart b/packages/flutter/lib/src/cupertino/search_field.dart index 83c0a1e79cca2..39920234f9578 100644 --- a/packages/flutter/lib/src/cupertino/search_field.dart +++ b/packages/flutter/lib/src/cupertino/search_field.dart @@ -11,7 +11,7 @@ import 'icons.dart'; import 'localizations.dart'; import 'text_field.dart'; -export 'package:flutter/services.dart' show SmartQuotesType, SmartDashesType; +export 'package:flutter/services.dart' show SmartDashesType, SmartQuotesType; /// A [CupertinoTextField] that mimics the look and behavior of UIKit's /// `UISearchTextField`. diff --git a/packages/flutter/lib/src/cupertino/text_field.dart b/packages/flutter/lib/src/cupertino/text_field.dart index 9a5e69dc7a0f0..24e1c105e3f38 100644 --- a/packages/flutter/lib/src/cupertino/text_field.dart +++ b/packages/flutter/lib/src/cupertino/text_field.dart @@ -16,7 +16,7 @@ import 'icons.dart'; import 'text_selection.dart'; import 'theme.dart'; -export 'package:flutter/services.dart' show TextInputType, TextInputAction, TextCapitalization, SmartQuotesType, SmartDashesType; +export 'package:flutter/services.dart' show SmartDashesType, SmartQuotesType, TextCapitalization, TextInputAction, TextInputType; const TextStyle _kDefaultPlaceholderStyle = TextStyle( fontWeight: FontWeight.w400, @@ -969,7 +969,7 @@ class _CupertinoTextFieldState extends State with Restoratio || cause == SelectionChangedCause.drag) { _editableText.bringIntoView(selection.extent); } - return; + break; case TargetPlatform.linux: case TargetPlatform.windows: case TargetPlatform.fuchsia: @@ -977,7 +977,21 @@ class _CupertinoTextFieldState extends State with Restoratio if (cause == SelectionChangedCause.drag) { _editableText.bringIntoView(selection.extent); } - return; + break; + } + + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.fuchsia: + case TargetPlatform.android: + break; + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + if (cause == SelectionChangedCause.drag) { + _editableText.hideToolbar(); + } + break; } } diff --git a/packages/flutter/lib/src/foundation/binding.dart b/packages/flutter/lib/src/foundation/binding.dart index f536b2daf3e22..87e95965f45fb 100644 --- a/packages/flutter/lib/src/foundation/binding.dart +++ b/packages/flutter/lib/src/foundation/binding.dart @@ -5,7 +5,7 @@ import 'dart:convert' show json; import 'dart:developer' as developer; import 'dart:io' show exit; -import 'dart:ui' as ui show SingletonFlutterWindow, Brightness, PlatformDispatcher, window; +import 'dart:ui' as ui show Brightness, PlatformDispatcher, SingletonFlutterWindow, window; // Before adding any more dart:ui imports, please read the README. import 'package:meta/meta.dart'; diff --git a/packages/flutter/lib/src/gestures/converter.dart b/packages/flutter/lib/src/gestures/converter.dart index 1e00d68207b1f..c871b40e51622 100644 --- a/packages/flutter/lib/src/gestures/converter.dart +++ b/packages/flutter/lib/src/gestures/converter.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. -import 'dart:ui' as ui show PointerData, PointerChange, PointerSignalKind; +import 'dart:ui' as ui show PointerChange, PointerData, PointerSignalKind; import 'events.dart'; @@ -216,7 +216,6 @@ class PointerEventConverter { return PointerPanZoomStartEvent( timeStamp: timeStamp, pointer: datum.pointerIdentifier, - kind: kind, device: datum.device, position: position, embedderId: datum.embedderId, @@ -230,7 +229,6 @@ class PointerEventConverter { return PointerPanZoomUpdateEvent( timeStamp: timeStamp, pointer: datum.pointerIdentifier, - kind: kind, device: datum.device, position: position, pan: pan, @@ -244,7 +242,6 @@ class PointerEventConverter { return PointerPanZoomEndEvent( timeStamp: timeStamp, pointer: datum.pointerIdentifier, - kind: kind, device: datum.device, position: position, embedderId: datum.embedderId, diff --git a/packages/flutter/lib/src/gestures/events.dart b/packages/flutter/lib/src/gestures/events.dart index 084d50df69f93..adeeee4834c0c 100644 --- a/packages/flutter/lib/src/gestures/events.dart +++ b/packages/flutter/lib/src/gestures/events.dart @@ -1035,7 +1035,10 @@ class PointerHoverEvent extends PointerEvent with _PointerEventDescription, _Cop super.tilt, super.synthesized, super.embedderId, - }) : super( + }) : // Dart doesn't support comparing enums with == in const contexts yet. + // https://github.com/dart-lang/language/issues/1811 + assert(!identical(kind, PointerDeviceKind.trackpad)), + super( down: false, pressure: 0.0, ); @@ -1153,7 +1156,8 @@ class PointerEnterEvent extends PointerEvent with _PointerEventDescription, _Cop super.down, super.synthesized, super.embedderId, - }) : super( + }) : assert(!identical(kind, PointerDeviceKind.trackpad)), + super( pressure: 0.0, ); @@ -1297,7 +1301,8 @@ class PointerExitEvent extends PointerEvent with _PointerEventDescription, _Copy super.down, super.synthesized, super.embedderId, - }) : super( + }) : assert(!identical(kind, PointerDeviceKind.trackpad)), + super( pressure: 0.0, ); @@ -1432,7 +1437,8 @@ class PointerDownEvent extends PointerEvent with _PointerEventDescription, _Copy super.orientation, super.tilt, super.embedderId, - }) : super( + }) : assert(!identical(kind, PointerDeviceKind.trackpad)), + super( down: true, distance: 0.0, ); @@ -1548,7 +1554,8 @@ class PointerMoveEvent extends PointerEvent with _PointerEventDescription, _Copy super.platformData, super.synthesized, super.embedderId, - }) : super( + }) : assert(!identical(kind, PointerDeviceKind.trackpad)), + super( down: true, distance: 0.0, ); @@ -1662,7 +1669,8 @@ class PointerUpEvent extends PointerEvent with _PointerEventDescription, _CopyPo super.orientation, super.tilt, super.embedderId, - }) : super( + }) : assert(!identical(kind, PointerDeviceKind.trackpad)), + super( down: false, ); @@ -1711,7 +1719,7 @@ abstract class PointerSignalEvent extends PointerEvent { super.device, super.position, super.embedderId, - }); + }) : assert(!identical(kind, PointerDeviceKind.trackpad)); } mixin _CopyPointerScrollEvent on PointerEvent { @@ -1849,9 +1857,9 @@ mixin _CopyPointerPanZoomStartEvent on PointerEvent { bool? synthesized, int? embedderId, }) { + assert(kind == null || identical(kind, PointerDeviceKind.trackpad)); return PointerPanZoomStartEvent( timeStamp: timeStamp ?? this.timeStamp, - kind: kind ?? this.kind, device: device ?? this.device, position: position ?? this.position, embedderId: embedderId ?? this.embedderId, @@ -1871,19 +1879,18 @@ class PointerPanZoomStartEvent extends PointerEvent with _PointerEventDescriptio /// All of the arguments must be non-null. const PointerPanZoomStartEvent({ super.timeStamp, - super.kind = PointerDeviceKind.mouse, super.device, super.pointer, super.position, super.embedderId, super.synthesized, }) : assert(timeStamp != null), - assert(kind != null), assert(device != null), assert(pointer != null), assert(position != null), assert(embedderId != null), - assert(synthesized != null); + assert(synthesized != null), + super(kind: PointerDeviceKind.trackpad); @override PointerPanZoomStartEvent transformed(Matrix4? transform) { @@ -1953,9 +1960,9 @@ mixin _CopyPointerPanZoomUpdateEvent on PointerEvent { double? scale, double? rotation, }) { + assert(kind == null || identical(kind, PointerDeviceKind.trackpad)); return PointerPanZoomUpdateEvent( timeStamp: timeStamp ?? this.timeStamp, - kind: kind ?? this.kind, device: device ?? this.device, position: position ?? this.position, embedderId: embedderId ?? this.embedderId, @@ -1979,7 +1986,6 @@ class PointerPanZoomUpdateEvent extends PointerEvent with _PointerEventDescripti /// All of the arguments must be non-null. const PointerPanZoomUpdateEvent({ super.timeStamp, - super.kind = PointerDeviceKind.mouse, super.device, super.pointer, super.position, @@ -1990,7 +1996,6 @@ class PointerPanZoomUpdateEvent extends PointerEvent with _PointerEventDescripti this.rotation = 0.0, super.synthesized, }) : assert(timeStamp != null), - assert(kind != null), assert(device != null), assert(pointer != null), assert(position != null), @@ -1999,7 +2004,9 @@ class PointerPanZoomUpdateEvent extends PointerEvent with _PointerEventDescripti assert(panDelta != null), assert(scale != null), assert(rotation != null), - assert(synthesized != null); + assert(synthesized != null), + super(kind: PointerDeviceKind.trackpad); + @override final Offset pan; @override @@ -2085,9 +2092,9 @@ mixin _CopyPointerPanZoomEndEvent on PointerEvent { bool? synthesized, int? embedderId, }) { + assert(kind == null || identical(kind, PointerDeviceKind.trackpad)); return PointerPanZoomEndEvent( timeStamp: timeStamp ?? this.timeStamp, - kind: kind ?? this.kind, device: device ?? this.device, position: position ?? this.position, embedderId: embedderId ?? this.embedderId, @@ -2107,19 +2114,18 @@ class PointerPanZoomEndEvent extends PointerEvent with _PointerEventDescription, /// All of the arguments must be non-null. const PointerPanZoomEndEvent({ super.timeStamp, - super.kind = PointerDeviceKind.mouse, super.device, super.pointer, super.position, super.embedderId, super.synthesized, }) : assert(timeStamp != null), - assert(kind != null), assert(device != null), assert(pointer != null), assert(position != null), assert(embedderId != null), - assert(synthesized != null); + assert(synthesized != null), + super(kind: PointerDeviceKind.trackpad); @override PointerPanZoomEndEvent transformed(Matrix4? transform) { @@ -2224,7 +2230,8 @@ class PointerCancelEvent extends PointerEvent with _PointerEventDescription, _Co super.orientation, super.tilt, super.embedderId, - }) : super( + }) : assert(!identical(kind, PointerDeviceKind.trackpad)), + super( down: false, pressure: 0.0, ); diff --git a/packages/flutter/lib/src/material/about.dart b/packages/flutter/lib/src/material/about.dart index 4e377d31efea2..01a406e74b0ac 100644 --- a/packages/flutter/lib/src/material/about.dart +++ b/packages/flutter/lib/src/material/about.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:developer' show Timeline, Flow; +import 'dart:developer' show Flow, Timeline; import 'dart:io' show Platform; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/lib/src/material/animated_icons.dart b/packages/flutter/lib/src/material/animated_icons.dart index 2f3c0ae5e13e5..659c66ba2c6ff 100644 --- a/packages/flutter/lib/src/material/animated_icons.dart +++ b/packages/flutter/lib/src/material/animated_icons.dart @@ -6,7 +6,7 @@ library material_animated_icons; import 'dart:math' as math show pi; -import 'dart:ui' as ui show Paint, Path, Canvas; +import 'dart:ui' as ui show Canvas, Paint, Path; import 'dart:ui' show lerpDouble; import 'package:flutter/foundation.dart' show clampDouble; diff --git a/packages/flutter/lib/src/material/icon_button.dart b/packages/flutter/lib/src/material/icon_button.dart index 3af465bca9f0a..df456ed848aa7 100644 --- a/packages/flutter/lib/src/material/icon_button.dart +++ b/packages/flutter/lib/src/material/icon_button.dart @@ -277,7 +277,7 @@ class IconButton extends StatelessWidget { /// IconButton( /// color: Colors.blue, /// onPressed: _handleTap, - /// icon: Icons.widgets, + /// icon: Icon(Icons.widgets), /// ) /// ``` final Color? color; diff --git a/packages/flutter/lib/src/material/input_date_picker_form_field.dart b/packages/flutter/lib/src/material/input_date_picker_form_field.dart index 3fcec07161001..ca334e12d232d 100644 --- a/packages/flutter/lib/src/material/input_date_picker_form_field.dart +++ b/packages/flutter/lib/src/material/input_date_picker_form_field.dart @@ -179,7 +179,7 @@ class _InputDatePickerFormFieldState extends State { if (_selectedDate != null) { final MaterialLocalizations localizations = MaterialLocalizations.of(context); _inputText = localizations.formatCompactDate(_selectedDate!); - TextEditingValue textEditingValue = _controller.value.copyWith(text: _inputText); + TextEditingValue textEditingValue = TextEditingValue(text: _inputText!); // Select the new text if we are auto focused and haven't selected the text before. if (widget.autofocus && !_autoSelected) { textEditingValue = textEditingValue.copyWith(selection: TextSelection( @@ -191,7 +191,7 @@ class _InputDatePickerFormFieldState extends State { _controller.value = textEditingValue; } else { _inputText = ''; - _controller.value = _controller.value.copyWith(text: _inputText); + _controller.value = TextEditingValue(text: _inputText!); } } diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart index dbbb4b2b50323..88bcff303ab2c 100644 --- a/packages/flutter/lib/src/material/input_decorator.dart +++ b/packages/flutter/lib/src/material/input_decorator.dart @@ -567,11 +567,11 @@ class _Decoration { required this.floatingLabelHeight, required this.floatingLabelProgress, required this.floatingLabelAlignment, - this.border, - this.borderGap, + required this.border, + required this.borderGap, required this.alignLabelWithHint, required this.isDense, - this.visualDensity, + required this.visualDensity, this.icon, this.input, this.label, @@ -594,11 +594,11 @@ class _Decoration { final double floatingLabelHeight; final double floatingLabelProgress; final FloatingLabelAlignment floatingLabelAlignment; - final InputBorder? border; - final _InputBorderGap? borderGap; + final InputBorder border; + final _InputBorderGap borderGap; final bool alignLabelWithHint; final bool? isDense; - final VisualDensity? visualDensity; + final VisualDensity visualDensity; final Widget? icon; final Widget? input; final Widget? label; @@ -788,14 +788,14 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin TextAlignVertical get _defaultTextAlignVertical => _isOutlineAligned ? TextAlignVertical.center : TextAlignVertical.top; - TextAlignVertical? get textAlignVertical => _textAlignVertical ?? _defaultTextAlignVertical; + TextAlignVertical get textAlignVertical => _textAlignVertical ?? _defaultTextAlignVertical; TextAlignVertical? _textAlignVertical; set textAlignVertical(TextAlignVertical? value) { if (_textAlignVertical == value) { return; } // No need to relayout if the effective value is still the same. - if (textAlignVertical!.y == (value?.y ?? _defaultTextAlignVertical.y)) { + if (textAlignVertical.y == (value?.y ?? _defaultTextAlignVertical.y)) { _textAlignVertical = value; return; } @@ -828,7 +828,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin // Indicates that the decoration should be aligned to accommodate an outline // border. bool get _isOutlineAligned { - return !decoration.isCollapsed && decoration.border!.isOutline; + return !decoration.isCollapsed && decoration.border.isOutline; } @override @@ -970,7 +970,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin // Increase the available width for the label when it is scaled down. final double invertedLabelScale = lerpDouble(1.00, 1 / _kFinalLabelScale, decoration.floatingLabelProgress)!; double suffixIconWidth = _boxSize(suffixIcon).width; - if (decoration.border!.isOutline) { + if (decoration.border.isOutline) { suffixIconWidth = lerpDouble(suffixIconWidth, 0.0, decoration.floatingLabelProgress)!; } final double labelWidth = math.max( @@ -1006,7 +1006,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin final double labelHeight = label == null ? 0 : decoration.floatingLabelHeight; - final double topHeight = decoration.border!.isOutline + final double topHeight = decoration.border.isOutline ? math.max(labelHeight - boxToBaseline[label]!, 0) : labelHeight; final double counterHeight = counter == null @@ -1021,7 +1021,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin counterHeight, helperErrorHeight, ); - final Offset densityOffset = decoration.visualDensity!.baseSizeAdjustment; + final Offset densityOffset = decoration.visualDensity.baseSizeAdjustment; boxToBaseline[input] = _layoutLineBox( input, boxConstraints.deflate(EdgeInsets.only( @@ -1034,8 +1034,8 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin ); // The field can be occupied by a hint or by the input itself - final double hintHeight = hint == null ? 0 : hint!.size.height; - final double inputDirectHeight = input == null ? 0 : input!.size.height; + final double hintHeight = hint?.size.height ?? 0; + final double inputDirectHeight = input?.size.height ?? 0; final double inputHeight = math.max(hintHeight, inputDirectHeight); final double inputInternalBaseline = math.max( boxToBaseline[input]!, @@ -1064,8 +1064,8 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin ); // Calculate the height of the input text container. - final double prefixIconHeight = prefixIcon == null ? 0 : prefixIcon!.size.height; - final double suffixIconHeight = suffixIcon == null ? 0 : suffixIcon!.size.height; + final double prefixIconHeight = prefixIcon?.size.height ?? 0; + final double suffixIconHeight = suffixIcon?.size.height ?? 0; final double fixIconHeight = math.max(prefixIconHeight, suffixIconHeight); final double contentHeight = math.max( fixIconHeight, @@ -1097,7 +1097,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin final double overflow = math.max(0, contentHeight - maxContainerHeight); // Map textAlignVertical from -1:1 to 0:1 so that it can be used to scale // the baseline from its minimum to maximum values. - final double textAlignVerticalFactor = (textAlignVertical!.y + 1.0) / 2.0; + final double textAlignVerticalFactor = (textAlignVertical.y + 1.0) / 2.0; // Adjust to try to fit top overflow inside the input on an inverse scale of // textAlignVertical, so that top aligned text adjusts the most and bottom // aligned text doesn't adjust at all. @@ -1137,7 +1137,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin outlineTopBaseline, outlineCenterBaseline, outlineBottomBaseline, - textAlignVertical!, + textAlignVertical, ); // Find the positions of the text below the input when it exists. @@ -1276,7 +1276,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin final double inputHeight = _lineHeight(availableInputWidth, [input, hint]); final double inputMaxHeight = [inputHeight, prefixHeight, suffixHeight].reduce(math.max); - final Offset densityOffset = decoration.visualDensity!.baseSizeAdjustment; + final Offset densityOffset = decoration.visualDensity.baseSizeAdjustment; final double contentHeight = contentPadding.top + (label == null ? 0.0 : decoration.floatingLabelHeight) + inputMaxHeight @@ -1337,15 +1337,15 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin _boxParentData(container!).offset = Offset(x, 0.0); } - double? height; + late double height; double centerLayout(RenderBox box, double x) { - _boxParentData(box).offset = Offset(x, (height! - box.size.height) / 2.0); + _boxParentData(box).offset = Offset(x, (height - box.size.height) / 2.0); return box.size.width; } - double? baseline; + late double baseline; double baselineLayout(RenderBox box, double x) { - _boxParentData(box).offset = Offset(x, baseline! - layout.boxToBaseline[box]!); + _boxParentData(box).offset = Offset(x, baseline - layout.boxToBaseline[box]!); return box.size.width; } @@ -1468,7 +1468,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin // _BorderContainer's x and is independent of label's x. switch (textDirection) { case TextDirection.rtl: - decoration.borderGap!.start = lerpDouble(labelX + _boxSize(label).width, + decoration.borderGap.start = lerpDouble(labelX + _boxSize(label).width, _boxSize(container).width / 2.0 + floatWidth / 2.0, floatAlign); @@ -1477,15 +1477,15 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin // The value of _InputBorderGap.start is relative to the origin of the // _BorderContainer which is inset by the icon's width. Although, when // floating label is centered, it's already relative to _BorderContainer. - decoration.borderGap!.start = lerpDouble(labelX - _boxSize(icon).width, + decoration.borderGap.start = lerpDouble(labelX - _boxSize(icon).width, _boxSize(container).width / 2.0 - floatWidth / 2.0, floatAlign); break; } - decoration.borderGap!.extent = label!.size.width * _kFinalLabelScale; + decoration.borderGap.extent = label!.size.width * _kFinalLabelScale; } else { - decoration.borderGap!.start = null; - decoration.borderGap!.extent = 0.0; + decoration.borderGap.start = null; + decoration.borderGap.extent = 0.0; } size = constraints.constrain(Size(overallWidth, overallHeight)); @@ -1513,11 +1513,11 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin // +1 shifts the range of x from (-1.0, 1.0) to (0.0, 2.0). final double floatAlign = decoration.floatingLabelAlignment._x + 1; final double floatWidth = labelWidth * _kFinalLabelScale; - final double borderWeight = decoration.border!.borderSide.width; + final double borderWeight = decoration.border.borderSide.width; final double t = decoration.floatingLabelProgress; // The center of the outline border label ends up a little below the // center of the top border line. - final bool isOutlineBorder = decoration.border != null && decoration.border!.isOutline; + final bool isOutlineBorder = decoration.border != null && decoration.border.isOutline; // Temporary opt-in fix for https://github.com/flutter/flutter/issues/54028 // Center the scaled label relative to the border. final double floatingY = isOutlineBorder ? (-labelHeight * _kFinalLabelScale) / 2.0 + borderWeight / 2.0 : contentPadding.top; @@ -1906,19 +1906,14 @@ class _InputDecoratorState extends State with TickerProviderStat } InputDecoration? _effectiveDecoration; - InputDecoration? get decoration { - _effectiveDecoration ??= widget.decoration.applyDefaults( - Theme.of(context).inputDecorationTheme, - ); - return _effectiveDecoration; - } + InputDecoration get decoration => _effectiveDecoration ??= widget.decoration.applyDefaults(Theme.of(context).inputDecorationTheme); TextAlign? get textAlign => widget.textAlign; bool get isFocused => widget.isFocused; - bool get isHovering => widget.isHovering && decoration!.enabled; + bool get isHovering => widget.isHovering && decoration.enabled; bool get isEmpty => widget.isEmpty; bool get _floatingLabelEnabled { - return decoration!.floatingLabelBehavior != FloatingLabelBehavior.never; + return decoration.floatingLabelBehavior != FloatingLabelBehavior.never; } @override @@ -1939,7 +1934,7 @@ class _InputDecoratorState extends State with TickerProviderStat } } - final String? errorText = decoration!.errorText; + final String? errorText = decoration.errorText; final String? oldErrorText = old.decoration.errorText; if (_floatingLabelController.isCompleted && errorText != null && errorText != oldErrorText) { @@ -1960,23 +1955,23 @@ class _InputDecoratorState extends State with TickerProviderStat if (isFocused) { return themeData.colorScheme.primary; } - if (decoration!.filled!) { + if (decoration.filled!) { return themeData.hintColor; } final Color enabledColor = themeData.colorScheme.onSurface.withOpacity(0.38); if (isHovering) { - final Color hoverColor = decoration!.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor; + final Color hoverColor = decoration.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor; return Color.alphaBlend(hoverColor.withOpacity(0.12), enabledColor); } return enabledColor; } Color _getFillColor(ThemeData themeData) { - if (decoration!.filled != true) { // filled == null same as filled == false + if (decoration.filled != true) { // filled == null same as filled == false return Colors.transparent; } - if (decoration!.fillColor != null) { - return MaterialStateProperty.resolveAs(decoration!.fillColor!, materialState); + if (decoration.fillColor != null) { + return MaterialStateProperty.resolveAs(decoration.fillColor!, materialState); } // dark theme: 10% white (enabled), 5% white (disabled) @@ -1988,17 +1983,17 @@ class _InputDecoratorState extends State with TickerProviderStat switch (themeData.brightness) { case Brightness.dark: - return decoration!.enabled ? darkEnabled : darkDisabled; + return decoration.enabled ? darkEnabled : darkDisabled; case Brightness.light: - return decoration!.enabled ? lightEnabled : lightDisabled; + return decoration.enabled ? lightEnabled : lightDisabled; } } Color _getHoverColor(ThemeData themeData) { - if (decoration!.filled == null || !decoration!.filled! || isFocused || !decoration!.enabled) { + if (decoration.filled == null || !decoration.filled! || isFocused || !decoration.enabled) { return Colors.transparent; } - return decoration!.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor; + return decoration.hoverColor ?? themeData.inputDecorationTheme.hoverColor ?? themeData.hoverColor; } Color _getIconColor(ThemeData themeData) { @@ -2038,8 +2033,8 @@ class _InputDecoratorState extends State with TickerProviderStat // hint would. bool get _hasInlineLabel { return !widget._labelShouldWithdraw - && (decoration!.labelText != null || decoration!.label != null) - && decoration!.floatingLabelBehavior != FloatingLabelBehavior.always; + && (decoration.labelText != null || decoration.label != null) + && decoration.floatingLabelBehavior != FloatingLabelBehavior.always; } // If the label is a floating placeholder, it's always shown. @@ -2049,10 +2044,10 @@ class _InputDecoratorState extends State with TickerProviderStat // i.e. when they appear in place of the empty text field. TextStyle _getInlineLabelStyle(ThemeData themeData) { final TextStyle defaultStyle = TextStyle( - color: decoration!.enabled ? themeData.hintColor : themeData.disabledColor, + color: decoration.enabled ? themeData.hintColor : themeData.disabledColor, ); - final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.labelStyle, materialState) + final TextStyle? style = MaterialStateProperty.resolveAs(decoration.labelStyle, materialState) ?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.labelStyle, materialState); return themeData.textTheme.subtitle1! @@ -2066,10 +2061,10 @@ class _InputDecoratorState extends State with TickerProviderStat // i.e. when they appear in place of the empty text field. TextStyle _getInlineHintStyle(ThemeData themeData) { final TextStyle defaultStyle = TextStyle( - color: decoration!.enabled ? themeData.hintColor : themeData.disabledColor, + color: decoration.enabled ? themeData.hintColor : themeData.disabledColor, ); - final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.hintStyle, materialState) + final TextStyle? style = MaterialStateProperty.resolveAs(decoration.hintStyle, materialState) ?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.hintStyle, materialState); return themeData.textTheme.subtitle1! @@ -2080,15 +2075,15 @@ class _InputDecoratorState extends State with TickerProviderStat TextStyle _getFloatingLabelStyle(ThemeData themeData) { TextStyle getFallbackTextStyle() { - final Color color = decoration!.errorText != null - ? decoration!.errorStyle?.color ?? themeData.errorColor + final Color color = decoration.errorText != null + ? decoration.errorStyle?.color ?? themeData.errorColor : _getActiveColor(themeData); - return TextStyle(color: decoration!.enabled ? color : themeData.disabledColor) - .merge(decoration!.floatingLabelStyle ?? decoration!.labelStyle); + return TextStyle(color: decoration.enabled ? color : themeData.disabledColor) + .merge(decoration.floatingLabelStyle ?? decoration.labelStyle); } - final TextStyle? style = MaterialStateProperty.resolveAs(decoration!.floatingLabelStyle, materialState) + final TextStyle? style = MaterialStateProperty.resolveAs(decoration.floatingLabelStyle, materialState) ?? MaterialStateProperty.resolveAs(themeData.inputDecorationTheme.floatingLabelStyle, materialState); return themeData.textTheme.subtitle1! @@ -2099,29 +2094,29 @@ class _InputDecoratorState extends State with TickerProviderStat } TextStyle _getHelperStyle(ThemeData themeData) { - final Color color = decoration!.enabled ? themeData.hintColor : Colors.transparent; - return themeData.textTheme.caption!.copyWith(color: color).merge(MaterialStateProperty.resolveAs(decoration!.helperStyle, materialState)); + final Color color = decoration.enabled ? themeData.hintColor : Colors.transparent; + return themeData.textTheme.caption!.copyWith(color: color).merge(MaterialStateProperty.resolveAs(decoration.helperStyle, materialState)); } TextStyle _getErrorStyle(ThemeData themeData) { - final Color color = decoration!.enabled ? themeData.errorColor : Colors.transparent; - return themeData.textTheme.caption!.copyWith(color: color).merge(decoration!.errorStyle); + final Color color = decoration.enabled ? themeData.errorColor : Colors.transparent; + return themeData.textTheme.caption!.copyWith(color: color).merge(decoration.errorStyle); } Set get materialState { return { - if (!decoration!.enabled) MaterialState.disabled, + if (!decoration.enabled) MaterialState.disabled, if (isFocused) MaterialState.focused, if (isHovering) MaterialState.hovered, - if (decoration!.errorText != null) MaterialState.error, + if (decoration.errorText != null) MaterialState.error, }; } InputBorder _getDefaultBorder(ThemeData themeData) { - final InputBorder border = MaterialStateProperty.resolveAs(decoration!.border, materialState) + final InputBorder border = MaterialStateProperty.resolveAs(decoration.border, materialState) ?? const UnderlineInputBorder(); - if (decoration!.border is MaterialStateProperty) { + if (decoration.border is MaterialStateProperty) { return border; } @@ -2130,18 +2125,18 @@ class _InputDecoratorState extends State with TickerProviderStat } final Color borderColor; - if (decoration!.enabled || isFocused) { - borderColor = decoration!.errorText == null + if (decoration.enabled || isFocused) { + borderColor = decoration.errorText == null ? _getDefaultBorderColor(themeData) : themeData.errorColor; } else { - borderColor = ((decoration!.filled ?? false) && !(decoration!.border?.isOutline ?? false)) + borderColor = ((decoration.filled ?? false) && !(decoration.border?.isOutline ?? false)) ? Colors.transparent : themeData.disabledColor; } final double borderWeight; - if (decoration!.isCollapsed || decoration?.border == InputBorder.none || !decoration!.enabled) { + if (decoration.isCollapsed || decoration.border == InputBorder.none || !decoration.enabled) { borderWeight = 0.0; } else { borderWeight = isFocused ? 2.0 : 1.0; @@ -2157,29 +2152,30 @@ class _InputDecoratorState extends State with TickerProviderStat final TextBaseline textBaseline = labelStyle.textBaseline!; final TextStyle hintStyle = _getInlineHintStyle(themeData); - final Widget? hint = decoration!.hintText == null ? null : AnimatedOpacity( + final String? hintText = decoration.hintText; + final Widget? hint = hintText == null ? null : AnimatedOpacity( opacity: (isEmpty && !_hasInlineLabel) ? 1.0 : 0.0, duration: _kTransitionDuration, curve: _kTransitionCurve, alwaysIncludeSemantics: true, child: Text( - decoration!.hintText!, + hintText, style: hintStyle, - textDirection: decoration!.hintTextDirection, + textDirection: decoration.hintTextDirection, overflow: TextOverflow.ellipsis, textAlign: textAlign, - maxLines: decoration!.hintMaxLines, + maxLines: decoration.hintMaxLines, ), ); - final bool isError = decoration!.errorText != null; + final bool isError = decoration.errorText != null; InputBorder? border; - if (!decoration!.enabled) { - border = isError ? decoration!.errorBorder : decoration!.disabledBorder; + if (!decoration.enabled) { + border = isError ? decoration.errorBorder : decoration.disabledBorder; } else if (isFocused) { - border = isError ? decoration!.focusedErrorBorder : decoration!.focusedBorder; + border = isError ? decoration.focusedErrorBorder : decoration.focusedBorder; } else { - border = isError ? decoration!.errorBorder : decoration!.enabledBorder; + border = isError ? decoration.errorBorder : decoration.enabledBorder; } border ??= _getDefaultBorder(themeData); @@ -2192,7 +2188,7 @@ class _InputDecoratorState extends State with TickerProviderStat isHovering: isHovering, ); - final Widget? label = decoration!.labelText == null && decoration!.label == null ? null : _Shaker( + final Widget? label = decoration.labelText == null && decoration.label == null ? null : _Shaker( animation: _shakingLabelController.view, child: AnimatedOpacity( duration: _kTransitionDuration, @@ -2204,8 +2200,8 @@ class _InputDecoratorState extends State with TickerProviderStat style: widget._labelShouldWithdraw ? _getFloatingLabelStyle(themeData) : labelStyle, - child: decoration!.label ?? Text( - decoration!.labelText!, + child: decoration.label ?? Text( + decoration.labelText!, overflow: TextOverflow.ellipsis, textAlign: textAlign, ), @@ -2213,27 +2209,27 @@ class _InputDecoratorState extends State with TickerProviderStat ), ); - final Widget? prefix = decoration!.prefix == null && decoration!.prefixText == null ? null : + final Widget? prefix = decoration.prefix == null && decoration.prefixText == null ? null : _AffixText( labelIsFloating: widget._labelShouldWithdraw, - text: decoration!.prefixText, - style: MaterialStateProperty.resolveAs(decoration!.prefixStyle, materialState) ?? hintStyle, - child: decoration!.prefix, + text: decoration.prefixText, + style: MaterialStateProperty.resolveAs(decoration.prefixStyle, materialState) ?? hintStyle, + child: decoration.prefix, ); - final Widget? suffix = decoration!.suffix == null && decoration!.suffixText == null ? null : + final Widget? suffix = decoration.suffix == null && decoration.suffixText == null ? null : _AffixText( labelIsFloating: widget._labelShouldWithdraw, - text: decoration!.suffixText, - style: MaterialStateProperty.resolveAs(decoration!.suffixStyle, materialState) ?? hintStyle, - child: decoration!.suffix, + text: decoration.suffixText, + style: MaterialStateProperty.resolveAs(decoration.suffixStyle, materialState) ?? hintStyle, + child: decoration.suffix, ); - final bool decorationIsDense = decoration!.isDense ?? false; + final bool decorationIsDense = decoration.isDense ?? false; final double iconSize = decorationIsDense ? 18.0 : 24.0; - final Widget? icon = decoration!.icon == null ? null : + final Widget? icon = decoration.icon == null ? null : Padding( padding: const EdgeInsetsDirectional.only(end: 16.0), child: IconTheme.merge( @@ -2241,16 +2237,16 @@ class _InputDecoratorState extends State with TickerProviderStat color: _getIconColor(themeData), size: iconSize, ), - child: decoration!.icon!, + child: decoration.icon!, ), ); - final Widget? prefixIcon = decoration!.prefixIcon == null ? null : + final Widget? prefixIcon = decoration.prefixIcon == null ? null : Center( widthFactor: 1.0, heightFactor: 1.0, child: ConstrainedBox( - constraints: decoration!.prefixIconConstraints ?? themeData.visualDensity.effectiveConstraints( + constraints: decoration.prefixIconConstraints ?? themeData.visualDensity.effectiveConstraints( const BoxConstraints( minWidth: kMinInteractiveDimension, minHeight: kMinInteractiveDimension, @@ -2261,17 +2257,17 @@ class _InputDecoratorState extends State with TickerProviderStat color: _getPrefixIconColor(themeData), size: iconSize, ), - child: decoration!.prefixIcon!, + child: decoration.prefixIcon!, ), ), ); - final Widget? suffixIcon = decoration!.suffixIcon == null ? null : + final Widget? suffixIcon = decoration.suffixIcon == null ? null : Center( widthFactor: 1.0, heightFactor: 1.0, child: ConstrainedBox( - constraints: decoration!.suffixIconConstraints ?? themeData.visualDensity.effectiveConstraints( + constraints: decoration.suffixIconConstraints ?? themeData.visualDensity.effectiveConstraints( const BoxConstraints( minWidth: kMinInteractiveDimension, minHeight: kMinInteractiveDimension, @@ -2282,33 +2278,33 @@ class _InputDecoratorState extends State with TickerProviderStat color: _getSuffixIconColor(themeData), size: iconSize, ), - child: decoration!.suffixIcon!, + child: decoration.suffixIcon!, ), ), ); final Widget helperError = _HelperError( textAlign: textAlign, - helperText: decoration!.helperText, + helperText: decoration.helperText, helperStyle: _getHelperStyle(themeData), - helperMaxLines: decoration!.helperMaxLines, - errorText: decoration!.errorText, + helperMaxLines: decoration.helperMaxLines, + errorText: decoration.errorText, errorStyle: _getErrorStyle(themeData), - errorMaxLines: decoration!.errorMaxLines, + errorMaxLines: decoration.errorMaxLines, ); Widget? counter; - if (decoration!.counter != null) { - counter = decoration!.counter; - } else if (decoration!.counterText != null && decoration!.counterText != '') { + if (decoration.counter != null) { + counter = decoration.counter; + } else if (decoration.counterText != null && decoration.counterText != '') { counter = Semantics( container: true, liveRegion: isFocused, child: Text( - decoration!.counterText!, - style: _getHelperStyle(themeData).merge(MaterialStateProperty.resolveAs(decoration!.counterStyle, materialState)), + decoration.counterText!, + style: _getHelperStyle(themeData).merge(MaterialStateProperty.resolveAs(decoration.counterStyle, materialState)), overflow: TextOverflow.ellipsis, - semanticsLabel: decoration!.semanticCounterText, + semanticsLabel: decoration.semanticCounterText, ), ); } @@ -2316,17 +2312,17 @@ class _InputDecoratorState extends State with TickerProviderStat // The _Decoration widget and _RenderDecoration assume that contentPadding // has been resolved to EdgeInsets. final TextDirection textDirection = Directionality.of(context); - final EdgeInsets? decorationContentPadding = decoration!.contentPadding?.resolve(textDirection); + final EdgeInsets? decorationContentPadding = decoration.contentPadding?.resolve(textDirection); final EdgeInsets contentPadding; final double floatingLabelHeight; - if (decoration!.isCollapsed) { + if (decoration.isCollapsed) { floatingLabelHeight = 0.0; contentPadding = decorationContentPadding ?? EdgeInsets.zero; } else if (!border.isOutline) { // 4.0: the vertical gap between the inline elements and the floating label. floatingLabelHeight = (4.0 + 0.75 * labelStyle.fontSize!) * MediaQuery.textScaleFactorOf(context); - if (decoration!.filled ?? false) { + if (decoration.filled ?? false) { contentPadding = decorationContentPadding ?? (decorationIsDense ? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0) : const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0)); @@ -2348,14 +2344,14 @@ class _InputDecoratorState extends State with TickerProviderStat final _Decorator decorator = _Decorator( decoration: _Decoration( contentPadding: contentPadding, - isCollapsed: decoration!.isCollapsed, + isCollapsed: decoration.isCollapsed, floatingLabelHeight: floatingLabelHeight, - floatingLabelAlignment: decoration!.floatingLabelAlignment!, + floatingLabelAlignment: decoration.floatingLabelAlignment!, floatingLabelProgress: _floatingLabelController.value, border: border, borderGap: _borderGap, - alignLabelWithHint: decoration!.alignLabelWithHint ?? false, - isDense: decoration!.isDense, + alignLabelWithHint: decoration.alignLabelWithHint ?? false, + isDense: decoration.isDense, visualDensity: themeData.visualDensity, icon: icon, input: widget.child, @@ -2376,7 +2372,7 @@ class _InputDecoratorState extends State with TickerProviderStat expands: widget.expands, ); - final BoxConstraints? constraints = decoration!.constraints ?? themeData.inputDecorationTheme.constraints; + final BoxConstraints? constraints = decoration.constraints ?? themeData.inputDecorationTheme.constraints; if (constraints != null) { return ConstrainedBox( constraints: constraints, diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index f9c3893c0c906..4b4ab9ea93a10 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -2029,7 +2029,7 @@ class ScaffoldState extends State with TickerProviderStateMixin, Resto bool get isEndDrawerOpen => _endDrawerOpened.value; void _drawerOpenedCallback(bool isOpened) { - if (_drawerOpened.value != isOpened) { + if (_drawerOpened.value != isOpened && _drawerKey.currentState != null) { setState(() { _drawerOpened.value = isOpened; }); @@ -2038,7 +2038,7 @@ class ScaffoldState extends State with TickerProviderStateMixin, Resto } void _endDrawerOpenedCallback(bool isOpened) { - if (_endDrawerOpened.value != isOpened) { + if (_endDrawerOpened.value != isOpened && _endDrawerKey.currentState != null) { setState(() { _endDrawerOpened.value = isOpened; }); diff --git a/packages/flutter/lib/src/material/text_field.dart b/packages/flutter/lib/src/material/text_field.dart index a7abaa8a068d0..e4b90e0540a3e 100644 --- a/packages/flutter/lib/src/material/text_field.dart +++ b/packages/flutter/lib/src/material/text_field.dart @@ -21,7 +21,7 @@ import 'selectable_text.dart' show iOSHorizontalOffset; import 'text_selection.dart'; import 'theme.dart'; -export 'package:flutter/services.dart' show TextInputType, TextInputAction, TextCapitalization, SmartQuotesType, SmartDashesType; +export 'package:flutter/services.dart' show SmartDashesType, SmartQuotesType, TextCapitalization, TextInputAction, TextInputType; /// Signature for the [TextField.buildCounter] callback. typedef InputCounterWidgetBuilder = Widget? Function( @@ -1063,7 +1063,7 @@ class _TextFieldState extends State with RestorationMixin implements || cause == SelectionChangedCause.drag) { _editableText?.bringIntoView(selection.extent); } - return; + break; case TargetPlatform.linux: case TargetPlatform.windows: case TargetPlatform.fuchsia: @@ -1071,7 +1071,21 @@ class _TextFieldState extends State with RestorationMixin implements if (cause == SelectionChangedCause.drag) { _editableText?.bringIntoView(selection.extent); } - return; + break; + } + + switch (Theme.of(context).platform) { + case TargetPlatform.iOS: + case TargetPlatform.fuchsia: + case TargetPlatform.android: + break; + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + if (cause == SelectionChangedCause.drag) { + _editableText?.hideToolbar(); + } + break; } } diff --git a/packages/flutter/lib/src/material/text_form_field.dart b/packages/flutter/lib/src/material/text_form_field.dart index a5332af041971..bf6d9563f18bd 100644 --- a/packages/flutter/lib/src/material/text_form_field.dart +++ b/packages/flutter/lib/src/material/text_form_field.dart @@ -9,7 +9,7 @@ import 'input_decorator.dart'; import 'text_field.dart'; import 'theme.dart'; -export 'package:flutter/services.dart' show SmartQuotesType, SmartDashesType; +export 'package:flutter/services.dart' show SmartDashesType, SmartQuotesType; /// A [FormField] that contains a [TextField]. /// diff --git a/packages/flutter/lib/src/painting/basic_types.dart b/packages/flutter/lib/src/painting/basic_types.dart index eac98937b5f9f..02933428b5517 100644 --- a/packages/flutter/lib/src/painting/basic_types.dart +++ b/packages/flutter/lib/src/painting/basic_types.dart @@ -23,9 +23,9 @@ export 'dart:ui' show Path, PathFillType, PathOperation, - Radius, RRect, RSTransform, + Radius, Rect, Shader, Size, @@ -43,8 +43,8 @@ export 'dart:ui' show VertexMode, // TODO(werainkhatri): remove these after their deprecation period in engine // https://github.com/flutter/flutter/pull/99505 - hashValues, // ignore: deprecated_member_use - hashList; // ignore: deprecated_member_use + hashList, // ignore: deprecated_member_use + hashValues; // ignore: deprecated_member_use export 'package:flutter/foundation.dart' show VoidCallback; diff --git a/packages/flutter/lib/src/painting/binding.dart b/packages/flutter/lib/src/painting/binding.dart index b58460dee01a6..28b2b72eb58cf 100644 --- a/packages/flutter/lib/src/painting/binding.dart +++ b/packages/flutter/lib/src/painting/binding.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show instantiateImageCodec, instantiateImageCodecFromBuffer, Codec, ImmutableBuffer; +import 'dart:ui' as ui show Codec, ImmutableBuffer, instantiateImageCodec, instantiateImageCodecFromBuffer; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show ServicesBinding; diff --git a/packages/flutter/lib/src/painting/clip.dart b/packages/flutter/lib/src/painting/clip.dart index 87956f285be4e..45d36bf5c605f 100644 --- a/packages/flutter/lib/src/painting/clip.dart +++ b/packages/flutter/lib/src/painting/clip.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show Canvas, Clip, Path, Paint, Rect, RRect, VoidCallback; +import 'dart:ui' show Canvas, Clip, Paint, Path, RRect, Rect, VoidCallback; /// Clip utilities used by [PaintingContext]. abstract class ClipContext { diff --git a/packages/flutter/lib/src/painting/debug.dart b/packages/flutter/lib/src/painting/debug.dart index a1b6491c6a5de..d158a0e021045 100644 --- a/packages/flutter/lib/src/painting/debug.dart +++ b/packages/flutter/lib/src/painting/debug.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:io'; -import 'dart:ui' show Size, Picture, Image; +import 'dart:ui' show Image, Picture, Size; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/lib/src/painting/edge_insets.dart b/packages/flutter/lib/src/painting/edge_insets.dart index 8072e659f3ff7..281f8c9da641c 100644 --- a/packages/flutter/lib/src/painting/edge_insets.dart +++ b/packages/flutter/lib/src/painting/edge_insets.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show lerpDouble, WindowPadding; +import 'dart:ui' as ui show WindowPadding, lerpDouble; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/lib/src/painting/image_provider.dart b/packages/flutter/lib/src/painting/image_provider.dart index d47110bc7c7fd..ff0ca9ff55e7e 100644 --- a/packages/flutter/lib/src/painting/image_provider.dart +++ b/packages/flutter/lib/src/painting/image_provider.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:ui' as ui show Codec, ImmutableBuffer; -import 'dart:ui' show Size, Locale, TextDirection; +import 'dart:ui' show Locale, Size, TextDirection; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; diff --git a/packages/flutter/lib/src/painting/image_stream.dart b/packages/flutter/lib/src/painting/image_stream.dart index c16963d02d7f9..1fee74b149492 100644 --- a/packages/flutter/lib/src/painting/image_stream.dart +++ b/packages/flutter/lib/src/painting/image_stream.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:ui' as ui show Image, Codec, FrameInfo; +import 'dart:ui' as ui show Codec, FrameInfo, Image; import 'package:flutter/foundation.dart'; import 'package:flutter/scheduler.dart'; diff --git a/packages/flutter/lib/src/painting/text_painter.dart b/packages/flutter/lib/src/painting/text_painter.dart index 2cbf171eb4490..ebead4e548745 100644 --- a/packages/flutter/lib/src/painting/text_painter.dart +++ b/packages/flutter/lib/src/painting/text_painter.dart @@ -2,8 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:math' show min, max; -import 'dart:ui' as ui show Paragraph, ParagraphBuilder, ParagraphConstraints, ParagraphStyle, PlaceholderAlignment, LineMetrics, TextHeightBehavior, TextStyle, BoxHeightStyle, BoxWidthStyle; +import 'dart:math' show max, min; +import 'dart:ui' as ui show + BoxHeightStyle, + BoxWidthStyle, + LineMetrics, + Paragraph, + ParagraphBuilder, + ParagraphConstraints, + ParagraphStyle, + PlaceholderAlignment, + TextHeightBehavior, + TextStyle; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; diff --git a/packages/flutter/lib/src/painting/text_span.dart b/packages/flutter/lib/src/painting/text_span.dart index cd84097f694f0..9a3a220a96c9d 100644 --- a/packages/flutter/lib/src/painting/text_span.dart +++ b/packages/flutter/lib/src/painting/text_span.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show ParagraphBuilder, Locale, StringAttribute, LocaleStringAttribute, SpellOutStringAttribute; +import 'dart:ui' as ui show Locale, LocaleStringAttribute, ParagraphBuilder, SpellOutStringAttribute, StringAttribute; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flutter/lib/src/painting/text_style.dart b/packages/flutter/lib/src/painting/text_style.dart index 862e87268c4b7..731769e197c12 100644 --- a/packages/flutter/lib/src/painting/text_style.dart +++ b/packages/flutter/lib/src/painting/text_style.dart @@ -2,7 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show ParagraphStyle, TextStyle, StrutStyle, lerpDouble, Shadow, FontFeature, FontVariation, TextHeightBehavior, TextLeadingDistribution; +import 'dart:ui' as ui show + FontFeature, + FontVariation, + ParagraphStyle, + Shadow, + StrutStyle, + TextHeightBehavior, + TextLeadingDistribution, + TextStyle, + lerpDouble; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/lib/src/rendering/editable.dart b/packages/flutter/lib/src/rendering/editable.dart index 9cc430ef462cb..d13844ddca46c 100644 --- a/packages/flutter/lib/src/rendering/editable.dart +++ b/packages/flutter/lib/src/rendering/editable.dart @@ -4,7 +4,7 @@ import 'dart:collection'; import 'dart:math' as math; -import 'dart:ui' as ui show TextBox, BoxHeightStyle, BoxWidthStyle, PlaceholderAlignment, LineMetrics; +import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, LineMetrics, PlaceholderAlignment, TextBox; import 'package:characters/characters.dart'; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index fd32cbf55227c..7f9dda15a55a3 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -14,7 +14,20 @@ import 'package:flutter/semantics.dart'; import 'debug.dart'; import 'layer.dart'; -export 'package:flutter/foundation.dart' show FlutterError, InformationCollector, DiagnosticsNode, ErrorSummary, ErrorDescription, ErrorHint, DiagnosticsProperty, StringProperty, DoubleProperty, EnumProperty, FlagProperty, IntProperty, DiagnosticPropertiesBuilder; +export 'package:flutter/foundation.dart' show + DiagnosticPropertiesBuilder, + DiagnosticsNode, + DiagnosticsProperty, + DoubleProperty, + EnumProperty, + ErrorDescription, + ErrorHint, + ErrorSummary, + FlagProperty, + FlutterError, + InformationCollector, + IntProperty, + StringProperty; export 'package:flutter/gestures.dart' show HitTestEntry, HitTestResult; export 'package:flutter/painting.dart'; diff --git a/packages/flutter/lib/src/rendering/paragraph.dart b/packages/flutter/lib/src/rendering/paragraph.dart index fdd3f360a7d94..74d4fe14cb86c 100644 --- a/packages/flutter/lib/src/rendering/paragraph.dart +++ b/packages/flutter/lib/src/rendering/paragraph.dart @@ -4,7 +4,7 @@ import 'dart:collection'; import 'dart:math' as math; -import 'dart:ui' as ui show Gradient, Shader, TextBox, PlaceholderAlignment, TextHeightBehavior, BoxHeightStyle, BoxWidthStyle; +import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Gradient, PlaceholderAlignment, Shader, TextBox, TextHeightBehavior; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index a5107bbd5751f..3b3bf47250979 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show ImageFilter, Gradient, Image, Color; +import 'dart:ui' as ui show Color, Gradient, Image, ImageFilter; import 'package:flutter/animation.dart'; import 'package:flutter/foundation.dart'; @@ -16,11 +16,11 @@ import 'layout_helper.dart'; import 'object.dart'; export 'package:flutter/gestures.dart' show - PointerEvent, + PointerCancelEvent, PointerDownEvent, + PointerEvent, PointerMoveEvent, - PointerUpEvent, - PointerCancelEvent; + PointerUpEvent; /// A base class for render boxes that resemble their children. /// diff --git a/packages/flutter/lib/src/rendering/view.dart b/packages/flutter/lib/src/rendering/view.dart index e3a86b871a35f..ff939fb65b2d7 100644 --- a/packages/flutter/lib/src/rendering/view.dart +++ b/packages/flutter/lib/src/rendering/view.dart @@ -4,7 +4,7 @@ import 'dart:developer'; import 'dart:io' show Platform; -import 'dart:ui' as ui show Scene, SceneBuilder, FlutterView; +import 'dart:ui' as ui show FlutterView, Scene, SceneBuilder; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index 67955033d232c..41dce5f7ff850 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -5,9 +5,9 @@ import 'dart:async'; import 'dart:collection'; import 'dart:developer' show Flow, Timeline, TimelineTask; -import 'dart:ui' show AppLifecycleState, FramePhase, FrameTiming, TimingsCallback, PlatformDispatcher; +import 'dart:ui' show AppLifecycleState, FramePhase, FrameTiming, PlatformDispatcher, TimingsCallback; -import 'package:collection/collection.dart' show PriorityQueue, HeapPriorityQueue; +import 'package:collection/collection.dart' show HeapPriorityQueue, PriorityQueue; import 'package:flutter/foundation.dart'; import 'debug.dart'; diff --git a/packages/flutter/lib/src/semantics/semantics.dart b/packages/flutter/lib/src/semantics/semantics.dart index bc20e0aaf2c9c..47fd86e703329 100644 --- a/packages/flutter/lib/src/semantics/semantics.dart +++ b/packages/flutter/lib/src/semantics/semantics.dart @@ -4,8 +4,7 @@ import 'dart:math' as math; import 'dart:ui' as ui; -import 'dart:ui' show Offset, Rect, SemanticsAction, SemanticsFlag, - TextDirection, StringAttribute; +import 'dart:ui' show Offset, Rect, SemanticsAction, SemanticsFlag, StringAttribute, TextDirection; import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart' show MatrixUtils, TransformProperty; diff --git a/packages/flutter/lib/src/services/hardware_keyboard.dart b/packages/flutter/lib/src/services/hardware_keyboard.dart index 493b4ed66e078..347ce9e94ec94 100644 --- a/packages/flutter/lib/src/services/hardware_keyboard.dart +++ b/packages/flutter/lib/src/services/hardware_keyboard.dart @@ -14,7 +14,7 @@ export 'dart:ui' show KeyData; export 'package:flutter/foundation.dart' show DiagnosticPropertiesBuilder; export 'keyboard_key.g.dart' show LogicalKeyboardKey, PhysicalKeyboardKey; -export 'raw_keyboard.dart' show RawKeyboard, RawKeyEvent; +export 'raw_keyboard.dart' show RawKeyEvent, RawKeyboard; /// Represents a lock mode of a keyboard, such as [KeyboardLockMode.capsLock]. /// diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart index 894b6df551604..8710c8beab8ba 100644 --- a/packages/flutter/lib/src/services/text_input.dart +++ b/packages/flutter/lib/src/services/text_input.dart @@ -7,8 +7,8 @@ import 'dart:io' show Platform; import 'dart:ui' show FontWeight, Offset, - Size, Rect, + Size, TextAlign, TextDirection; diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart index a4dc273626af8..6137714401727 100644 --- a/packages/flutter/lib/src/widgets/basic.dart +++ b/packages/flutter/lib/src/widgets/basic.dart @@ -26,8 +26,8 @@ export 'package:flutter/foundation.dart' show ValueNotifier; export 'package:flutter/painting.dart'; export 'package:flutter/rendering.dart' show - AlignmentTween, AlignmentGeometryTween, + AlignmentTween, Axis, BoxConstraints, BoxConstraintsTransform, @@ -45,7 +45,6 @@ export 'package:flutter/rendering.dart' show MainAxisAlignment, MainAxisSize, MouseCursor, - SystemMouseCursors, MultiChildLayoutDelegate, PaintingContext, PointerCancelEvent, @@ -63,6 +62,7 @@ export 'package:flutter/rendering.dart' show ShapeBorderClipper, SingleChildLayoutDelegate, StackFit, + SystemMouseCursors, TextOverflow, ValueChanged, ValueGetter, diff --git a/packages/flutter/lib/src/widgets/binding.dart b/packages/flutter/lib/src/widgets/binding.dart index c6b537bed44f9..a0c9a9cfff354 100644 --- a/packages/flutter/lib/src/widgets/binding.dart +++ b/packages/flutter/lib/src/widgets/binding.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'dart:developer' as developer; -import 'dart:ui' show AppLifecycleState, Locale, AccessibilityFeatures, FrameTiming, TimingsCallback, PlatformDispatcher; +import 'dart:ui' show AccessibilityFeatures, AppLifecycleState, FrameTiming, Locale, PlatformDispatcher, TimingsCallback; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart index dc1cb337517c8..37801f2765b20 100644 --- a/packages/flutter/lib/src/widgets/editable_text.dart +++ b/packages/flutter/lib/src/widgets/editable_text.dart @@ -38,7 +38,7 @@ import 'text_selection.dart'; import 'ticker_provider.dart'; import 'widget_span.dart'; -export 'package:flutter/services.dart' show SelectionChangedCause, TextEditingValue, TextSelection, TextInputType, SmartQuotesType, SmartDashesType; +export 'package:flutter/services.dart' show SelectionChangedCause, SmartDashesType, SmartQuotesType, TextEditingValue, TextInputType, TextSelection; /// Signature for the callback that reports when the user changes the selection /// (including the cursor location). @@ -2152,7 +2152,7 @@ class EditableTextState extends State with AutomaticKeepAliveClien @override void performPrivateCommand(String action, Map data) { - widget.onAppPrivateCommand!(action, data); + widget.onAppPrivateCommand?.call(action, data); } // The original position of the caret on FloatingCursorDragState.start. @@ -2184,6 +2184,9 @@ class EditableTextState extends State with AutomaticKeepAliveClien _floatingCursorResetController!.stop(); _onFloatingCursorResetTick(); } + // Stop cursor blinking and making it visible. + _stopCursorBlink(resetCharTicks: false); + _cursorBlinkOpacityController.value = 1.0; // We want to send in points that are centered around a (0,0) origin, so // we cache the position. _pointOffsetOrigin = point.offset; @@ -2204,6 +2207,8 @@ class EditableTextState extends State with AutomaticKeepAliveClien renderEditable.setFloatingCursor(point.state, _lastBoundedOffset!, _lastTextPosition!); break; case FloatingCursorDragState.End: + // Resume cursor blinking. + _startCursorBlink(); // We skip animation if no update has happened. if (_lastTextPosition != null && _lastBoundedOffset != null) { _floatingCursorResetController!.value = 0.0; diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 1e0e6ee0d7ceb..26b49a4c5eb5c 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -24,11 +24,11 @@ export 'package:flutter/foundation.dart' show protected, required, visibleForTesting; -export 'package:flutter/foundation.dart' show FlutterError, ErrorSummary, ErrorDescription, ErrorHint, debugPrint, debugPrintStack; -export 'package:flutter/foundation.dart' show VoidCallback, ValueChanged, ValueGetter, ValueSetter; -export 'package:flutter/foundation.dart' show DiagnosticsNode, DiagnosticLevel; +export 'package:flutter/foundation.dart' show ErrorDescription, ErrorHint, ErrorSummary, FlutterError, debugPrint, debugPrintStack; +export 'package:flutter/foundation.dart' show ValueChanged, ValueGetter, ValueSetter, VoidCallback; +export 'package:flutter/foundation.dart' show DiagnosticLevel, DiagnosticsNode; export 'package:flutter/foundation.dart' show Key, LocalKey, ValueKey; -export 'package:flutter/rendering.dart' show RenderObject, RenderBox, debugDumpRenderTree, debugDumpLayerTree; +export 'package:flutter/rendering.dart' show RenderBox, RenderObject, debugDumpLayerTree, debugDumpRenderTree; // Examples can assume: // late BuildContext context; diff --git a/packages/flutter/lib/src/widgets/gesture_detector.dart b/packages/flutter/lib/src/widgets/gesture_detector.dart index 7b51f8324aafc..23453645c7cf0 100644 --- a/packages/flutter/lib/src/widgets/gesture_detector.dart +++ b/packages/flutter/lib/src/widgets/gesture_detector.dart @@ -12,39 +12,39 @@ import 'media_query.dart'; export 'package:flutter/gestures.dart' show DragDownDetails, + DragEndDetails, DragStartDetails, DragUpdateDetails, - DragEndDetails, - GestureTapDownCallback, - GestureTapUpCallback, - GestureTapCallback, - GestureTapCancelCallback, - GestureLongPressCallback, - GestureLongPressStartCallback, - GestureLongPressMoveUpdateCallback, - GestureLongPressUpCallback, - GestureLongPressEndCallback, + ForcePressDetails, + GestureDragCancelCallback, GestureDragDownCallback, + GestureDragEndCallback, GestureDragStartCallback, GestureDragUpdateCallback, - GestureDragEndCallback, - GestureDragCancelCallback, - GestureScaleStartCallback, - GestureScaleUpdateCallback, - GestureScaleEndCallback, - GestureForcePressStartCallback, - GestureForcePressPeakCallback, GestureForcePressEndCallback, + GestureForcePressPeakCallback, + GestureForcePressStartCallback, GestureForcePressUpdateCallback, - LongPressStartDetails, - LongPressMoveUpdateDetails, + GestureLongPressCallback, + GestureLongPressEndCallback, + GestureLongPressMoveUpdateCallback, + GestureLongPressStartCallback, + GestureLongPressUpCallback, + GestureScaleEndCallback, + GestureScaleStartCallback, + GestureScaleUpdateCallback, + GestureTapCallback, + GestureTapCancelCallback, + GestureTapDownCallback, + GestureTapUpCallback, LongPressEndDetails, + LongPressMoveUpdateDetails, + LongPressStartDetails, + ScaleEndDetails, ScaleStartDetails, ScaleUpdateDetails, - ScaleEndDetails, TapDownDetails, TapUpDetails, - ForcePressDetails, Velocity; export 'package:flutter/rendering.dart' show RenderSemanticsGestureHandler; diff --git a/packages/flutter/lib/src/widgets/image.dart b/packages/flutter/lib/src/widgets/image.dart index 27f9b06d1ca21..39ef6bd311b3d 100644 --- a/packages/flutter/lib/src/widgets/image.dart +++ b/packages/flutter/lib/src/widgets/image.dart @@ -27,8 +27,8 @@ export 'package:flutter/painting.dart' show FilterQuality, ImageConfiguration, ImageInfo, - ImageStream, ImageProvider, + ImageStream, MemoryImage, NetworkImage; diff --git a/packages/flutter/lib/src/widgets/interactive_viewer.dart b/packages/flutter/lib/src/widgets/interactive_viewer.dart index e9cc1f0ca587c..69e1aa1957c1b 100644 --- a/packages/flutter/lib/src/widgets/interactive_viewer.dart +++ b/packages/flutter/lib/src/widgets/interactive_viewer.dart @@ -7,7 +7,7 @@ import 'dart:math' as math; import 'package:flutter/foundation.dart' show clampDouble; import 'package:flutter/gestures.dart'; import 'package:flutter/physics.dart'; -import 'package:vector_math/vector_math_64.dart' show Quad, Vector3, Matrix4; +import 'package:vector_math/vector_math_64.dart' show Matrix4, Quad, Vector3; import 'basic.dart'; import 'framework.dart'; diff --git a/packages/flutter/lib/src/widgets/overscroll_indicator.dart b/packages/flutter/lib/src/widgets/overscroll_indicator.dart index 124b0910c6623..148bfbc6543cd 100644 --- a/packages/flutter/lib/src/widgets/overscroll_indicator.dart +++ b/packages/flutter/lib/src/widgets/overscroll_indicator.dart @@ -6,7 +6,7 @@ import 'dart:async' show Timer; import 'dart:math' as math; import 'package:flutter/foundation.dart'; -import 'package:flutter/physics.dart' show nearEqual, Tolerance; +import 'package:flutter/physics.dart' show Tolerance, nearEqual; import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; diff --git a/packages/flutter/lib/src/widgets/page_view.dart b/packages/flutter/lib/src/widgets/page_view.dart index 911bb2cfaabf1..ba03778a69cf2 100644 --- a/packages/flutter/lib/src/widgets/page_view.dart +++ b/packages/flutter/lib/src/widgets/page_view.dart @@ -4,7 +4,7 @@ import 'dart:math' as math; -import 'package:flutter/foundation.dart' show precisionErrorTolerance, clampDouble; +import 'package:flutter/foundation.dart' show clampDouble, precisionErrorTolerance; import 'package:flutter/gestures.dart' show DragStartBehavior; import 'package:flutter/rendering.dart'; diff --git a/packages/flutter/lib/src/widgets/scroll_physics.dart b/packages/flutter/lib/src/widgets/scroll_physics.dart index 11c20c10c9fcf..6c66d9183c2f9 100644 --- a/packages/flutter/lib/src/widgets/scroll_physics.dart +++ b/packages/flutter/lib/src/widgets/scroll_physics.dart @@ -14,7 +14,7 @@ import 'overscroll_indicator.dart'; import 'scroll_metrics.dart'; import 'scroll_simulation.dart'; -export 'package:flutter/physics.dart' show Simulation, ScrollSpringSimulation, Tolerance; +export 'package:flutter/physics.dart' show ScrollSpringSimulation, Simulation, Tolerance; // Examples can assume: // class FooScrollPhysics extends ScrollPhysics { diff --git a/packages/flutter/lib/src/widgets/scrollbar.dart b/packages/flutter/lib/src/widgets/scrollbar.dart index 65a78084636e7..67d28bcf3dace 100644 --- a/packages/flutter/lib/src/widgets/scrollbar.dart +++ b/packages/flutter/lib/src/widgets/scrollbar.dart @@ -944,6 +944,7 @@ class RawScrollbar extends StatefulWidget { this.scrollbarOrientation, this.mainAxisMargin = 0.0, this.crossAxisMargin = 0.0, + this.padding, @Deprecated( 'Use thumbVisibility instead. ' 'This feature was deprecated after v2.9.0-1.0.pre.', @@ -1366,6 +1367,13 @@ class RawScrollbar extends StatefulWidget { /// Must not be null and defaults to 0. final double crossAxisMargin; + /// The insets by which the scrollbar thumb and track should be padded. + /// + /// When null, the inherited [MediaQueryData.padding] is used. + /// + /// Defaults to null. + final EdgeInsets? padding; + @override RawScrollbarState createState() => RawScrollbarState(); } @@ -1593,7 +1601,7 @@ class RawScrollbarState extends State with TickerProv ..textDirection = Directionality.of(context) ..thickness = widget.thickness ?? _kScrollbarThickness ..radius = widget.radius - ..padding = MediaQuery.of(context).padding + ..padding = widget.padding ?? MediaQuery.of(context).padding ..scrollbarOrientation = widget.scrollbarOrientation ..mainAxisMargin = widget.mainAxisMargin ..shape = widget.shape diff --git a/packages/flutter/lib/src/widgets/sliver.dart b/packages/flutter/lib/src/widgets/sliver.dart index 306c7fb3ee43a..3a49fea1a78bd 100644 --- a/packages/flutter/lib/src/widgets/sliver.dart +++ b/packages/flutter/lib/src/widgets/sliver.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:collection' show SplayTreeMap, HashMap; +import 'dart:collection' show HashMap, SplayTreeMap; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; diff --git a/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart b/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart index 7f3613a2daafe..8bbf6a56ef3db 100644 --- a/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart +++ b/packages/flutter/lib/src/widgets/slotted_render_object_widget.dart @@ -182,6 +182,15 @@ mixin SlottedContainerRenderObjectMixin on RenderBox { adoptChild(child); } } + + void _moveChild(RenderBox child, S slot, S oldSlot) { + assert(slot != oldSlot); + final RenderBox? oldChild = _slotToChild[oldSlot]; + if (oldChild == child) { + _setChild(null, oldSlot); + } + _setChild(child, slot); + } } /// Element used by the [SlottedMultiChildRenderObjectWidgetMixin]. @@ -189,7 +198,8 @@ class SlottedRenderObjectElement extends RenderObjectElement { /// Creates an element that uses the given widget as its configuration. SlottedRenderObjectElement(SlottedMultiChildRenderObjectWidgetMixin super.widget); - final Map _slotToChild = {}; + Map _slotToChild = {}; + Map _keyedChildren = {}; @override SlottedContainerRenderObjectMixin get renderObject => super.renderObject as SlottedContainerRenderObjectMixin; @@ -231,21 +241,73 @@ class SlottedRenderObjectElement extends RenderObjectElement { }(), '${widget.runtimeType}.slots must not change.'); assert(slottedMultiChildRenderObjectWidgetMixin.slots.toSet().length == slottedMultiChildRenderObjectWidgetMixin.slots.length, 'slots must be unique'); + final Map oldKeyedElements = _keyedChildren; + _keyedChildren = {}; + final Map oldSlotToChild = _slotToChild; + _slotToChild = {}; + + Map>? debugDuplicateKeys; + for (final S slot in slottedMultiChildRenderObjectWidgetMixin.slots) { - _updateChild(slottedMultiChildRenderObjectWidgetMixin.childForSlot(slot), slot); + final Widget? widget = slottedMultiChildRenderObjectWidgetMixin.childForSlot(slot); + final Key? newWidgetKey = widget?.key; + + final Element? oldSlotChild = oldSlotToChild[slot]; + final Element? oldKeyChild = oldKeyedElements[newWidgetKey]; + + // Try to find the slot for the correct Element that `widget` should update. + // If key matching fails, resort to `oldSlotChild` from the same slot. + final Element? fromElement; + if (oldKeyChild != null) { + fromElement = oldSlotToChild.remove(oldKeyChild.slot as S); + } else if (oldSlotChild?.widget.key == null) { + fromElement = oldSlotToChild.remove(slot); + } else { + // The only case we can't use `oldSlotChild` is when its widget has a key. + assert(oldSlotChild!.widget.key != newWidgetKey); + fromElement = null; + } + final Element? newChild = updateChild(fromElement, widget, slot); + + if (newChild != null) { + _slotToChild[slot] = newChild; + + if (newWidgetKey != null) { + assert(() { + final Element? existingElement = _keyedChildren[newWidgetKey]; + if (existingElement != null) { + (debugDuplicateKeys ??= >{}) + .putIfAbsent(newWidgetKey, () => [existingElement]) + .add(newChild); + } + return true; + }()); + _keyedChildren[newWidgetKey] = newChild; + } + } } + oldSlotToChild.values.forEach(deactivateChild); + assert(_debugDuplicateKeys(debugDuplicateKeys)); + assert(_keyedChildren.values.every(_slotToChild.values.contains), '_keyedChildren ${_keyedChildren.values} should be a subset of ${_slotToChild.values}'); } - void _updateChild(Widget? widget, S slot) { - final Element? oldChild = _slotToChild[slot]; - assert(oldChild == null || oldChild.slot == slot); // Reason why [moveRenderObjectChild] is not reachable. - final Element? newChild = updateChild(oldChild, widget, slot); - if (oldChild != null) { - _slotToChild.remove(slot); + bool _debugDuplicateKeys(Map>? debugDuplicateKeys) { + if (debugDuplicateKeys == null) { + return true; } - if (newChild != null) { - _slotToChild[slot] = newChild; + for (final MapEntry> duplicateKey in debugDuplicateKeys.entries) { + throw FlutterError.fromParts([ + ErrorSummary('Multiple widgets used the same key in ${widget.runtimeType}.'), + ErrorDescription( + 'The key ${duplicateKey.key} was used by multiple widgets. The parents of those widgets were:\n' + ), + for (final Element element in duplicateKey.value) ErrorDescription(' - $element\n'), + ErrorDescription( + 'A key can only be specified on one widget at a time in the same parent widget.', + ), + ]); } + return true; } @override @@ -256,14 +318,14 @@ class SlottedRenderObjectElement extends RenderObjectElement { @override void removeRenderObjectChild(RenderBox child, S slot) { - assert(renderObject._slotToChild[slot] == child); - renderObject._setChild(null, slot); - assert(renderObject._slotToChild[slot] == null); + if (renderObject._slotToChild[slot] == child) { + renderObject._setChild(null, slot); + assert(renderObject._slotToChild[slot] == null); + } } @override - void moveRenderObjectChild(RenderBox child, Object? oldSlot, Object? newSlot) { - // Existing elements are never moved to a new slot, see assert in [_updateChild]. - assert(false, 'not reachable'); + void moveRenderObjectChild(RenderBox child, S oldSlot, S newSlot) { + renderObject._moveChild(child, newSlot, oldSlot); } } diff --git a/packages/flutter/test/cupertino/text_field_test.dart b/packages/flutter/test/cupertino/text_field_test.dart index 88cdd5b365456..464a880e4e39a 100644 --- a/packages/flutter/test/cupertino/text_field_test.dart +++ b/packages/flutter/test/cupertino/text_field_test.dart @@ -16,7 +16,7 @@ import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Color; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter/gestures.dart' show DragStartBehavior, PointerDeviceKind, kSecondaryMouseButton, kDoubleTapTimeout; +import 'package:flutter/gestures.dart' show DragStartBehavior, PointerDeviceKind, kDoubleTapTimeout, kSecondaryMouseButton; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; @@ -155,7 +155,6 @@ class PathPointsMatcher extends Matcher { } } - void main() { TestWidgetsFlutterBinding.ensureInitialized(); final MockClipboard mockClipboard = MockClipboard(); @@ -4080,6 +4079,53 @@ void main() { expect(find.byType(CupertinoTextSelectionToolbar), findsOneWidget); expect(tester.takeException(), null); }); + + testWidgets('Drag selection hides the selection menu', (WidgetTester tester) async { + final TextEditingController controller = TextEditingController( + text: 'blah1 blah2', + ); + await tester.pumpWidget( + CupertinoApp( + home: Center( + child: CupertinoTextField( + controller: controller, + ), + ), + ), + ); + + // Initially, the menu is not shown and there is no selection. + expect(controller.selection, const TextSelection(baseOffset: -1, extentOffset: -1)); + final Offset midBlah1 = textOffsetToPosition(tester, 2); + final Offset midBlah2 = textOffsetToPosition(tester, 8); + + // Right click the second word. + final TestGesture gesture = await tester.startGesture( + midBlah2, + kind: PointerDeviceKind.mouse, + buttons: kSecondaryMouseButton, + ); + await tester.pump(); + await gesture.up(); + await tester.pumpAndSettle(); + + // The toolbar is shown. + expect(find.text('Paste'), findsOneWidget); + + // Drag the mouse to the first word. + final TestGesture gesture2 = await tester.startGesture( + midBlah1, + kind: PointerDeviceKind.mouse, + ); + await tester.pump(); + await gesture2.moveTo(midBlah2); + await tester.pump(); + await gesture2.up(); + await tester.pumpAndSettle(); + + // The toolbar is hidden. + expect(find.text('Paste'), findsNothing); + }, variant: TargetPlatformVariant.desktop()); }, skip: isContextMenuProvidedByPlatform); // [intended] only applies to platforms where we supply the context menu. group('textAlignVertical position', () { @@ -4509,6 +4555,7 @@ void main() { }, ); }); + testWidgets("Arrow keys don't move input focus", (WidgetTester tester) async { final TextEditingController controller1 = TextEditingController(); final TextEditingController controller2 = TextEditingController(); diff --git a/packages/flutter/test/cupertino/text_selection_test.dart b/packages/flutter/test/cupertino/text_selection_test.dart index ead287a227f56..9941e8b8deed9 100644 --- a/packages/flutter/test/cupertino/text_selection_test.dart +++ b/packages/flutter/test/cupertino/text_selection_test.dart @@ -16,7 +16,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import '../widgets/clipboard_utils.dart'; -import '../widgets/editable_text_utils.dart' show textOffsetToPosition, findRenderEditable; +import '../widgets/editable_text_utils.dart' show findRenderEditable, textOffsetToPosition; class _LongCupertinoLocalizationsDelegate extends LocalizationsDelegate { const _LongCupertinoLocalizationsDelegate(); diff --git a/packages/flutter/test/gestures/drag_test.dart b/packages/flutter/test/gestures/drag_test.dart index c6ef908a81b29..829f684c8211a 100644 --- a/packages/flutter/test/gestures/drag_test.dart +++ b/packages/flutter/test/gestures/drag_test.dart @@ -1507,7 +1507,7 @@ void main() { didEndPan = true; }; - final TestPointer pointer = TestPointer(2); + final TestPointer pointer = TestPointer(2, PointerDeviceKind.trackpad); final PointerPanZoomStartEvent start = pointer.panZoomStart(const Offset(10.0, 10.0)); pan.addPointerPanZoom(start); competingPan.addPointerPanZoom(start); @@ -1564,7 +1564,7 @@ void main() { didEndPan = true; }; - final TestPointer panZoomPointer = TestPointer(2); + final TestPointer panZoomPointer = TestPointer(2, PointerDeviceKind.trackpad); final TestPointer touchPointer = TestPointer(3); final PointerPanZoomStartEvent start = panZoomPointer.panZoomStart(const Offset(10.0, 10.0)); pan.addPointerPanZoom(start); @@ -1641,7 +1641,7 @@ testGesture('Touch drags should allow pointer pan/zooms to join them', (GestureT didEndPan = true; }; - final TestPointer panZoomPointer = TestPointer(2); + final TestPointer panZoomPointer = TestPointer(2, PointerDeviceKind.trackpad); final TestPointer touchPointer = TestPointer(3); final PointerDownEvent touchDown = touchPointer.down(const Offset(20.0, 20.0)); pan.addPointer(touchDown); diff --git a/packages/flutter/test/gestures/scale_test.dart b/packages/flutter/test/gestures/scale_test.dart index e02823a39dd50..ea601fc0c139c 100644 --- a/packages/flutter/test/gestures/scale_test.dart +++ b/packages/flutter/test/gestures/scale_test.dart @@ -732,7 +732,7 @@ void main() { didEndScale = true; }; - final TestPointer pointer1 = TestPointer(2); + final TestPointer pointer1 = TestPointer(2, PointerDeviceKind.trackpad); final PointerPanZoomStartEvent start = pointer1.panZoomStart(Offset.zero); scale.addPointerPanZoom(start); @@ -836,7 +836,7 @@ void main() { final TestPointer touchPointer1 = TestPointer(2); final TestPointer touchPointer2 = TestPointer(3); - final TestPointer panZoomPointer = TestPointer(4); + final TestPointer panZoomPointer = TestPointer(4, PointerDeviceKind.trackpad); final PointerPanZoomStartEvent panZoomStart = panZoomPointer.panZoomStart(Offset.zero); scale.addPointerPanZoom(panZoomStart); @@ -985,7 +985,7 @@ void main() { drag.onStart = (DragStartDetails details) { log.add('drag-start'); }; drag.onEnd = (DragEndDetails details) { log.add('drag-end'); }; - final TestPointer pointer1 = TestPointer(2); + final TestPointer pointer1 = TestPointer(2, PointerDeviceKind.trackpad); final PointerPanZoomStartEvent down = pointer1.panZoomStart(const Offset(10.0, 10.0)); scale.addPointerPanZoom(down); @@ -1004,7 +1004,7 @@ void main() { expect(log, equals(['scale-start', 'scale-update'])); log.clear(); - final TestPointer pointer2 = TestPointer(3); + final TestPointer pointer2 = TestPointer(3, PointerDeviceKind.trackpad); final PointerPanZoomStartEvent down2 = pointer2.panZoomStart(const Offset(10.0, 20.0)); scale.addPointerPanZoom(down2); drag.addPointerPanZoom(down2); @@ -1033,7 +1033,7 @@ void main() { // TODO(ianh): https://github.com/flutter/flutter/issues/11384 // In this case, we move fast, so that the scale wins. If we moved slowly, // the horizontal drag would win, since it was added first. - final TestPointer pointer3 = TestPointer(4); + final TestPointer pointer3 = TestPointer(4, PointerDeviceKind.trackpad); final PointerPanZoomStartEvent down3 = pointer3.panZoomStart(const Offset(30.0, 30.0)); scale.addPointerPanZoom(down3); drag.addPointerPanZoom(down3); @@ -1084,7 +1084,7 @@ void main() { didEndScale = true; }; - final TestPointer pointer1 = TestPointer(2); + final TestPointer pointer1 = TestPointer(2, PointerDeviceKind.trackpad); final PointerPanZoomStartEvent start = pointer1.panZoomStart(Offset.zero); scale.addPointerPanZoom(start); diff --git a/packages/flutter/test/material/drawer_test.dart b/packages/flutter/test/material/drawer_test.dart index 0fe90959bc7bc..4c9aa6db94ece 100644 --- a/packages/flutter/test/material/drawer_test.dart +++ b/packages/flutter/test/material/drawer_test.dart @@ -422,6 +422,87 @@ void main() { expect(find.text('Drawer'), findsNothing); }); + testWidgets('Disposing drawer does not crash if drawer is open and framework is locked', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/34978 + addTearDown(tester.binding.window.clearPhysicalSizeTestValue); + tester.binding.window.physicalSizeTestValue = const Size(1800.0, 2400.0); + + await tester.pumpWidget( + MaterialApp( + home: OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { + switch (orientation) { + case Orientation.portrait: + return Scaffold( + drawer: const Text('drawer'), + body: Container(), + ); + case Orientation.landscape: + return Scaffold( + appBar: AppBar(), + body: Container(), + ); + } + }, + ), + ), + ); + + expect(find.text('drawer'), findsNothing); + + // Using a global key is a workaround for this issue. + final ScaffoldState portraitScaffoldState = tester.firstState(find.byType(Scaffold)); + portraitScaffoldState.openDrawer(); + await tester.pumpAndSettle(); + expect(find.text('drawer'), findsOneWidget); + + // Change the orientation and cause the drawer controller to be disposed + // while the framework is locked. + tester.binding.window.physicalSizeTestValue = const Size(2400.0, 1800.0); + await tester.pumpAndSettle(); + expect(find.byType(BackButton), findsNothing); + }); + + testWidgets('Disposing endDrawer does not crash if endDrawer is open and framework is locked', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/34978 + addTearDown(tester.binding.window.clearPhysicalSizeTestValue); + tester.binding.window.physicalSizeTestValue = const Size(1800.0, 2400.0); + + await tester.pumpWidget( + MaterialApp( + home: OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { + switch (orientation) { + case Orientation.portrait: + return Scaffold( + endDrawer: const Text('endDrawer'), + body: Container(), + ); + case Orientation.landscape: + return Scaffold( + appBar: AppBar(), + body: Container(), + ); + } + }, + ), + ), + ); + + expect(find.text('endDrawer'), findsNothing); + + // Using a global key is a workaround for this issue. + final ScaffoldState portraitScaffoldState = tester.firstState(find.byType(Scaffold)); + portraitScaffoldState.openEndDrawer(); + await tester.pumpAndSettle(); + expect(find.text('endDrawer'), findsOneWidget); + + // Change the orientation and cause the drawer controller to be disposed + // while the framework is locked. + tester.binding.window.physicalSizeTestValue = const Size(2400.0, 1800.0); + await tester.pumpAndSettle(); + expect(find.byType(BackButton), findsNothing); + }); testWidgets('ScaffoldState close end drawer', (WidgetTester tester) async { final GlobalKey scaffoldKey = GlobalKey(); diff --git a/packages/flutter/test/material/input_date_picker_form_field_test.dart b/packages/flutter/test/material/input_date_picker_form_field_test.dart index d1432d4eb656c..43fe9c2d371b0 100644 --- a/packages/flutter/test/material/input_date_picker_form_field_test.dart +++ b/packages/flutter/test/material/input_date_picker_form_field_test.dart @@ -2,12 +2,33 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import '../widgets/clipboard_utils.dart'; +class TestMaterialLocalizations extends DefaultMaterialLocalizations { + @override + String formatCompactDate(DateTime date) { + return '${date.month}/${date.day}/${date.year}'; + } +} + +class TestMaterialLocalizationsDelegate extends LocalizationsDelegate { + @override + bool isSupported(Locale locale) => true; + + @override + Future load(Locale locale) { + return SynchronousFuture(TestMaterialLocalizations()); + } + + @override + bool shouldReload(TestMaterialLocalizationsDelegate old) => false; +} + void main() { TestWidgetsFlutterBinding.ensureInitialized(); final MockClipboard mockClipboard = MockClipboard(); @@ -27,9 +48,11 @@ void main() { bool autofocus = false, Key? formKey, ThemeData? theme, + Iterable>? localizationsDelegates, }) { return MaterialApp( theme: theme ?? ThemeData.from(colorScheme: const ColorScheme.light()), + localizationsDelegates: localizationsDelegates, home: Material( child: Form( key: formKey, @@ -300,5 +323,27 @@ void main() { expect(containerColor, equals(Colors.transparent)); }); + testWidgets('Date text localization', (WidgetTester tester) async { + final Iterable> delegates = >[ + TestMaterialLocalizationsDelegate(), + DefaultWidgetsLocalizations.delegate, + ]; + await tester.pumpWidget( + inputDatePickerField( + localizationsDelegates: delegates, + ) + ); + await tester.enterText(find.byType(TextField), '01/01/2022'); + await tester.pumpAndSettle(); + + // Verify that the widget can be updated to a new value after the + // entered text was transformed by the localization formatter. + await tester.pumpWidget( + inputDatePickerField( + initialDate: DateTime(2017), + localizationsDelegates: delegates, + ) + ); + }); }); } diff --git a/packages/flutter/test/material/popup_menu_test.dart b/packages/flutter/test/material/popup_menu_test.dart index 5745ebb329870..cfac72adc31bc 100644 --- a/packages/flutter/test/material/popup_menu_test.dart +++ b/packages/flutter/test/material/popup_menu_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show SemanticsFlag, DisplayFeature, DisplayFeatureType, DisplayFeatureState; +import 'dart:ui' show DisplayFeature, DisplayFeatureState, DisplayFeatureType, SemanticsFlag; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart index a7d5922d55899..34a5fa229db4a 100644 --- a/packages/flutter/test/material/text_field_test.dart +++ b/packages/flutter/test/material/text_field_test.dart @@ -24,7 +24,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import '../widgets/clipboard_utils.dart'; -import '../widgets/editable_text_utils.dart' show findRenderEditable, globalize, textOffsetToPosition, OverflowWidgetTextEditingController; +import '../widgets/editable_text_utils.dart' show OverflowWidgetTextEditingController, findRenderEditable, globalize, textOffsetToPosition; import '../widgets/semantics_tester.dart'; import 'feedback_tester.dart'; @@ -7658,6 +7658,56 @@ void main() { skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu., ); + testWidgets('Drag selection hides the selection menu', (WidgetTester tester) async { + final TextEditingController controller = TextEditingController( + text: 'blah1 blah2', + ); + await tester.pumpWidget( + MaterialApp( + home: Material( + child: TextField( + controller: controller, + ), + ), + ), + ); + + // Initially, the menu is not shown and there is no selection. + expect(controller.selection, const TextSelection(baseOffset: -1, extentOffset: -1)); + final Offset midBlah1 = textOffsetToPosition(tester, 2); + final Offset midBlah2 = textOffsetToPosition(tester, 8); + + // Right click the second word. + final TestGesture gesture = await tester.startGesture( + midBlah2, + kind: PointerDeviceKind.mouse, + buttons: kSecondaryMouseButton, + ); + await tester.pump(); + await gesture.up(); + await tester.pumpAndSettle(); + + // The toolbar is shown. + expect(find.text('Paste'), findsOneWidget); + + // Drag the mouse to the first word. + final TestGesture gesture2 = await tester.startGesture( + midBlah1, + kind: PointerDeviceKind.mouse, + ); + await tester.pump(); + await gesture2.moveTo(midBlah2); + await tester.pump(); + await gesture2.up(); + await tester.pumpAndSettle(); + + // The toolbar is hidden. + expect(find.text('Paste'), findsNothing); + }, + variant: TargetPlatformVariant.desktop(), + skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu. + ); + testWidgets( 'Long press on an autofocused field shows the selection menu', (WidgetTester tester) async { diff --git a/packages/flutter/test/painting/decoration_test.dart b/packages/flutter/test/painting/decoration_test.dart index 5ce14de9bc30b..c7f7ea9871d34 100644 --- a/packages/flutter/test/painting/decoration_test.dart +++ b/packages/flutter/test/painting/decoration_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:ui' as ui show Image, ColorFilter; +import 'dart:ui' as ui show ColorFilter, Image; import 'package:fake_async/fake_async.dart'; import 'package:flutter/foundation.dart'; diff --git a/packages/flutter/test/painting/image_stream_test.dart b/packages/flutter/test/painting/image_stream_test.dart index 954a442c2bf40..0f376c63ea99c 100644 --- a/packages/flutter/test/painting/image_stream_test.dart +++ b/packages/flutter/test/painting/image_stream_test.dart @@ -7,7 +7,7 @@ import 'dart:ui'; import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart'; -import 'package:flutter/scheduler.dart' show timeDilation, SchedulerBinding; +import 'package:flutter/scheduler.dart' show SchedulerBinding, timeDilation; import 'package:flutter_test/flutter_test.dart'; import '../image_data.dart'; diff --git a/packages/flutter/test/painting/text_style_test.dart b/packages/flutter/test/painting/text_style_test.dart index 80404ccda3fbe..60da595bf6e2a 100644 --- a/packages/flutter/test/painting/text_style_test.dart +++ b/packages/flutter/test/painting/text_style_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show TextStyle, ParagraphStyle, FontFeature, FontVariation, Shadow; +import 'dart:ui' as ui show FontFeature, FontVariation, ParagraphStyle, Shadow, TextStyle; import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart'; diff --git a/packages/flutter/test/rendering/mock_canvas.dart b/packages/flutter/test/rendering/mock_canvas.dart index 57a633737abf9..3f707688d402e 100644 --- a/packages/flutter/test/rendering/mock_canvas.dart +++ b/packages/flutter/test/rendering/mock_canvas.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show Paragraph, Image; +import 'dart:ui' as ui show Image, Paragraph; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; diff --git a/packages/flutter/test/rendering/paragraph_test.dart b/packages/flutter/test/rendering/paragraph_test.dart index deddef608757f..a8d12623678e4 100644 --- a/packages/flutter/test/rendering/paragraph_test.dart +++ b/packages/flutter/test/rendering/paragraph_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' as ui show TextBox, BoxHeightStyle, BoxWidthStyle, Paragraph; +import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Paragraph, TextBox; import 'package:flutter/gestures.dart'; import 'package:flutter/rendering.dart'; diff --git a/packages/flutter/test/rendering/rendering_tester.dart b/packages/flutter/test/rendering/rendering_tester.dart index afeaca5007bd0..e14dbee6a8457 100644 --- a/packages/flutter/test/rendering/rendering_tester.dart +++ b/packages/flutter/test/rendering/rendering_tester.dart @@ -9,10 +9,10 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart' show TestDefaultBinaryMessengerBinding, EnginePhase, fail; +import 'package:flutter_test/flutter_test.dart' show EnginePhase, TestDefaultBinaryMessengerBinding, fail; export 'package:flutter/foundation.dart' show FlutterError, FlutterErrorDetails; -export 'package:flutter_test/flutter_test.dart' show TestDefaultBinaryMessengerBinding, EnginePhase; +export 'package:flutter_test/flutter_test.dart' show EnginePhase, TestDefaultBinaryMessengerBinding; class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, TestDefaultBinaryMessengerBinding { /// Creates a binding for testing rendering library functionality. diff --git a/packages/flutter/test/scheduler/time_dilation_test.dart b/packages/flutter/test/scheduler/time_dilation_test.dart index d4c134b1a4c29..a81cc4481017c 100644 --- a/packages/flutter/test/scheduler/time_dilation_test.dart +++ b/packages/flutter/test/scheduler/time_dilation_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/scheduler.dart'; -import 'package:flutter_test/flutter_test.dart' show test, expect; +import 'package:flutter_test/flutter_test.dart' show expect, test; // This file should not use testWidgets, and should not instantiate the binding. diff --git a/packages/flutter/test/widgets/editable_text_cursor_test.dart b/packages/flutter/test/widgets/editable_text_cursor_test.dart index 39388358b0c25..1708f82a86323 100644 --- a/packages/flutter/test/widgets/editable_text_cursor_test.dart +++ b/packages/flutter/test/widgets/editable_text_cursor_test.dart @@ -701,6 +701,73 @@ void main() { expect(tester.takeException(), null); }); + testWidgets("Drag the floating cursor, it won't blink.", (WidgetTester tester) async { + const String text = 'hello world this is fun and cool and awesome!'; + controller.text = text; + final FocusNode focusNode = FocusNode(); + + await tester.pumpWidget( + MediaQuery( + data: const MediaQueryData(), + child: Directionality( + textDirection: TextDirection.ltr, + child: FocusScope( + node: focusScopeNode, + autofocus: true, + child: EditableText( + backgroundCursorColor: Colors.grey, + controller: controller, + focusNode: focusNode, + style: textStyle, + cursorColor: cursorColor, + ), + ), + ), + ), + ); + + final EditableTextState editableText = tester.state(find.byType(EditableText)); + + // Check that the cursor visibility toggles after each blink interval. + // Or if it's not blinking at all, it stays on. + Future checkCursorBlinking({ bool isBlinking = true }) async { + bool initialShowCursor = true; + if (isBlinking) { + initialShowCursor = editableText.cursorCurrentlyVisible; + } + await tester.pump(editableText.cursorBlinkInterval); + expect(editableText.cursorCurrentlyVisible, equals(isBlinking ? !initialShowCursor : initialShowCursor)); + await tester.pump(editableText.cursorBlinkInterval); + expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor)); + await tester.pump(editableText.cursorBlinkInterval ~/ 10); + expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor)); + await tester.pump(editableText.cursorBlinkInterval); + expect(editableText.cursorCurrentlyVisible, equals(isBlinking ? !initialShowCursor : initialShowCursor)); + await tester.pump(editableText.cursorBlinkInterval); + expect(editableText.cursorCurrentlyVisible, equals(initialShowCursor)); + } + + final Offset textfieldStart = tester.getTopLeft(find.byType(EditableText)); + + await tester.tapAt(textfieldStart + const Offset(50.0, 9.0)); + await tester.pumpAndSettle(); + + // Before dragging, the cursor should blink. + await checkCursorBlinking(); + + final EditableTextState editableTextState = tester.firstState(find.byType(EditableText)); + editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start)); + + // When drag cursor, the cursor shouldn't blink. + await checkCursorBlinking(isBlinking: false); + + editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.End)); + await tester.pumpAndSettle(); + + // After dragging, the cursor should blink. + await checkCursorBlinking(); + }); + // Regression test for https://github.com/flutter/flutter/pull/30475. testWidgets('Trying to select with the floating cursor does not crash', (WidgetTester tester) async { const String text = 'hello world this is fun and cool and awesome!'; diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart index 55acff909ff5c..569c0f6e9a9b8 100644 --- a/packages/flutter/test/widgets/editable_text_test.dart +++ b/packages/flutter/test/widgets/editable_text_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:convert' show jsonDecode; import 'dart:ui' as ui; import 'package:flutter/cupertino.dart'; @@ -397,6 +398,53 @@ void main() { ); }); + testWidgets('onAppPrivateCommand does not throw', (WidgetTester tester) async { + await tester.pumpWidget( + MediaQuery( + data: const MediaQueryData(), + child: Directionality( + textDirection: TextDirection.ltr, + child: FocusScope( + node: focusScopeNode, + autofocus: true, + child: EditableText( + backgroundCursorColor: Colors.grey, + controller: controller, + focusNode: focusNode, + style: textStyle, + cursorColor: cursorColor, + ), + ), + ), + ), + ); + + await tester.tap(find.byType(EditableText)); + await tester.showKeyboard(find.byType(EditableText)); + controller.text = 'test'; + await tester.idle(); + + final ByteData? messageBytes = const JSONMessageCodec().encodeMessage({ + 'args': [ + -1, // The magic clint id that points to the current client. + jsonDecode('{"action": "actionCommand", "data": {"input_context" : "abcdefg"}}'), + ], + 'method': 'TextInputClient.performPrivateCommand', + }); + + Object? error; + try { + await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage( + 'flutter/textinput', + messageBytes, + (ByteData? _) {}, + ); + } catch (e) { + error = e; + } + expect(error, isNull); + }); + group('Infer keyboardType from autofillHints', () { testWidgets( 'infer keyboard types from autofillHints: ios', diff --git a/packages/flutter/test/widgets/interactive_viewer_test.dart b/packages/flutter/test/widgets/interactive_viewer_test.dart index 6834c56423b33..a10815047521e 100644 --- a/packages/flutter/test/widgets/interactive_viewer_test.dart +++ b/packages/flutter/test/widgets/interactive_viewer_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:vector_math/vector_math_64.dart' show Quad, Vector3, Matrix4; +import 'package:vector_math/vector_math_64.dart' show Matrix4, Quad, Vector3; import 'gesture_utils.dart'; diff --git a/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart b/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart index 690fbfcaa772d..8cbdb86c0a401 100644 --- a/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart +++ b/packages/flutter/test/widgets/list_wheel_scroll_view_test.dart @@ -11,7 +11,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import '../rendering/mock_canvas.dart'; -import '../rendering/rendering_tester.dart' show TestClipPaintingContext, TestCallbackPainter; +import '../rendering/rendering_tester.dart' show TestCallbackPainter, TestClipPaintingContext; void main() { testWidgets('ListWheelScrollView respects clipBehavior', (WidgetTester tester) async { diff --git a/packages/flutter/test/widgets/modal_barrier_test.dart b/packages/flutter/test/widgets/modal_barrier_test.dart index 30a05cb35e13b..4ac4aef061d5d 100644 --- a/packages/flutter/test/widgets/modal_barrier_test.dart +++ b/packages/flutter/test/widgets/modal_barrier_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter/gestures.dart' show kSecondaryButton, PointerDeviceKind; +import 'package:flutter/gestures.dart' show PointerDeviceKind, kSecondaryButton; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; diff --git a/packages/flutter/test/widgets/scrollbar_test.dart b/packages/flutter/test/widgets/scrollbar_test.dart index 6b98b3bb76121..1961dcd632824 100644 --- a/packages/flutter/test/widgets/scrollbar_test.dart +++ b/packages/flutter/test/widgets/scrollbar_test.dart @@ -2612,7 +2612,7 @@ void main() { // Go without throw. }); - testWidgets('Track offset respects padding', (WidgetTester tester) async { + testWidgets('Track offset respects MediaQuery padding', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/106834 final ScrollController scrollController = ScrollController(); await tester.pumpWidget( @@ -2640,7 +2640,39 @@ void main() { find.byType(RawScrollbar), paints ..rect(rect: const Rect.fromLTRB(744.0, 50.0, 750.0, 550.0)) // track - ..rect(rect: const Rect.fromLTRB(744.0, 50.0, 750.0, 71.0)) + ..rect(rect: const Rect.fromLTRB(744.0, 50.0, 750.0, 71.0)) // thumb + ); // thumb + }); + + testWidgets('RawScrollbar.padding replaces MediaQueryData.padding', (WidgetTester tester) async { + final ScrollController scrollController = ScrollController(); + await tester.pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: MediaQuery( + data: const MediaQueryData( + padding: EdgeInsets.all(50.0), + ), + child: RawScrollbar( + controller: scrollController, + minThumbLength: 21, + minOverscrollLength: 8, + thumbVisibility: true, + padding: const EdgeInsets.all(100), + child: SingleChildScrollView( + controller: scrollController, + child: const SizedBox(width: 1000.0, height: 50000.0), + ), + ), + ) + ) + ); + await tester.pumpAndSettle(); + expect( + find.byType(RawScrollbar), + paints + ..rect(rect: const Rect.fromLTRB(694.0, 100.0, 700.0, 500.0)) // track + ..rect(rect: const Rect.fromLTRB(694.0, 100.0, 700.0, 121.0)) // thumb ); // thumb }); } diff --git a/packages/flutter/test/widgets/semantics_tester.dart b/packages/flutter/test/widgets/semantics_tester.dart index 5cf5138cb7049..b6855a48f89d1 100644 --- a/packages/flutter/test/widgets/semantics_tester.dart +++ b/packages/flutter/test/widgets/semantics_tester.dart @@ -7,7 +7,7 @@ import 'package:flutter/physics.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; -export 'dart:ui' show SemanticsFlag, SemanticsAction; +export 'dart:ui' show SemanticsAction, SemanticsFlag; export 'package:flutter/rendering.dart' show SemanticsData; const String _matcherHelp = 'Try dumping the semantics with debugDumpSemanticsTree(DebugSemanticsDumpOrder.inverseHitTest) from the package:flutter/rendering.dart library to see what the semantics tree looks like.'; diff --git a/packages/flutter/test/widgets/slotted_render_object_widget_test.dart b/packages/flutter/test/widgets/slotted_render_object_widget_test.dart index 43f7bebfed5ea..7fc1a9ba62389 100644 --- a/packages/flutter/test/widgets/slotted_render_object_widget_test.dart +++ b/packages/flutter/test/widgets/slotted_render_object_widget_test.dart @@ -139,6 +139,72 @@ void main() { expect(_RenderTest().publicNameForSlot(slot), slot.toString()); }); + testWidgets('key reparenting', (WidgetTester tester) async { + const Widget widget1 = SizedBox(key: ValueKey('smol'), height: 10, width: 10); + const Widget widget2 = SizedBox(key: ValueKey('big'), height: 100, width: 100); + const Widget nullWidget = SizedBox(key: ValueKey('null'), height: 50, width: 50); + + await tester.pumpWidget(buildWidget(topLeft: widget1, bottomRight: widget2, nullSlot: nullWidget)); + final _RenderDiagonal renderObject = tester.renderObject(find.byType(_Diagonal)); + expect(renderObject._topLeft!.size, const Size(10, 10)); + expect(renderObject._bottomRight!.size, const Size(100, 100)); + expect(renderObject._nullSlot!.size, const Size(50, 50)); + + final Element widget1Element = tester.element(find.byWidget(widget1)); + final Element widget2Element = tester.element(find.byWidget(widget2)); + final Element nullWidgetElement = tester.element(find.byWidget(nullWidget)); + + // Swapping 1 and 2. + await tester.pumpWidget(buildWidget(topLeft: widget2, bottomRight: widget1, nullSlot: nullWidget)); + expect(renderObject._topLeft!.size, const Size(100, 100)); + expect(renderObject._bottomRight!.size, const Size(10, 10)); + expect(renderObject._nullSlot!.size, const Size(50, 50)); + expect(widget1Element, same(tester.element(find.byWidget(widget1)))); + expect(widget2Element, same(tester.element(find.byWidget(widget2)))); + expect(nullWidgetElement, same(tester.element(find.byWidget(nullWidget)))); + + // Shifting slots + await tester.pumpWidget(buildWidget(topLeft: nullWidget, bottomRight: widget2, nullSlot: widget1)); + expect(renderObject._topLeft!.size, const Size(50, 50)); + expect(renderObject._bottomRight!.size, const Size(100, 100)); + expect(renderObject._nullSlot!.size, const Size(10, 10)); + expect(widget1Element, same(tester.element(find.byWidget(widget1)))); + expect(widget2Element, same(tester.element(find.byWidget(widget2)))); + expect(nullWidgetElement, same(tester.element(find.byWidget(nullWidget)))); + + // Moving + Deleting. + await tester.pumpWidget(buildWidget(bottomRight: widget2)); + expect(renderObject._topLeft, null); + expect(renderObject._bottomRight!.size, const Size(100, 100)); + expect(renderObject._nullSlot, null); + expect(widget1Element.debugIsDefunct, isTrue); + expect(nullWidgetElement.debugIsDefunct, isTrue); + expect(widget2Element, same(tester.element(find.byWidget(widget2)))); + + // Moving. + await tester.pumpWidget(buildWidget(topLeft: widget2)); + expect(renderObject._topLeft!.size, const Size(100, 100)); + expect(renderObject._bottomRight, null); + expect(widget2Element, same(tester.element(find.byWidget(widget2)))); + }); + + testWidgets('duplicated key error message', (WidgetTester tester) async { + const Widget widget1 = SizedBox(key: ValueKey('widget 1'), height: 10, width: 10); + const Widget widget2 = SizedBox(key: ValueKey('widget 1'), height: 100, width: 100); + const Widget widget3 = SizedBox(key: ValueKey('widget 1'), height: 50, width: 50); + + await tester.pumpWidget(buildWidget(topLeft: widget1, bottomRight: widget2, nullSlot: widget3)); + + expect((tester.takeException() as FlutterError).toString(), equalsIgnoringHashCodes( + 'Multiple widgets used the same key in _Diagonal.\n' + "The key [<'widget 1'>] was used by multiple widgets. The parents of those widgets were:\n" + " - SizedBox-[<'widget 1'>](width: 50.0, height: 50.0, renderObject: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT)\n" + " - SizedBox-[<'widget 1'>](width: 10.0, height: 10.0, renderObject: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT)\n" + " - SizedBox-[<'widget 1'>](width: 100.0, height: 100.0, renderObject: RenderConstrainedBox#a4685 NEEDS-LAYOUT NEEDS-PAINT)\n" + 'A key can only be specified on one widget at a time in the same parent widget.' + )); + }); + testWidgets('debugDescribeChildren', (WidgetTester tester) async { await tester.pumpWidget(buildWidget( topLeft: const SizedBox( @@ -178,7 +244,7 @@ _RenderDiagonal#00000 relayoutBoundary=up1 }); } -Widget buildWidget({Widget? topLeft, Widget? bottomRight}) { +Widget buildWidget({Widget? topLeft, Widget? bottomRight, Widget? nullSlot}) { return Directionality( textDirection: TextDirection.ltr, child: Align( @@ -186,6 +252,7 @@ Widget buildWidget({Widget? topLeft, Widget? bottomRight}) { child: _Diagonal( topLeft: topLeft, bottomRight: bottomRight, + nullSlot: nullSlot, ), ), ); @@ -196,21 +263,25 @@ enum _DiagonalSlot { bottomRight, } -class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DiagonalSlot> { +class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DiagonalSlot?> { const _Diagonal({ this.topLeft, this.bottomRight, + this.nullSlot, }); final Widget? topLeft; final Widget? bottomRight; + final Widget? nullSlot; @override - Iterable<_DiagonalSlot> get slots => _DiagonalSlot.values; + Iterable<_DiagonalSlot?> get slots => <_DiagonalSlot?>[null, ..._DiagonalSlot.values]; @override - Widget? childForSlot(_DiagonalSlot slot) { + Widget? childForSlot(_DiagonalSlot? slot) { switch (slot) { + case null: + return nullSlot; case _DiagonalSlot.topLeft: return topLeft; case _DiagonalSlot.bottomRight: @@ -219,16 +290,17 @@ class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWid } @override - SlottedContainerRenderObjectMixin<_DiagonalSlot> createRenderObject( + SlottedContainerRenderObjectMixin<_DiagonalSlot?> createRenderObject( BuildContext context, ) { return _RenderDiagonal(); } } -class _RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<_DiagonalSlot> { +class _RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<_DiagonalSlot?> { RenderBox? get _topLeft => childForSlot(_DiagonalSlot.topLeft); RenderBox? get _bottomRight => childForSlot(_DiagonalSlot.bottomRight); + RenderBox? get _nullSlot => childForSlot(null); @override void performLayout() { @@ -251,9 +323,17 @@ class _RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<_ bottomRightSize = _bottomRight!.size; } + Size nullSlotSize = Size.zero; + final RenderBox? nullSlot = _nullSlot; + if (nullSlot != null) { + nullSlot.layout(childConstraints, parentUsesSize: true); + _positionChild(nullSlot, Offset.zero); + nullSlotSize = nullSlot.size; + } + size = constraints.constrain(Size( - topLeftSize.width + bottomRightSize.width, - topLeftSize.height + bottomRightSize.height, + topLeftSize.width + bottomRightSize.width + nullSlotSize.width, + topLeftSize.height + bottomRightSize.height + nullSlotSize.height, )); } diff --git a/packages/flutter/test_private/test/animated_icons_private_test.dart.tmpl b/packages/flutter/test_private/test/animated_icons_private_test.dart.tmpl index 96d23c4d4bbd2..af1d2c43368a6 100644 --- a/packages/flutter/test_private/test/animated_icons_private_test.dart.tmpl +++ b/packages/flutter/test_private/test/animated_icons_private_test.dart.tmpl @@ -12,8 +12,8 @@ library material_animated_icons; import 'dart:math' as math show pi; -import 'dart:ui' show lerpDouble, Offset; -import 'dart:ui' as ui show Paint, Path, Canvas; +import 'dart:ui' show Offset, lerpDouble; +import 'dart:ui' as ui show Canvas, Paint, Path; import 'package:flutter/foundation.dart' show clampDouble; import 'package:flutter/widgets.dart'; diff --git a/packages/flutter_driver/lib/src/common/error.dart b/packages/flutter_driver/lib/src/common/error.dart index 9c595e17aae16..698b78106abd6 100644 --- a/packages/flutter_driver/lib/src/common/error.dart +++ b/packages/flutter_driver/lib/src/common/error.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io' show stderr, FileSystemException; +import 'dart:io' show FileSystemException, stderr; /// Standard error thrown by Flutter Driver API. class DriverError extends Error { diff --git a/packages/flutter_driver/lib/src/driver/timeline_summary.dart b/packages/flutter_driver/lib/src/driver/timeline_summary.dart index ab64748f9ba6c..b364277d33e8c 100644 --- a/packages/flutter_driver/lib/src/driver/timeline_summary.dart +++ b/packages/flutter_driver/lib/src/driver/timeline_summary.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:convert' show json, JsonEncoder; +import 'dart:convert' show JsonEncoder, json; import 'dart:math' as math; import 'package:file/file.dart'; diff --git a/packages/flutter_test/lib/src/test_pointer.dart b/packages/flutter_test/lib/src/test_pointer.dart index bcd019512f186..efe36e20a8da9 100644 --- a/packages/flutter_test/lib/src/test_pointer.dart +++ b/packages/flutter_test/lib/src/test_pointer.dart @@ -314,12 +314,12 @@ class TestPointer { Duration timeStamp = Duration.zero }) { assert(!isPanZoomActive); + assert(kind == PointerDeviceKind.trackpad); _location = location; _pan = Offset.zero; _isPanZoomActive = true; return PointerPanZoomStartEvent( timeStamp: timeStamp, - kind: kind, device: _device, pointer: pointer, position: location, @@ -341,12 +341,12 @@ class TestPointer { Duration timeStamp = Duration.zero, }) { assert(isPanZoomActive); + assert(kind == PointerDeviceKind.trackpad); _location = location; final Offset panDelta = pan - _pan!; _pan = pan; return PointerPanZoomUpdateEvent( timeStamp: timeStamp, - kind: kind, device: _device, pointer: pointer, position: location, @@ -366,11 +366,11 @@ class TestPointer { Duration timeStamp = Duration.zero }) { assert(isPanZoomActive); + assert(kind == PointerDeviceKind.trackpad); _isPanZoomActive = false; _pan = null; return PointerPanZoomEndEvent( timeStamp: timeStamp, - kind: kind, device: _device, pointer: pointer, position: location!, diff --git a/packages/flutter_test/lib/src/widget_tester.dart b/packages/flutter_test/lib/src/widget_tester.dart index 2b4149d88de89..0b2e93f877e89 100644 --- a/packages/flutter_test/lib/src/widget_tester.dart +++ b/packages/flutter_test/lib/src/widget_tester.dart @@ -47,14 +47,14 @@ export 'package:flutter/rendering.dart' show SemanticsHandle; // that doesn't apply here. // ignore: deprecated_member_use export 'package:test_api/test_api.dart' hide - test, + expect, group, - setUpAll, - tearDownAll, + isInstanceOf, setUp, + setUpAll, tearDown, - expect, - isInstanceOf; + tearDownAll, + test; /// Signature for callback to [testWidgets] and [benchmarkWidgets]. typedef WidgetTesterCallback = Future Function(WidgetTester widgetTester); diff --git a/packages/flutter_test/test/goldens_test.dart b/packages/flutter_test/test/goldens_test.dart index c6c3ec4499e94..c421aedb09c11 100644 --- a/packages/flutter_test/test/goldens_test.dart +++ b/packages/flutter_test/test/goldens_test.dart @@ -7,7 +7,7 @@ import 'dart:io' as io; import 'dart:typed_data'; import 'package:file/memory.dart'; -import 'package:flutter/foundation.dart' show DiagnosticLevel, DiagnosticsNode, DiagnosticPropertiesBuilder, FlutterError; +import 'package:flutter/foundation.dart' show DiagnosticLevel, DiagnosticPropertiesBuilder, DiagnosticsNode, FlutterError; import 'package:flutter_test/flutter_test.dart' hide test; import 'package:flutter_test/flutter_test.dart' as test_package; diff --git a/packages/flutter_test/test/platform_dispatcher_test.dart b/packages/flutter_test/test/platform_dispatcher_test.dart index 361880e88c3f4..971c3b14ce761 100644 --- a/packages/flutter_test/test/platform_dispatcher_test.dart +++ b/packages/flutter_test/test/platform_dispatcher_test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:ui' show Locale, AccessibilityFeatures, Brightness, PlatformDispatcher; +import 'dart:ui' show AccessibilityFeatures, Brightness, Locale, PlatformDispatcher; import 'package:flutter/widgets.dart' show WidgetsBinding, WidgetsBindingObserver; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/flutter_test/test/window_test.dart b/packages/flutter_test/test/window_test.dart index 45875e251a5f5..255ac8aa333e0 100644 --- a/packages/flutter_test/test/window_test.dart +++ b/packages/flutter_test/test/window_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:ui' as ui show window; -import 'dart:ui' show Size, Locale, WindowPadding, AccessibilityFeatures, Brightness; +import 'dart:ui' show AccessibilityFeatures, Brightness, Locale, Size, WindowPadding; import 'package:flutter/widgets.dart' show WidgetsBinding, WidgetsBindingObserver; import 'package:flutter_test/flutter_test.dart'; diff --git a/packages/flutter_tools/bin/podhelper.rb b/packages/flutter_tools/bin/podhelper.rb index 972679c524e37..0c79bff922982 100644 --- a/packages/flutter_tools/bin/podhelper.rb +++ b/packages/flutter_tools/bin/podhelper.rb @@ -95,11 +95,11 @@ def flutter_additional_macos_build_settings(target) # [target.deployment_target] is a [String] formatted as "10.8". deployment_target_major, deployment_target_minor = target.deployment_target.match(/(\d+).?(\d*)/).captures - # Suppress warning when pod supports a version lower than the minimum supported by the latest stable version of Xcode (currently 10.9). + # Suppress warning when pod supports a version lower than the minimum supported by the latest stable version of Xcode (currently 10.13). # This warning is harmless but confusing--it's not a bad thing for dependencies to support a lower version. inherit_deployment_target = !target.deployment_target.blank? && (deployment_target_major.to_i < 10) || - (deployment_target_major.to_i == 10 && deployment_target_minor.to_i < 9) + (deployment_target_major.to_i == 10 && deployment_target_minor.to_i < 13) # This podhelper script is at $FLUTTER_ROOT/packages/flutter_tools/bin. # Add search paths from $FLUTTER_ROOT/bin/cache/artifacts/engine. @@ -220,7 +220,7 @@ def flutter_install_macos_engine_pod(mac_application_path = nil) s.license = { :type => 'BSD' } s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } - s.osx.deployment_target = '10.11' + s.osx.deployment_target = '10.13' # Framework linking is handled by Flutter tooling, not CocoaPods. # Add a placeholder to satisfy `s.dependency 'FlutterMacOS'` plugin podspecs. s.vendored_frameworks = 'path/to/nothing' diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart index 9ea76318cff7b..3d69b03b6ea0f 100644 --- a/packages/flutter_tools/lib/executable.dart +++ b/packages/flutter_tools/lib/executable.dart @@ -142,6 +142,7 @@ List generateCommands({ logger: globals.logger, terminal: globals.terminal, artifacts: globals.artifacts!, + // new ProjectValidators should be added here for the --suggestions to run allProjectValidators: [], ), AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem), diff --git a/packages/flutter_tools/lib/src/base/error_handling_io.dart b/packages/flutter_tools/lib/src/base/error_handling_io.dart index 3bdd3c037f64b..6d1ce3c6681f7 100644 --- a/packages/flutter_tools/lib/src/base/error_handling_io.dart +++ b/packages/flutter_tools/lib/src/base/error_handling_io.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:convert'; -import 'dart:io' as io show Directory, File, Link, ProcessException, ProcessResult, ProcessSignal, systemEncoding, Process, ProcessStartMode; +import 'dart:io' as io show Directory, File, Link, Process, ProcessException, ProcessResult, ProcessSignal, ProcessStartMode, systemEncoding; import 'dart:typed_data'; import 'package:file/file.dart'; diff --git a/packages/flutter_tools/lib/src/base/io.dart b/packages/flutter_tools/lib/src/base/io.dart index a8721542c8b7b..567c3013dbc67 100644 --- a/packages/flutter_tools/lib/src/base/io.dart +++ b/packages/flutter_tools/lib/src/base/io.dart @@ -34,21 +34,21 @@ import 'dart:async'; import 'dart:io' as io show - exit, + IOSink, InternetAddress, InternetAddressType, - IOSink, NetworkInterface, - pid, Process, ProcessInfo, ProcessSignal, - stderr, - stdin, Stdin, StdinException, Stdout, StdoutException, + exit, + pid, + stderr, + stdin, stdout; import 'package:file/file.dart'; @@ -63,10 +63,8 @@ export 'dart:io' BytesBuilder, CompressionOptions, // Directory, NO! Use `file_system.dart` - exitCode, // File, NO! Use `file_system.dart` // FileSystemEntity, NO! Use `file_system.dart` - gzip, GZipCodec, HandshakeException, HttpClient, @@ -79,14 +77,13 @@ export 'dart:io' HttpResponse, HttpServer, HttpStatus, - InternetAddress, - InternetAddressType, IOException, IOSink, + InternetAddress, + InternetAddressType, // Link NO! Use `file_system.dart` // NetworkInterface NO! Use `io.dart` OSError, - pid, // Platform NO! use `platform.dart` Process, ProcessException, @@ -97,19 +94,22 @@ export 'dart:io' // RandomAccessFile NO! Use `file_system.dart` ServerSocket, SignalException, - // stderr, NO! Use `io.dart` - // stdin, NO! Use `io.dart` + Socket, + SocketException, Stdin, StdinException, - // stdout, NO! Use `io.dart` Stdout, - Socket, - SocketException, - systemEncoding, WebSocket, WebSocketException, WebSocketTransformer, - ZLibEncoder; + ZLibEncoder, + exitCode, + gzip, + pid, + // stderr, NO! Use `io.dart` + // stdin, NO! Use `io.dart` + // stdout, NO! Use `io.dart` + systemEncoding; /// Exits the process with the given [exitCode]. typedef ExitFunction = void Function(int exitCode); diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart index b102fe84abb05..506680dc4cad4 100644 --- a/packages/flutter_tools/lib/src/base/logger.dart +++ b/packages/flutter_tools/lib/src/base/logger.dart @@ -10,7 +10,7 @@ import 'package:meta/meta.dart'; import '../convert.dart'; import 'common.dart'; import 'io.dart'; -import 'terminal.dart' show Terminal, TerminalColor, OutputPreferences; +import 'terminal.dart' show OutputPreferences, Terminal, TerminalColor; import 'utils.dart'; const int kDefaultStatusPadding = 59; diff --git a/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart b/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart index e7c6e45bd752d..4ea2f0a96374e 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/shader_compiler.dart @@ -68,6 +68,7 @@ class ShaderCompiler { '--spirv=$outputPath', '--input=${input.path}', '--input-type=frag', + '--include=${input.parent.path}', ]; final Process impellercProcess = await _processManager.start(cmd); final int code = await impellercProcess.exitCode; diff --git a/packages/flutter_tools/lib/src/commands/analyze.dart b/packages/flutter_tools/lib/src/commands/analyze.dart index 62c109d44dc3f..e63d2a42793b1 100644 --- a/packages/flutter_tools/lib/src/commands/analyze.dart +++ b/packages/flutter_tools/lib/src/commands/analyze.dart @@ -138,10 +138,14 @@ class AnalyzeCommand extends FlutterCommand { } if (workingDirectory == null) { final Set items = findDirectories(argResults!, _fileSystem); - if (items.isEmpty || items.length > 1) { - throwToolExit('The suggestions flags needs one directory path'); + if (items.isEmpty) { // user did not specify any path + directoryPath = _fileSystem.currentDirectory.path; + _logger.printTrace('Showing suggestions for current directory: $directoryPath'); + } else if (items.length > 1) { // if the user sends more than one path + throwToolExit('The suggestions flag can process only one directory path'); + } else { + directoryPath = items.first; } - directoryPath = items.first; } else { directoryPath = workingDirectory!.path; } @@ -150,6 +154,7 @@ class AnalyzeCommand extends FlutterCommand { logger: _logger, allProjectValidators: _allProjectValidators, userPath: directoryPath, + processManager: _processManager, ).run(); } else if (boolArgDeprecated('watch')) { await AnalyzeContinuously( diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index bc50508185f4f..55e350958a53b 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart @@ -215,7 +215,11 @@ known, it can be explicitly provided to attach via the command-line, e.g. Future runCommand() async { await _validateArguments(); - final Device device = await (findTargetDevice() as FutureOr); + final Device? device = await findTargetDevice(); + + if (device == null) { + throwToolExit('Did not find any valid target devices.'); + } final Artifacts? overrideArtifacts = device.artifactOverrides ?? globals.artifacts; await context.run( @@ -272,7 +276,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. } else if ((device is IOSDevice) || (device is IOSSimulator) || (device is MacOSDesignedForIPadDevice)) { final Uri? uriFromMdns = await MDnsObservatoryDiscovery.instance!.getObservatoryUri( - appId!, + appId, device, usesIpv6: usesIpv6, deviceVmservicePort: deviceVmservicePort, @@ -317,12 +321,12 @@ known, it can be explicitly provided to attach via the command-line, e.g. try { int? result; if (daemon != null) { - final ResidentRunner runner = await (createResidentRunner( + final ResidentRunner runner = await createResidentRunner( observatoryUris: observatoryUri, device: device, flutterProject: flutterProject, usesIpv6: usesIpv6, - ) as FutureOr); + ); late AppInstance app; try { app = await daemon.appDomain.launch( @@ -351,12 +355,12 @@ known, it can be explicitly provided to attach via the command-line, e.g. return; } while (true) { - final ResidentRunner runner = await (createResidentRunner( + final ResidentRunner runner = await createResidentRunner( observatoryUris: observatoryUri, device: device, flutterProject: flutterProject, usesIpv6: usesIpv6, - ) as FutureOr); + ); final Completer onAppStart = Completer.sync(); TerminalHandler? terminalHandler; unawaited(onAppStart.future.whenComplete(() { @@ -400,7 +404,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. } } - Future createResidentRunner({ + Future createResidentRunner({ required Stream observatoryUris, required Device device, required FlutterProject flutterProject, @@ -452,7 +456,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. } class HotRunnerFactory { - HotRunner? build( + HotRunner build( List devices, { required String target, required DebuggingOptions debuggingOptions, diff --git a/packages/flutter_tools/lib/src/commands/build_macos_framework.dart b/packages/flutter_tools/lib/src/commands/build_macos_framework.dart index 8bc3ee28c6cbd..c30ac643cac91 100644 --- a/packages/flutter_tools/lib/src/commands/build_macos_framework.dart +++ b/packages/flutter_tools/lib/src/commands/build_macos_framework.dart @@ -162,7 +162,7 @@ LICENSE s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } s.source = { :http => '${cache.storageBaseUrl}/flutter_infra_release/flutter/${cache.engineRevision}/$artifactsMode/artifacts.zip' } s.documentation_url = 'https://flutter.dev/docs' - s.osx.deployment_target = '10.11' + s.osx.deployment_target = '10.13' s.vendored_frameworks = 'FlutterMacOS.framework' s.prepare_command = 'unzip FlutterMacOS.framework -d FlutterMacOS.framework' end diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index ac33fc1bda9dd..193426213bd29 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart @@ -499,6 +499,7 @@ class AppDomain extends Domain { bool multidexEnabled = false, String? isolateFilter, bool machine = true, + String? userIdentifier, }) async { if (!await device.supportsRuntimeMode(options.buildInfo.mode)) { throw Exception( @@ -517,6 +518,7 @@ class AppDomain extends Domain { target: target, buildInfo: options.buildInfo, platform: globals.platform, + userIdentifier: userIdentifier, ); ResidentRunner runner; diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index 75d417668da4b..714a8b9c32fac 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -605,6 +605,7 @@ class RunCommand extends RunCommandBase { dillOutputPath: stringArgDeprecated('output-dill'), ipv6: ipv6 ?? false, multidexEnabled: boolArgDeprecated('multidex'), + userIdentifier: userIdentifier, ); } on Exception catch (error) { throwToolExit(error.toString()); diff --git a/packages/flutter_tools/lib/src/commands/validate_project.dart b/packages/flutter_tools/lib/src/commands/validate_project.dart index 9117f7cab47f2..b8ff3c37aa5ea 100644 --- a/packages/flutter_tools/lib/src/commands/validate_project.dart +++ b/packages/flutter_tools/lib/src/commands/validate_project.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:process/process.dart'; + import '../base/file_system.dart'; import '../base/logger.dart'; import '../project.dart'; @@ -15,7 +17,8 @@ class ValidateProject { required this.logger, required this.allProjectValidators, required this.userPath, - this.verbose = false + required this.processManager, + this.verbose = false, }); final FileSystem fileSystem; @@ -23,6 +26,7 @@ class ValidateProject { final bool verbose; final String userPath; final List allProjectValidators; + final ProcessManager processManager; Future run() async { final Directory workingDirectory = userPath.isEmpty ? fileSystem.currentDirectory : fileSystem.directory(userPath); diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index 86689f490dd9c..d35bdb5f3d148 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -42,7 +42,7 @@ import 'flutter_cache.dart'; import 'flutter_device_manager.dart'; import 'flutter_features.dart'; import 'fuchsia/fuchsia_device.dart' show FuchsiaDeviceTools; -import 'fuchsia/fuchsia_sdk.dart' show FuchsiaSdk, FuchsiaArtifacts; +import 'fuchsia/fuchsia_sdk.dart' show FuchsiaArtifacts, FuchsiaSdk; import 'fuchsia/fuchsia_workflow.dart' show FuchsiaWorkflow, fuchsiaWorkflow; import 'globals.dart' as globals; import 'ios/ios_workflow.dart'; diff --git a/packages/flutter_tools/lib/src/convert.dart b/packages/flutter_tools/lib/src/convert.dart index caec2776aa1f9..836f5820e91a8 100644 --- a/packages/flutter_tools/lib/src/convert.dart +++ b/packages/flutter_tools/lib/src/convert.dart @@ -5,12 +5,12 @@ // Hide the original utf8 [Codec] so that we can export our own implementation // which adds additional error handling. import 'dart:convert' hide utf8; -import 'dart:convert' as cnv show utf8, Utf8Decoder; +import 'dart:convert' as cnv show Utf8Decoder, utf8; import 'package:meta/meta.dart'; import 'base/common.dart'; -export 'dart:convert' hide utf8, Utf8Codec, Utf8Decoder; +export 'dart:convert' hide Utf8Codec, Utf8Decoder, utf8; /// The original utf8 encoding for testing overrides only. /// diff --git a/packages/flutter_tools/lib/src/dart_pub_json_formatter.dart b/packages/flutter_tools/lib/src/dart_pub_json_formatter.dart new file mode 100644 index 0000000000000..156df4804ddc8 --- /dev/null +++ b/packages/flutter_tools/lib/src/dart_pub_json_formatter.dart @@ -0,0 +1,71 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:collection'; + +/// Parsing the output of "dart pub deps --json" +/// +/// expected structure: {"name": "package name", "source": "hosted", "dependencies": [...]} +class DartDependencyPackage { + DartDependencyPackage({ + required this.name, + required this.version, + required this.source, + required this.dependencies, + }); + + factory DartDependencyPackage.fromHashMap(dynamic packageInfo) { + String name = ''; + String version = ''; + String source = ''; + List dependencies = []; + + if (packageInfo is LinkedHashMap) { + final LinkedHashMap info = packageInfo as LinkedHashMap; + if (info.containsKey('name')) { + name = info['name'] as String; + } + if (info.containsKey('version')) { + version = info['version'] as String; + } + if (info.containsKey('source')) { + source = info['source'] as String; + } + if (info.containsKey('dependencies')) { + dependencies = info['dependencies'] as List; + } + } + return DartDependencyPackage( + name: name, + version: version, + source: source, + dependencies: dependencies.map((dynamic e) => e.toString()).toList(), + ); + } + + final String name; + final String version; + final String source; + final List dependencies; + +} + +class DartPubJson { + DartPubJson(this._json); + final LinkedHashMap _json; + final List _packages = []; + + List get packages { + if (_packages.isNotEmpty) { + return _packages; + } + if (_json.containsKey('packages')) { + final List packagesInfo = _json['packages'] as List; + for (final dynamic info in packagesInfo) { + _packages.add(DartDependencyPackage.fromHashMap(info)); + } + } + return _packages; + } +} diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 862fc0a88d99d..314377ed22bd2 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -44,31 +44,52 @@ import 'windows/visual_studio_validator.dart'; import 'windows/windows_workflow.dart'; abstract class DoctorValidatorsProvider { + // Allow tests to construct a [_DefaultDoctorValidatorsProvider] with explicit + // [FeatureFlags]. + factory DoctorValidatorsProvider.test({ + Platform? platform, + required FeatureFlags featureFlags, + }) { + return _DefaultDoctorValidatorsProvider( + featureFlags: featureFlags, + platform: platform ?? FakePlatform(), + ); + } /// The singleton instance, pulled from the [AppContext]. static DoctorValidatorsProvider get _instance => context.get()!; - static final DoctorValidatorsProvider defaultInstance = _DefaultDoctorValidatorsProvider(); + static final DoctorValidatorsProvider defaultInstance = _DefaultDoctorValidatorsProvider( + platform: globals.platform, + featureFlags: featureFlags, + ); List get validators; List get workflows; } class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider { + _DefaultDoctorValidatorsProvider({ + required this.platform, + required this.featureFlags, + }); + List? _validators; List? _workflows; + final Platform platform; + final FeatureFlags featureFlags; - final LinuxWorkflow linuxWorkflow = LinuxWorkflow( - platform: globals.platform, + late final LinuxWorkflow linuxWorkflow = LinuxWorkflow( + platform: platform, featureFlags: featureFlags, ); - final WebWorkflow webWorkflow = WebWorkflow( - platform: globals.platform, + late final WebWorkflow webWorkflow = WebWorkflow( + platform: platform, featureFlags: featureFlags, ); - final MacOSWorkflow macOSWorkflow = MacOSWorkflow( - platform: globals.platform, + late final MacOSWorkflow macOSWorkflow = MacOSWorkflow( + platform: platform, featureFlags: featureFlags, ); @@ -80,17 +101,17 @@ class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider { final List ideValidators = [ if (androidWorkflow!.appliesToHostPlatform) - ...AndroidStudioValidator.allValidators(globals.config, globals.platform, globals.fs, globals.userMessages), + ...AndroidStudioValidator.allValidators(globals.config, platform, globals.fs, globals.userMessages), ...IntelliJValidator.installedValidators( fileSystem: globals.fs, - platform: globals.platform, + platform: platform, userMessages: userMessages, plistParser: globals.plistParser, processManager: globals.processManager, ), - ...VsCodeValidator.installedValidators(globals.fs, globals.platform, globals.processManager), + ...VsCodeValidator.installedValidators(globals.fs, platform, globals.processManager), ]; - final ProxyValidator proxyValidator = ProxyValidator(platform: globals.platform); + final ProxyValidator proxyValidator = ProxyValidator(platform: platform); _validators = [ FlutterValidator( fileSystem: globals.fs, @@ -320,12 +341,12 @@ class Doctor { Future diagnose({ bool androidLicenses = false, bool verbose = true, - bool showColor = true, AndroidLicenseValidator? androidLicenseValidator, bool showPii = true, List? startedValidatorTasks, bool sendEvent = true, }) async { + final bool showColor = globals.terminal.supportsColor; if (androidLicenses && androidLicenseValidator != null) { return androidLicenseValidator.runLicenseManager(); } @@ -644,7 +665,7 @@ class DoctorText { Future _runDiagnosis(bool showPii) async { try { - await _doctor.diagnose(showColor: false, startedValidatorTasks: _validatorTasks, showPii: showPii, sendEvent: _sendDoctorEvent); + await _doctor.diagnose(startedValidatorTasks: _validatorTasks, showPii: showPii, sendEvent: _sendDoctorEvent); // Do not send the doctor event a second time. _sendDoctorEvent = false; final String text = _logger.statusText; diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart index 5d67e121280c6..4114d43febbac 100644 --- a/packages/flutter_tools/lib/src/ios/mac.dart +++ b/packages/flutter_tools/lib/src/ios/mac.dart @@ -25,8 +25,8 @@ import '../reporting/reporting.dart'; import 'application_package.dart'; import 'code_signing.dart'; import 'iproxy.dart'; -import 'migrations/deployment_target_migration.dart'; import 'migrations/host_app_info_plist_migration.dart'; +import 'migrations/ios_deployment_target_migration.dart'; import 'migrations/project_base_configuration_migration.dart'; import 'migrations/project_build_location_migration.dart'; import 'migrations/project_object_version_migration.dart'; @@ -123,7 +123,7 @@ Future buildXcodeProject({ XcodeBuildSystemMigration(app.project, globals.logger), ProjectBaseConfigurationMigration(app.project, globals.logger), ProjectBuildLocationMigration(app.project, globals.logger), - DeploymentTargetMigration(app.project, globals.logger), + IOSDeploymentTargetMigration(app.project, globals.logger), ProjectObjectVersionMigration(app.project, globals.logger), HostAppInfoPlistMigration(app.project, globals.logger), ]; diff --git a/packages/flutter_tools/lib/src/ios/migrations/deployment_target_migration.dart b/packages/flutter_tools/lib/src/ios/migrations/ios_deployment_target_migration.dart similarity index 96% rename from packages/flutter_tools/lib/src/ios/migrations/deployment_target_migration.dart rename to packages/flutter_tools/lib/src/ios/migrations/ios_deployment_target_migration.dart index a1cabcc50b135..4376d4039808b 100644 --- a/packages/flutter_tools/lib/src/ios/migrations/deployment_target_migration.dart +++ b/packages/flutter_tools/lib/src/ios/migrations/ios_deployment_target_migration.dart @@ -7,8 +7,8 @@ import '../../base/project_migrator.dart'; import '../../xcode_project.dart'; /// Update the minimum iOS deployment version to the minimum allowed by Xcode without causing a warning. -class DeploymentTargetMigration extends ProjectMigrator { - DeploymentTargetMigration( +class IOSDeploymentTargetMigration extends ProjectMigrator { + IOSDeploymentTargetMigration( IosProject project, super.logger, ) : _xcodeProjectInfoFile = project.xcodeProjectInfoFile, @@ -36,7 +36,7 @@ class DeploymentTargetMigration extends ProjectMigrator { if (_podfile.existsSync()) { processFileLines(_podfile); } else { - logger.printTrace('Podfile not found, skipping global platform version migration.'); + logger.printTrace('Podfile not found, skipping global platform iOS version migration.'); } return true; diff --git a/packages/flutter_tools/lib/src/localizations/gen_l10n.dart b/packages/flutter_tools/lib/src/localizations/gen_l10n.dart index 0323143cab42f..b073d26fdd196 100644 --- a/packages/flutter_tools/lib/src/localizations/gen_l10n.dart +++ b/packages/flutter_tools/lib/src/localizations/gen_l10n.dart @@ -942,7 +942,13 @@ class LocalizationsGenerator { @visibleForTesting static File templateArbFileFromFileName(String templateArbFileName, Directory inputDirectory) { final File templateArbFile = inputDirectory.childFile(templateArbFileName); - final String templateArbFileStatModeString = templateArbFile.statSync().modeString(); + final FileStat templateArbFileStat = templateArbFile.statSync(); + if (templateArbFileStat.type == FileSystemEntityType.notFound) { + throw L10nException( + "The 'template-arb-file', $templateArbFile, does not exist." + ); + } + final String templateArbFileStatModeString = templateArbFileStat.modeString(); if (templateArbFileStatModeString[0] == '-' && templateArbFileStatModeString[3] == '-') { throw L10nException( "The 'template-arb-file', $templateArbFile, is not readable.\n" @@ -1044,6 +1050,9 @@ class LocalizationsGenerator { } static bool _isValidGetterAndMethodName(String name) { + if (name.isEmpty) { + return false; + } // Public Dart method name must not start with an underscore if (name[0] == '_') { return false; diff --git a/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart b/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart index 314e7c35f7f87..076abcc4d55db 100644 --- a/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart +++ b/packages/flutter_tools/lib/src/localizations/gen_l10n_types.dart @@ -124,6 +124,9 @@ class L10nException implements Exception { L10nException(this.message); final String message; + + @override + String toString() => message; } // One optional named parameter to be used by a NumberFormat. diff --git a/packages/flutter_tools/lib/src/macos/build_macos.dart b/packages/flutter_tools/lib/src/macos/build_macos.dart index 1af3b7b009223..d872d89f9a79a 100644 --- a/packages/flutter_tools/lib/src/macos/build_macos.dart +++ b/packages/flutter_tools/lib/src/macos/build_macos.dart @@ -14,6 +14,7 @@ import '../ios/xcode_build_settings.dart'; import '../ios/xcodeproj.dart'; import '../project.dart'; import 'cocoapod_utils.dart'; +import 'migrations/macos_deployment_target_migration.dart'; import 'migrations/remove_macos_framework_link_and_embedding_migration.dart'; /// When run in -quiet mode, Xcode should only print from the underlying tasks to stdout. @@ -45,6 +46,7 @@ Future buildMacOS({ globals.logger, globals.flutterUsage, ), + MacOSDeploymentTargetMigration(flutterProject.macos, globals.logger), ]; final ProjectMigration migration = ProjectMigration(migrators); diff --git a/packages/flutter_tools/lib/src/macos/migrations/macos_deployment_target_migration.dart b/packages/flutter_tools/lib/src/macos/migrations/macos_deployment_target_migration.dart new file mode 100644 index 0000000000000..58ce9fb7df146 --- /dev/null +++ b/packages/flutter_tools/lib/src/macos/migrations/macos_deployment_target_migration.dart @@ -0,0 +1,60 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import '../../base/file_system.dart'; +import '../../base/project_migrator.dart'; +import '../../xcode_project.dart'; + +/// Update the minimum macOS deployment version to the minimum allowed by Xcode without causing a warning. +class MacOSDeploymentTargetMigration extends ProjectMigrator { + MacOSDeploymentTargetMigration( + MacOSProject project, + super.logger, + ) : _xcodeProjectInfoFile = project.xcodeProjectInfoFile, + _podfile = project.podfile; + + final File _xcodeProjectInfoFile; + final File _podfile; + + @override + bool migrate() { + if (_xcodeProjectInfoFile.existsSync()) { + processFileLines(_xcodeProjectInfoFile); + } else { + logger.printTrace('Xcode project not found, skipping macOS deployment target version migration.'); + } + + if (_podfile.existsSync()) { + processFileLines(_podfile); + } else { + logger.printTrace('Podfile not found, skipping global platform macOS version migration.'); + } + + return true; + } + + @override + String? migrateLine(String line) { + // Xcode project file changes. + const String deploymentTargetOriginal = 'MACOSX_DEPLOYMENT_TARGET = 10.11;'; + + // Podfile changes. + const String podfilePlatformVersionOriginal = "platform :osx, '10.11'"; + + if (line.contains(deploymentTargetOriginal) || line.contains(podfilePlatformVersionOriginal)) { + if (!migrationRequired) { + // Only print for the first discovered change found. + logger.printStatus('Updating minimum macOS deployment target to 10.13.'); + } + + const String deploymentTargetReplacement = 'MACOSX_DEPLOYMENT_TARGET = 10.13;'; + const String podfilePlatformVersionReplacement = "platform :osx, '10.13'"; + return line + .replaceAll(deploymentTargetOriginal, deploymentTargetReplacement) + .replaceAll(podfilePlatformVersionOriginal, podfilePlatformVersionReplacement); + } + + return line; + } +} diff --git a/packages/flutter_tools/lib/src/mdns_discovery.dart b/packages/flutter_tools/lib/src/mdns_discovery.dart index ce7d8c2602b16..13882b923bded 100644 --- a/packages/flutter_tools/lib/src/mdns_discovery.dart +++ b/packages/flutter_tools/lib/src/mdns_discovery.dart @@ -145,7 +145,7 @@ class MDnsObservatoryDiscovery { } } - Future getObservatoryUri(String applicationId, Device device, { + Future getObservatoryUri(String? applicationId, Device device, { bool usesIpv6 = false, int? hostVmservicePort, int? deviceVmservicePort, diff --git a/packages/flutter_tools/lib/src/project_validator.dart b/packages/flutter_tools/lib/src/project_validator.dart index a2abcc47d8722..595e77c26933f 100644 --- a/packages/flutter_tools/lib/src/project_validator.dart +++ b/packages/flutter_tools/lib/src/project_validator.dart @@ -2,19 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:collection'; + +import 'package:process/process.dart'; + +import 'base/io.dart'; +import 'convert.dart'; +import 'dart_pub_json_formatter.dart'; import 'flutter_manifest.dart'; import 'project.dart'; import 'project_validator_result.dart'; abstract class ProjectValidator { + const ProjectValidator(); String get title; bool supportsProject(FlutterProject project); /// Can return more than one result in case a file/command have a lot of info to share to the user Future> start(FlutterProject project); - /// new ProjectValidators should be added here for the ValidateProjectCommand to run - static List allProjectValidators = [ - GeneralInfoProjectValidator(), - ]; } /// Validator run for all platforms that extract information from the pubspec.yaml. @@ -109,3 +113,77 @@ class GeneralInfoProjectValidator extends ProjectValidator{ @override String get title => 'General Info'; } + +class PubDependenciesProjectValidator extends ProjectValidator { + const PubDependenciesProjectValidator(this._processManager); + final ProcessManager _processManager; + + @override + Future> start(FlutterProject project) async { + const String name = 'Dart dependencies'; + final ProcessResult processResult = await _processManager.run(['dart', 'pub', 'deps', '--json']); + if (processResult.stdout is! String) { + return [ + _createProjectValidatorError(name, 'Command dart pub deps --json failed') + ]; + } + + final LinkedHashMap jsonResult; + final List result = []; + try { + jsonResult = json.decode( + processResult.stdout.toString() + ) as LinkedHashMap; + } on FormatException{ + result.add(_createProjectValidatorError(name, processResult.stderr.toString())); + return result; + } + + final DartPubJson dartPubJson = DartPubJson(jsonResult); + final List dependencies = []; + + // Information retrieved from the pubspec.lock file if a dependency comes from + // the hosted url https://pub.dartlang.org we ignore it or if the package + // is the current directory being analyzed (root). + final Set hostedDependencies = {'hosted', 'root'}; + + for (final DartDependencyPackage package in dartPubJson.packages) { + if (!hostedDependencies.contains(package.source)) { + dependencies.addAll(package.dependencies); + } + } + + if (dependencies.isNotEmpty) { + final String verb = dependencies.length == 1 ? 'is' : 'are'; + result.add( + ProjectValidatorResult( + name: name, + value: '${dependencies.join(', ')} $verb not hosted', + status: StatusProjectValidator.warning, + ) + ); + } else { + result.add( + const ProjectValidatorResult( + name: name, + value: 'All pub dependencies are hosted on https://pub.dartlang.org', + status: StatusProjectValidator.success, + ) + ); + } + + return result; + } + + @override + bool supportsProject(FlutterProject project) { + return true; + } + + @override + String get title => 'Pub dependencies'; + + ProjectValidatorResult _createProjectValidatorError(String name, String value) { + return ProjectValidatorResult(name: name, value: value, status: StatusProjectValidator.error); + } +} diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml index 2e73d6e6ee3cc..c23f898658f88 100644 --- a/packages/flutter_tools/pubspec.yaml +++ b/packages/flutter_tools/pubspec.yaml @@ -61,7 +61,7 @@ dependencies: analyzer: 4.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" boolean_selector: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" built_collection: 5.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" - built_value: 8.3.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" + built_value: 8.4.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" csslib: 0.17.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" dds_service_extensions: 1.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade" @@ -103,4 +103,4 @@ dartdoc: # Exclude this package from the hosted API docs. nodoc: true -# PUBSPEC CHECKSUM: 5069 +# PUBSPEC CHECKSUM: 9667 diff --git a/packages/flutter_tools/templates/app_shared/macos.tmpl/Runner.xcodeproj/project.pbxproj.tmpl b/packages/flutter_tools/templates/app_shared/macos.tmpl/Runner.xcodeproj/project.pbxproj.tmpl index b992f1aa1534a..65ed3d85f372d 100644 --- a/packages/flutter_tools/templates/app_shared/macos.tmpl/Runner.xcodeproj/project.pbxproj.tmpl +++ b/packages/flutter_tools/templates/app_shared/macos.tmpl/Runner.xcodeproj/project.pbxproj.tmpl @@ -344,7 +344,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -423,7 +423,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -470,7 +470,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/packages/flutter_tools/templates/cocoapods/Podfile-macos b/packages/flutter_tools/templates/cocoapods/Podfile-macos index dade8dfad0dcf..fe733905db657 100644 --- a/packages/flutter_tools/templates/cocoapods/Podfile-macos +++ b/packages/flutter_tools/templates/cocoapods/Podfile-macos @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.13' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart index 2575d7f527906..0610be0b621d8 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'dart:async'; import 'package:file/memory.dart'; @@ -13,6 +11,7 @@ import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/dds.dart'; import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/build_info.dart'; @@ -24,11 +23,13 @@ import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/ios/application_package.dart'; import 'package:flutter_tools/src/ios/devices.dart'; import 'package:flutter_tools/src/macos/macos_ipad_device.dart'; +import 'package:flutter_tools/src/mdns_discovery.dart'; import 'package:flutter_tools/src/project.dart'; +import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/resident_runner.dart'; import 'package:flutter_tools/src/run_hot.dart'; import 'package:flutter_tools/src/vmservice.dart'; -import 'package:meta/meta.dart'; +import 'package:multicast_dns/multicast_dns.dart'; import 'package:test/fake.dart'; import 'package:vm_service/vm_service.dart' as vm_service; @@ -43,8 +44,8 @@ void main() { }); group('attach', () { - StreamLogger logger; - FileSystem testFileSystem; + late StreamLogger logger; + late FileSystem testFileSystem; setUp(() { Cache.disableLocking(); @@ -62,10 +63,10 @@ void main() { const int devicePort = 499; const int hostPort = 42; - FakeDeviceLogReader fakeLogReader; - RecordingPortForwarder portForwarder; - FakeDartDevelopmentService fakeDds; - FakeAndroidDevice device; + late FakeDeviceLogReader fakeLogReader; + late RecordingPortForwarder portForwarder; + late FakeDartDevelopmentService fakeDds; + late FakeAndroidDevice device; setUp(() { fakeLogReader = FakeDeviceLogReader(); @@ -80,6 +81,45 @@ void main() { fakeLogReader.dispose(); }); + testUsingContext('succeeds with iOS device', () async { + final FakeIOSDevice device = FakeIOSDevice( + logReader: fakeLogReader, + portForwarder: portForwarder, + onGetLogReader: () { + fakeLogReader.addLine('Foo'); + fakeLogReader.addLine('The Dart VM service is listening on http://127.0.0.1:$devicePort'); + return fakeLogReader; + }, + ); + + testDeviceManager.addDevice(device); + final Completer completer = Completer(); + final StreamSubscription loggerSubscription = logger.stream.listen((String message) { + if (message == '[verbose] Observatory URL on device: http://127.0.0.1:$devicePort') { + // The "Observatory URL on device" message is output by the ProtocolDiscovery when it found the observatory. + completer.complete(); + } + }); + final Future task = createTestCommandRunner(AttachCommand()).run(['attach']); + await completer.future; + + expect(portForwarder.devicePort, devicePort); + expect(portForwarder.hostPort, hostPort); + + await fakeLogReader.dispose(); + await expectLoggerInterruptEndsTask(task, logger); + await loggerSubscription.cancel(); + }, overrides: { + FileSystem: () => testFileSystem, + ProcessManager: () => FakeProcessManager.any(), + Logger: () => logger, + MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery( + mdnsClient: FakeMDnsClient([], >{}), + logger: logger, + flutterUsage: TestUsage(), + ), + }); + testUsingContext('finds observatory port and forwards', () async { device.onGetLogReader = () { fakeLogReader.addLine('Foo'); @@ -139,8 +179,8 @@ void main() { final FakeHotRunner hotRunner = FakeHotRunner(); hotRunner.onAttach = ( - Completer connectionInfoCompleter, - Completer appStartedCompleter, + Completer? connectionInfoCompleter, + Completer? appStartedCompleter, bool allowExistingDdsInstance, bool enableDevTools, ) async => 0; @@ -224,8 +264,8 @@ void main() { group('forwarding to given port', () { const int devicePort = 499; const int hostPort = 42; - RecordingPortForwarder portForwarder; - FakeAndroidDevice device; + late RecordingPortForwarder portForwarder; + late FakeAndroidDevice device; setUp(() { final FakeDartDevelopmentService fakeDds = FakeDartDevelopmentService(); @@ -408,8 +448,8 @@ void main() { final FakeHotRunnerFactory hotRunnerFactory = FakeHotRunnerFactory() ..hotRunner = hotRunner; hotRunner.onAttach = ( - Completer connectionInfoCompleter, - Completer appStartedCompleter, + Completer? connectionInfoCompleter, + Completer? appStartedCompleter, bool allowExistingDdsInstance, bool enableDevTools, ) async { @@ -438,8 +478,8 @@ void main() { ..hotRunner = hotRunner; hotRunner.onAttach = ( - Completer connectionInfoCompleter, - Completer appStartedCompleter, + Completer? connectionInfoCompleter, + Completer? appStartedCompleter, bool allowExistingDdsInstance, bool enableDevTools, ) async { @@ -447,7 +487,6 @@ void main() { throw vm_service.RPCError('flutter._listViews', RPCErrorCodes.kInvalidParams, ''); }; - testDeviceManager.addDevice(device); testFileSystem.file('lib/main.dart').createSync(); @@ -463,7 +502,7 @@ void main() { } class FakeHotRunner extends Fake implements HotRunner { - Future Function(Completer, Completer, bool, bool) onAttach; + late Future Function(Completer?, Completer?, bool, bool) onAttach; @override bool exited = false; @@ -473,8 +512,8 @@ class FakeHotRunner extends Fake implements HotRunner { @override Future attach({ - Completer connectionInfoCompleter, - Completer appStartedCompleter, + Completer? connectionInfoCompleter, + Completer? appStartedCompleter, bool allowExistingDdsInstance = false, bool enableDevTools = false, bool needsFullRestart = true, @@ -484,25 +523,25 @@ class FakeHotRunner extends Fake implements HotRunner { } class FakeHotRunnerFactory extends Fake implements HotRunnerFactory { - HotRunner hotRunner; - String dillOutputPath; - String projectRootPath; - List devices; + late HotRunner hotRunner; + String? dillOutputPath; + String? projectRootPath; + late List devices; @override HotRunner build( List devices, { - String target, - DebuggingOptions debuggingOptions, + required String target, + required DebuggingOptions debuggingOptions, bool benchmarkMode = false, - File applicationBinary, + File? applicationBinary, bool hostIsIde = false, - String projectRootPath, - String packagesFilePath, - String dillOutputPath, + String? projectRootPath, + String? packagesFilePath, + String? dillOutputPath, bool stayResident = true, bool ipv6 = false, - FlutterProject flutterProject, + FlutterProject? flutterProject, }) { this.devices = devices; this.dillOutputPath = dillOutputPath; @@ -514,17 +553,17 @@ class FakeHotRunnerFactory extends Fake implements HotRunnerFactory { class RecordingPortForwarder implements DevicePortForwarder { RecordingPortForwarder([this.hostPort]); - int devicePort; - int hostPort; + int? devicePort; + int? hostPort; @override Future dispose() async { } @override - Future forward(int devicePort, {int hostPort}) async { + Future forward(int devicePort, {int? hostPort}) async { this.devicePort = devicePort; this.hostPort ??= hostPort; - return this.hostPort; + return this.hostPort!; } @override @@ -541,12 +580,12 @@ class StreamLogger extends Logger { @override void printError( String message, { - StackTrace stackTrace, - bool emphasis, - TerminalColor color, - int indent, - int hangingIndent, - bool wrap, + StackTrace? stackTrace, + bool? emphasis, + TerminalColor? color, + int? indent, + int? hangingIndent, + bool? wrap, }) { hadErrorOutput = true; _log('[stderr] $message'); @@ -555,11 +594,11 @@ class StreamLogger extends Logger { @override void printWarning( String message, { - bool emphasis, - TerminalColor color, - int indent, - int hangingIndent, - bool wrap, + bool? emphasis, + TerminalColor? color, + int? indent, + int? hangingIndent, + bool? wrap, }) { hadWarningOutput = true; _log('[stderr] $message'); @@ -568,12 +607,12 @@ class StreamLogger extends Logger { @override void printStatus( String message, { - bool emphasis, - TerminalColor color, - bool newline, - int indent, - int hangingIndent, - bool wrap, + bool? emphasis, + TerminalColor? color, + bool? newline, + int? indent, + int? hangingIndent, + bool? wrap, }) { _log('[stdout] $message'); } @@ -581,7 +620,7 @@ class StreamLogger extends Logger { @override void printBox( String message, { - String title, + String? title, }) { if (title == null) { _log('[stdout] $message'); @@ -598,8 +637,8 @@ class StreamLogger extends Logger { @override Status startProgress( String message, { - @required Duration timeout, - String progressId, + Duration? timeout, + String? progressId, bool multilineOutput = false, bool includeTiming = true, int progressIndicatorPadding = kDefaultStatusPadding, @@ -612,9 +651,9 @@ class StreamLogger extends Logger { @override Status startSpinner({ - VoidCallback onFinish, - Duration timeout, - SlowWarningCallback slowWarningCallback, + VoidCallback? onFinish, + Duration? timeout, + SlowWarningCallback? slowWarningCallback, }) { return SilentStatus( stopwatch: Stopwatch(), @@ -641,7 +680,7 @@ class StreamLogger extends Logger { Stream get stream => _controller.stream; @override - void sendEvent(String name, [Map args]) { } + void sendEvent(String name, [Map? args]) { } @override bool get supportsColor => throw UnimplementedError(); @@ -676,10 +715,10 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService @override Future startDartDevelopmentService( Uri observatoryUri, { - @required Logger logger, - int hostPort, - bool ipv6, - bool disableServiceAuthCodes, + required Logger logger, + int? hostPort, + bool? ipv6, + bool? disableServiceAuthCodes, bool cacheStartupProfile = false, }) async {} @@ -691,10 +730,10 @@ class FakeDartDevelopmentService extends Fake implements DartDevelopmentService // Until we fix that, we have to also ignore related lints here. // ignore: avoid_implementing_value_types class FakeAndroidDevice extends Fake implements AndroidDevice { - FakeAndroidDevice({@required this.id}); + FakeAndroidDevice({required this.id}); @override - DartDevelopmentService dds; + late DartDevelopmentService dds; @override final String id; @@ -727,20 +766,25 @@ class FakeAndroidDevice extends Fake implements AndroidDevice { bool isSupportedForProject(FlutterProject flutterProject) => true; @override - DevicePortForwarder portForwarder; + DevicePortForwarder? portForwarder; - DeviceLogReader Function() onGetLogReader; + DeviceLogReader Function()? onGetLogReader; @override FutureOr getLogReader({ - AndroidApk app, + AndroidApk? app, bool includePastLogs = false, }) { - return onGetLogReader(); + if (onGetLogReader == null) { + throw UnimplementedError( + 'Called getLogReader but no onGetLogReader callback was supplied in the constructor to FakeAndroidDevice.', + ); + } + return onGetLogReader!(); } @override - OverrideArtifacts get artifactOverrides => null; + OverrideArtifacts? get artifactOverrides => null; @override final PlatformType platformType = PlatformType.android; @@ -753,24 +797,40 @@ class FakeAndroidDevice extends Fake implements AndroidDevice { // Until we fix that, we have to also ignore related lints here. // ignore: avoid_implementing_value_types class FakeIOSDevice extends Fake implements IOSDevice { - FakeIOSDevice({this.dds, this.portForwarder, this.logReader}); + FakeIOSDevice({ + DevicePortForwarder? portForwarder, + DeviceLogReader? logReader, + this.onGetLogReader, + }) : _portForwarder = portForwarder, _logReader = logReader; + + final DevicePortForwarder? _portForwarder; @override - final DevicePortForwarder portForwarder; + DevicePortForwarder get portForwarder => _portForwarder!; @override - final DartDevelopmentService dds; + DartDevelopmentService get dds => throw UnimplementedError('getter dds not implemented'); - final DeviceLogReader logReader; + final DeviceLogReader? _logReader; + DeviceLogReader get logReader => _logReader!; + + final DeviceLogReader Function()? onGetLogReader; @override DeviceLogReader getLogReader({ - IOSApp app, + IOSApp? app, bool includePastLogs = false, - }) => logReader; + }) { + if (onGetLogReader == null) { + throw UnimplementedError( + 'Called getLogReader but no onGetLogReader callback was supplied in the constructor to FakeIOSDevice', + ); + } + return onGetLogReader!(); + } @override - OverrideArtifacts get artifactOverrides => null; + OverrideArtifacts? get artifactOverrides => null; @override final String name = 'name'; @@ -781,3 +841,49 @@ class FakeIOSDevice extends Fake implements IOSDevice { @override final PlatformType platformType = PlatformType.ios; } + +class FakeMDnsClient extends Fake implements MDnsClient { + FakeMDnsClient(this.ptrRecords, this.srvResponse, { + this.txtResponse = const >{}, + this.osErrorOnStart = false, + }); + + final List ptrRecords; + final Map> srvResponse; + final Map> txtResponse; + final bool osErrorOnStart; + + @override + Future start({ + InternetAddress? listenAddress, + NetworkInterfacesFactory? interfacesFactory, + int mDnsPort = 5353, + InternetAddress? mDnsAddress, + }) async { + if (osErrorOnStart) { + throw const OSError('Operation not supported on socket', 102); + } + } + + @override + Stream lookup( + ResourceRecordQuery query, { + Duration timeout = const Duration(seconds: 5), + }) { + if (T == PtrResourceRecord && query.fullyQualifiedName == MDnsObservatoryDiscovery.dartObservatoryName) { + return Stream.fromIterable(ptrRecords) as Stream; + } + if (T == SrvResourceRecord) { + final String key = query.fullyQualifiedName; + return Stream.fromIterable(srvResponse[key] ?? []) as Stream; + } + if (T == TxtResourceRecord) { + final String key = query.fullyQualifiedName; + return Stream.fromIterable(txtResponse[key] ?? []) as Stream; + } + throw UnsupportedError('Unsupported query type $T'); + } + + @override + void stop() {} +} diff --git a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart index aab2b42bf923b..d703026fc6514 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:file/memory.dart'; import 'package:file_testing/file_testing.dart'; import 'package:flutter_tools/src/base/file_system.dart'; @@ -22,8 +20,8 @@ import '../../src/context.dart'; void main() { group('clean command', () { - Xcode xcode; - FakeXcodeProjectInterpreter xcodeProjectInterpreter; + late Xcode xcode; + late FakeXcodeProjectInterpreter xcodeProjectInterpreter; setUp(() { xcodeProjectInterpreter = FakeXcodeProjectInterpreter(); @@ -34,8 +32,8 @@ void main() { }); group('general', () { - MemoryFileSystem fs; - Directory buildDirectory; + late MemoryFileSystem fs; + late Directory buildDirectory; setUp(() { fs = MemoryFileSystem.test(); @@ -104,9 +102,9 @@ void main() { }); group('Windows', () { - FakePlatform windowsPlatform; - MemoryFileSystem fileSystem; - FileExceptionHandler exceptionHandler; + late FakePlatform windowsPlatform; + late MemoryFileSystem fileSystem; + late FileExceptionHandler exceptionHandler; setUp(() { windowsPlatform = FakePlatform(operatingSystem: 'windows'); @@ -191,8 +189,13 @@ class FakeXcodeProjectInterpreter extends Fake implements XcodeProjectInterprete Version version = Version(0, 0, 0); @override - Future getInfo(String projectPath, {String projectFilename}) async { - return XcodeProjectInfo(null, null, ['Runner'], BufferLogger.test()); + Future getInfo(String projectPath, {String? projectFilename}) async { + return XcodeProjectInfo( + const [], + const [], + ['Runner'], + BufferLogger.test(), + ); } final List workspaces = []; diff --git a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart index 4bc1f0b269d63..6a8a9321da40d 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart @@ -2,14 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - -// TODO(gspencergoog): Remove this tag once this test's state leaks/test -// dependencies have been fixed. -// https://github.com/flutter/flutter/issues/85160 -// Fails with "flutter test --test-randomize-ordering-seed=20210723" -@Tags(['no-shuffle']) - import 'dart:async'; import 'package:args/command_runner.dart'; @@ -19,6 +11,7 @@ import 'package:flutter_tools/src/android/android_studio_validator.dart'; import 'package:flutter_tools/src/android/android_workflow.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/user_messages.dart'; import 'package:flutter_tools/src/build_info.dart'; @@ -27,7 +20,6 @@ import 'package:flutter_tools/src/commands/doctor.dart'; import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/doctor.dart'; import 'package:flutter_tools/src/doctor_validator.dart'; -import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/version.dart'; @@ -42,9 +34,9 @@ import '../../src/fakes.dart'; import '../../src/test_flutter_command_runner.dart'; void main() { - FakeFlutterVersion flutterVersion; - BufferLogger logger; - FakeProcessManager fakeProcessManager; + late FakeFlutterVersion flutterVersion; + late BufferLogger logger; + late FakeProcessManager fakeProcessManager; setUp(() { flutterVersion = FakeFlutterVersion(); @@ -187,12 +179,13 @@ void main() { '• No issues found!\n' )); }, overrides: { + AnsiTerminal: () => FakeTerminal(), DoctorValidatorsProvider: () => FakeDoctorValidatorsProvider(), }); }); group('doctor usage params', () { - TestUsage testUsage; + late TestUsage testUsage; setUp(() { testUsage = TestUsage(); @@ -328,6 +321,8 @@ void main() { '\n' '• No issues found!\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate non-verbose output format for run with crash', () async { @@ -345,6 +340,8 @@ void main() { '\n' '! Doctor found issues in 1 category.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate verbose output format contains trace for run with crash', () async { @@ -361,6 +358,8 @@ void main() { }); expect(logger.statusText, contains('Stuck validator that never completes exceeded maximum allowed duration of ')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate non-verbose output format for run with an async crash', () async { @@ -387,6 +386,8 @@ void main() { '\n' '! Doctor found issues in 1 category.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); @@ -399,6 +400,8 @@ void main() { '\n' '! Doctor found issues in 1 category.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate non-verbose output format for a passing run', () async { @@ -415,6 +418,8 @@ void main() { '\n' '! Doctor found issues in 2 categories.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate non-verbose output format', () async { @@ -436,6 +441,8 @@ void main() { '\n' '! Doctor found issues in 4 categories.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate verbose output format', () async { @@ -466,6 +473,8 @@ void main() { '\n' '! Doctor found issues in 4 categories.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate PII can be hidden', () async { @@ -485,12 +494,14 @@ void main() { '\n' '• No issues found!\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); }); group('doctor diagnosis wrapper', () { - TestUsage testUsage; - BufferLogger logger; + late TestUsage testUsage; + late BufferLogger logger; setUp(() { testUsage = TestUsage(); @@ -527,6 +538,7 @@ void main() { ), ]); }, overrides: { + AnsiTerminal: () => FakeTerminal(), Usage: () => testUsage, }); @@ -572,6 +584,8 @@ void main() { '! Doctor found issues in 4\n' ' categories.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate verbose output wrapping', () async { @@ -616,6 +630,8 @@ void main() { '! Doctor found issues in 4\n' ' categories.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); group('doctor with grouped validators', () { @@ -632,6 +648,8 @@ void main() { '\n' '! Doctor found issues in 1 category.\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate merging assigns statusInfo and title', () async { @@ -644,6 +662,8 @@ void main() { '\n' '• No issues found!\n' )); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); }); @@ -655,54 +675,77 @@ void main() { testUsingContext('validate installed + installed = installed', () async { expect(await FakeSmallGroupDoctor(logger, installed, installed).diagnose(), isTrue); expect(logger.statusText, startsWith('[✓]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate installed + partial = partial', () async { expect(await FakeSmallGroupDoctor(logger, installed, partial).diagnose(), isTrue); expect(logger.statusText, startsWith('[!]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate installed + missing = partial', () async { expect(await FakeSmallGroupDoctor(logger, installed, missing).diagnose(), isTrue); expect(logger.statusText, startsWith('[!]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate partial + installed = partial', () async { expect(await FakeSmallGroupDoctor(logger, partial, installed).diagnose(), isTrue); expect(logger.statusText, startsWith('[!]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate partial + partial = partial', () async { expect(await FakeSmallGroupDoctor(logger, partial, partial).diagnose(), isTrue); expect(logger.statusText, startsWith('[!]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate partial + missing = partial', () async { expect(await FakeSmallGroupDoctor(logger, partial, missing).diagnose(), isTrue); expect(logger.statusText, startsWith('[!]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate missing + installed = partial', () async { expect(await FakeSmallGroupDoctor(logger, missing, installed).diagnose(), isTrue); expect(logger.statusText, startsWith('[!]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate missing + partial = partial', () async { expect(await FakeSmallGroupDoctor(logger, missing, partial).diagnose(), isTrue); expect(logger.statusText, startsWith('[!]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); testUsingContext('validate missing + missing = missing', () async { expect(await FakeSmallGroupDoctor(logger, missing, missing).diagnose(), isFalse); expect(logger.statusText, startsWith('[✗]')); + }, overrides: { + AnsiTerminal: () => FakeTerminal(), }); }); testUsingContext('WebWorkflow is a part of validator workflows if enabled', () async { - expect(DoctorValidatorsProvider.defaultInstance.workflows, - contains(isA())); + final List workflows = DoctorValidatorsProvider.test( + featureFlags: TestFeatureFlags(isWebEnabled: true), + platform: FakePlatform(), + ).workflows; + expect( + workflows, + contains(isA()), + ); }, overrides: { - FeatureFlags: () => TestFeatureFlags(isWebEnabled: true), FileSystem: () => MemoryFileSystem.test(), ProcessManager: () => fakeProcessManager, }); @@ -725,13 +768,30 @@ void main() { }, initializeFlutterRoot: false); testUsingContext('If android workflow is disabled, AndroidStudio validator is not included', () { - expect(DoctorValidatorsProvider.defaultInstance.validators, isNot(contains(isA()))); - expect(DoctorValidatorsProvider.defaultInstance.validators, isNot(contains(isA()))); + final DoctorValidatorsProvider provider = DoctorValidatorsProvider.test( + featureFlags: TestFeatureFlags(isAndroidEnabled: false), + ); + expect(provider.validators, isNot(contains(isA()))); + expect(provider.validators, isNot(contains(isA()))); }, overrides: { - FeatureFlags: () => TestFeatureFlags(isAndroidEnabled: false), + AndroidWorkflow: () => FakeAndroidWorkflow(appliesToHostPlatform: false), + }); +} + +class FakeAndroidWorkflow extends Fake implements AndroidWorkflow { + FakeAndroidWorkflow({ + this.canListDevices = true, + this.appliesToHostPlatform = true, }); + + @override + final bool canListDevices; + + @override + final bool appliesToHostPlatform; } + class NoOpDoctor implements Doctor { @override bool get canLaunchAnything => true; @@ -747,9 +807,9 @@ class NoOpDoctor implements Doctor { bool androidLicenses = false, bool verbose = true, bool showColor = true, - AndroidLicenseValidator androidLicenseValidator, + AndroidLicenseValidator? androidLicenseValidator, bool showPii = true, - List startedValidatorTasks, + List? startedValidatorTasks, bool sendEvent = true, }) async => true; @@ -767,7 +827,7 @@ class NoOpDoctor implements Doctor { } class PassingValidator extends DoctorValidator { - PassingValidator(String name) : super(name); + PassingValidator(super.name); @override Future validate() async { @@ -875,10 +935,10 @@ class AsyncCrashingValidator extends DoctorValidator { @override Future validate() { const Duration delay = Duration(seconds: 1); - final Future result = Future.delayed(delay) - .then((_) { - throw StateError('fatal error'); - }); + final Future result = Future.delayed( + delay, + () => throw StateError('fatal error'), + ); _time.elapse(const Duration(seconds: 1)); _time.flushMicrotasks(); return result; @@ -889,34 +949,27 @@ class AsyncCrashingValidator extends DoctorValidator { class FakeDoctor extends Doctor { FakeDoctor(Logger logger) : super(logger: logger); - List _validators; - @override - List get validators { - return _validators ??= [ - PassingValidator('Passing Validator'), - MissingValidator(), - NotAvailableValidator(), - PartialValidatorWithHintsOnly(), - PartialValidatorWithErrors(), - ]; - } + late final List validators = [ + PassingValidator('Passing Validator'), + MissingValidator(), + NotAvailableValidator(), + PartialValidatorWithHintsOnly(), + PartialValidatorWithErrors(), + ]; } /// A doctor that should pass, but still has issues in some categories. class FakePassingDoctor extends Doctor { FakePassingDoctor(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - return _validators ??= [ - PassingValidator('Passing Validator'), - PartialValidatorWithHintsOnly(), - PartialValidatorWithErrors(), - PassingValidator('Another Passing Validator'), - ]; - } + late final List validators = [ + PassingValidator('Passing Validator'), + PartialValidatorWithHintsOnly(), + PartialValidatorWithErrors(), + PassingValidator('Another Passing Validator'), + ]; } /// A doctor that should pass, but still has 1 issue to test the singular of @@ -924,80 +977,61 @@ class FakePassingDoctor extends Doctor { class FakeSinglePassingDoctor extends Doctor { FakeSinglePassingDoctor(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - return _validators ??= [ - PartialValidatorWithHintsOnly(), - ]; - } + late final List validators = [ + PartialValidatorWithHintsOnly(), + ]; } /// A doctor that passes and has no issues anywhere. class FakeQuietDoctor extends Doctor { FakeQuietDoctor(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - return _validators ??= [ - PassingValidator('Passing Validator'), - PassingValidator('Another Passing Validator'), - PassingValidator('Validators are fun'), - PassingValidator('Four score and seven validators ago'), - ]; - } + late final List validators = [ + PassingValidator('Passing Validator'), + PassingValidator('Another Passing Validator'), + PassingValidator('Validators are fun'), + PassingValidator('Four score and seven validators ago'), + ]; } /// A doctor that passes and contains PII that can be hidden. class FakePiiDoctor extends Doctor { FakePiiDoctor(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - return _validators ??= [ - PiiValidator(), - ]; - } + late final List validators = [ + PiiValidator(), + ]; } /// A doctor with a validator that throws an exception. class FakeCrashingDoctor extends Doctor { FakeCrashingDoctor(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - if (_validators == null) { - _validators = []; - _validators.add(PassingValidator('Passing Validator')); - _validators.add(PassingValidator('Another Passing Validator')); - _validators.add(CrashingValidator()); - _validators.add(PassingValidator('Validators are fun')); - _validators.add(PassingValidator('Four score and seven validators ago')); - } - return _validators; - } + late final List validators = [ + PassingValidator('Passing Validator'), + PassingValidator('Another Passing Validator'), + CrashingValidator(), + PassingValidator('Validators are fun'), + PassingValidator('Four score and seven validators ago'), + ]; } /// A doctor with a validator that will never finish. class FakeAsyncStuckDoctor extends Doctor { FakeAsyncStuckDoctor(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - if (_validators == null) { - _validators = []; - _validators.add(PassingValidator('Passing Validator')); - _validators.add(PassingValidator('Another Passing Validator')); - _validators.add(StuckValidator()); - _validators.add(PassingValidator('Validators are fun')); - _validators.add(PassingValidator('Four score and seven validators ago')); - } - return _validators; - } + late final List validators = [ + PassingValidator('Passing Validator'), + PassingValidator('Another Passing Validator'), + StuckValidator(), + PassingValidator('Validators are fun'), + PassingValidator('Four score and seven validators ago'), + ]; } /// A doctor with a validator that throws an exception. @@ -1006,19 +1040,14 @@ class FakeAsyncCrashingDoctor extends Doctor { final FakeAsync _time; - List _validators; @override - List get validators { - if (_validators == null) { - _validators = []; - _validators.add(PassingValidator('Passing Validator')); - _validators.add(PassingValidator('Another Passing Validator')); - _validators.add(AsyncCrashingValidator(_time)); - _validators.add(PassingValidator('Validators are fun')); - _validators.add(PassingValidator('Four score and seven validators ago')); - } - return _validators; - } + late final List validators = [ + PassingValidator('Passing Validator'), + PassingValidator('Another Passing Validator'), + AsyncCrashingValidator(_time), + PassingValidator('Validators are fun'), + PassingValidator('Four score and seven validators ago'), + ]; } /// A DoctorValidatorsProvider that overrides the default validators without @@ -1038,7 +1067,7 @@ class FakeDoctorValidatorsProvider implements DoctorValidatorsProvider { } class PassingGroupedValidator extends DoctorValidator { - PassingGroupedValidator(String name) : super(name); + PassingGroupedValidator(super.name); @override Future validate() async { @@ -1050,7 +1079,7 @@ class PassingGroupedValidator extends DoctorValidator { } class MissingGroupedValidator extends DoctorValidator { - MissingGroupedValidator(String name) : super(name); + MissingGroupedValidator(super.name); @override Future validate() async { @@ -1062,7 +1091,7 @@ class MissingGroupedValidator extends DoctorValidator { } class PartialGroupedValidator extends DoctorValidator { - PartialGroupedValidator(String name) : super(name); + PartialGroupedValidator(super.name); @override Future validate() async { @@ -1074,7 +1103,7 @@ class PartialGroupedValidator extends DoctorValidator { } class PassingGroupedValidatorWithStatus extends DoctorValidator { - PassingGroupedValidatorWithStatus(String name) : super(name); + PassingGroupedValidatorWithStatus(super.name); @override Future validate() async { @@ -1089,52 +1118,44 @@ class PassingGroupedValidatorWithStatus extends DoctorValidator { class FakeGroupedDoctor extends Doctor { FakeGroupedDoctor(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - return _validators ??= [ - GroupedValidator([ - PassingGroupedValidator('Category 1'), - PassingGroupedValidator('Category 1'), - ]), - GroupedValidator([ - PassingGroupedValidator('Category 2'), - MissingGroupedValidator('Category 2'), - ]), - ]; - } + late final List validators = [ + GroupedValidator([ + PassingGroupedValidator('Category 1'), + PassingGroupedValidator('Category 1'), + ]), + GroupedValidator([ + PassingGroupedValidator('Category 2'), + MissingGroupedValidator('Category 2'), + ]), + ]; } class FakeGroupedDoctorWithStatus extends Doctor { FakeGroupedDoctorWithStatus(Logger logger) : super(logger: logger); - List _validators; @override - List get validators { - return _validators ??= [ - GroupedValidator([ - PassingGroupedValidator('First validator title'), - PassingGroupedValidatorWithStatus('Second validator title'), - ]), - ]; - } + late final List validators = [ + GroupedValidator([ + PassingGroupedValidator('First validator title'), + PassingGroupedValidatorWithStatus('Second validator title'), + ]), + ]; } /// A doctor that takes any two validators. Used to check behavior when /// merging ValidationTypes (installed, missing, partial). class FakeSmallGroupDoctor extends Doctor { - FakeSmallGroupDoctor(Logger logger, DoctorValidator val1, DoctorValidator val2) : super(logger: logger) { - _validators = [GroupedValidator([val1, val2])]; - } - - List _validators; + FakeSmallGroupDoctor(Logger logger, DoctorValidator val1, DoctorValidator val2) + : validators = [GroupedValidator([val1, val2])], + super(logger: logger); @override - List get validators => _validators; + final List validators; } class VsCodeValidatorTestTargets extends VsCodeValidator { - VsCodeValidatorTestTargets._(String installDirectory, String extensionDirectory, {String edition}) + VsCodeValidatorTestTargets._(String installDirectory, String extensionDirectory, {String? edition}) : super(VsCode.fromDirectory(installDirectory, extensionDirectory, edition: edition, fileSystem: globals.fs)); static VsCodeValidatorTestTargets get installedWithExtension => @@ -1190,3 +1211,8 @@ class FakeDevice extends Fake implements Device { @override Future get targetPlatform => Future.value(TargetPlatform.android); } + +class FakeTerminal extends Fake implements AnsiTerminal { + @override + final bool supportsColor = false; +} diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart index 7eb2d8263c538..4ebcb4ff40c51 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart @@ -520,6 +520,37 @@ void main() { Stdio: () => FakeStdio(), Logger: () => AppRunLogger(parent: BufferLogger.test()), }); + + testUsingContext('can pass --device-user', () async { + final DaemonCapturingRunCommand command = DaemonCapturingRunCommand(); + final FakeDevice device = FakeDevice(platformType: PlatformType.android); + mockDeviceManager + ..devices = [device] + ..targetDevices = [device]; + + await expectLater( + () => createTestCommandRunner(command).run([ + 'run', + '--no-pub', + '--machine', + '--device-user', + '10', + '-d', + device.id, + ]), + throwsToolExit(), + ); + expect(command.appDomain.userIdentifier, '10'); + }, overrides: { + Artifacts: () => artifacts, + Cache: () => Cache.test(processManager: FakeProcessManager.any()), + DeviceManager: () => mockDeviceManager, + FileSystem: () => fs, + ProcessManager: () => FakeProcessManager.any(), + Usage: () => usage, + Stdio: () => FakeStdio(), + Logger: () => AppRunLogger(parent: BufferLogger.test()), + }); }); }); @@ -1080,6 +1111,7 @@ class CapturingAppDomain extends AppDomain { CapturingAppDomain(Daemon daemon) : super(daemon); bool /*?*/ multidexEnabled; + String /*?*/ userIdentifier; @override Future startApp( @@ -1098,8 +1130,10 @@ class CapturingAppDomain extends AppDomain { bool multidexEnabled = false, String isolateFilter, bool machine = true, + String userIdentifier, }) async { this.multidexEnabled = multidexEnabled; + this.userIdentifier = userIdentifier; throwToolExit(''); } } diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart index c0cbc05a73786..0f76d522d15c0 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart @@ -397,6 +397,7 @@ flutter: late Artifacts artifacts; late String impellerc; late Directory output; + late String assetsPath; late String shaderPath; late String outputPath; @@ -408,8 +409,9 @@ flutter: fileSystem.file(impellerc).createSync(recursive: true); output = fileSystem.directory('asset_output')..createSync(recursive: true); - shaderPath = fileSystem.path.join('assets', 'shader.frag'); - outputPath = fileSystem.path.join(output.path, 'assets', 'shader.frag'); + assetsPath = 'assets'; + shaderPath = fileSystem.path.join(assetsPath, 'shader.frag'); + outputPath = fileSystem.path.join(output.path, assetsPath, 'shader.frag'); fileSystem.file(shaderPath).createSync(recursive: true); }); @@ -445,6 +447,7 @@ flutter: '--spirv=$outputPath', '--input=/$shaderPath', '--input-type=frag', + '--include=/$assetsPath', ], onRun: () { fileSystem.file(outputPath).createSync(recursive: true); diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/shader_compiler_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/shader_compiler_test.dart index 456e9fa6670c5..08c199eb505c0 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/shader_compiler_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/shader_compiler_test.dart @@ -10,6 +10,7 @@ import 'package:flutter_tools/src/build_system/targets/shader_compiler.dart'; import '../../../src/common.dart'; import '../../../src/fake_process_manager.dart'; +const String fragDir = '/shaders'; const String fragPath = '/shaders/my_shader.frag'; const String notFragPath = '/shaders/not_a_frag.file'; const String outputPath = '/output/shaders/my_shader.spv'; @@ -40,6 +41,7 @@ void main() { '--spirv=$outputPath', '--input=$fragPath', '--input-type=frag', + '--include=$fragDir', ], onRun: () { fileSystem.file(outputPath).createSync(recursive: true); @@ -72,6 +74,7 @@ void main() { '--spirv=$outputPath', '--input=$notFragPath', '--input-type=frag', + '--include=$fragDir', ], onRun: () { fileSystem.file(outputPath).createSync(recursive: true); @@ -104,6 +107,7 @@ void main() { '--spirv=$outputPath', '--input=$notFragPath', '--input-type=frag', + '--include=$fragDir', ], exitCode: 1, ), diff --git a/packages/flutter_tools/test/general.shard/devfs_test.dart b/packages/flutter_tools/test/general.shard/devfs_test.dart index 0b0579baecca6..75a6da85f9efe 100644 --- a/packages/flutter_tools/test/general.shard/devfs_test.dart +++ b/packages/flutter_tools/test/general.shard/devfs_test.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' as io show ProcessSignal, Process; +import 'dart:io' as io show Process, ProcessSignal; import 'package:file/file.dart'; import 'package:file/memory.dart'; diff --git a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart index 692a198751ecd..8516df6410e29 100644 --- a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart +++ b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart @@ -180,6 +180,32 @@ void main() { ); }); + testWithoutContext('throws error when arb file does not exist', () { + // Set up project directory. + fs.currentDirectory + .childDirectory('lib') + .childDirectory('l10n') + .createSync(recursive: true); + + // Arb file should be nonexistent in the l10n directory. + expect( + () => LocalizationsGenerator( + fileSystem: fs, + projectPathString: './', + inputPathString: defaultL10nPathString, + outputPathString: defaultL10nPathString, + templateArbFileName: defaultTemplateArbFileName, + outputFileString: defaultOutputFileString, + classNameString: defaultClassNameString, + ), + throwsA(isA().having( + (L10nException e) => e.message, + 'message', + contains(', does not exist.'), + )), + ); + }); + group('className should only take valid Dart class names', () { setUp(() { _standardFlutterDirectoryL10nSetup(fs); @@ -966,9 +992,7 @@ class AppLocalizationsEn extends AppLocalizations { }); testWithoutContext( - 'throws an error attempting to add preferred locales ' - 'when there is no corresponding arb file for that ' - 'locale', + 'throws an error attempting to add preferred locales when there is no corresponding arb file for that locale', () { final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') ..createSync(recursive: true); @@ -1135,6 +1159,38 @@ class AppLocalizationsEn extends AppLocalizations { )), ); }); + + testWithoutContext('throws when an empty string is used as a key', () { + const String arbFileStringWithEmptyResourceId = ''' +{ + "market": "MARKET", + "": { + "description": "This key is invalid" + } +}'''; + + final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n') + ..createSync(recursive: true); + l10nDirectory.childFile('app_en.arb') + .writeAsStringSync(arbFileStringWithEmptyResourceId); + + expect( + () => LocalizationsGenerator( + fileSystem: fs, + inputPathString: defaultL10nPathString, + outputPathString: defaultL10nPathString, + templateArbFileName: 'app_en.arb', + outputFileString: defaultOutputFileString, + classNameString: defaultClassNameString, + ).loadResources(), + throwsA(isA().having( + (L10nException e) => e.message, + 'message', + contains('Invalid ARB resource name ""'), + )), + ); + }); + testWithoutContext('throws when the same locale is detected more than once', () { const String secondMessageArbFileString = ''' { diff --git a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart index ef08b9497f9b7..4c43180d978c0 100644 --- a/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/ios_project_migration_test.dart @@ -6,8 +6,8 @@ import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/project_migrator.dart'; -import 'package:flutter_tools/src/ios/migrations/deployment_target_migration.dart'; import 'package:flutter_tools/src/ios/migrations/host_app_info_plist_migration.dart'; +import 'package:flutter_tools/src/ios/migrations/ios_deployment_target_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_base_configuration_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_build_location_migration.dart'; import 'package:flutter_tools/src/ios/migrations/project_object_version_migration.dart'; @@ -514,7 +514,7 @@ keep this 3 }); testWithoutContext('skipped if files are missing', () { - final DeploymentTargetMigration iosProjectMigration = DeploymentTargetMigration( + final IOSDeploymentTargetMigration iosProjectMigration = IOSDeploymentTargetMigration( project, testLogger, ); @@ -525,7 +525,7 @@ keep this 3 expect(testLogger.traceText, contains('Xcode project not found, skipping iOS deployment target version migration')); expect(testLogger.traceText, contains('AppFrameworkInfo.plist not found, skipping minimum OS version migration')); - expect(testLogger.traceText, contains('Podfile not found, skipping global platform version migration')); + expect(testLogger.traceText, contains('Podfile not found, skipping global platform iOS version migration')); expect(testLogger.statusText, isEmpty); }); @@ -545,7 +545,7 @@ keep this 3 podfile.writeAsStringSync(podfileFileContents); final DateTime podfileLastModified = podfile.lastModifiedSync(); - final DeploymentTargetMigration iosProjectMigration = DeploymentTargetMigration( + final IOSDeploymentTargetMigration iosProjectMigration = IOSDeploymentTargetMigration( project, testLogger, ); @@ -591,7 +591,7 @@ keep this 3 platform :ios, '9.0' '''); - final DeploymentTargetMigration iosProjectMigration = DeploymentTargetMigration( + final IOSDeploymentTargetMigration iosProjectMigration = IOSDeploymentTargetMigration( project, testLogger, ); diff --git a/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart b/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart index 380508f389a6c..693122ca5d891 100644 --- a/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/macos_project_migration_test.dart @@ -5,6 +5,7 @@ import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/macos/migrations/macos_deployment_target_migration.dart'; import 'package:flutter_tools/src/macos/migrations/remove_macos_framework_link_and_embedding_migration.dart'; import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/xcode_project.dart'; @@ -13,80 +14,81 @@ import 'package:test/fake.dart'; import '../../src/common.dart'; void main() { - late TestUsage testUsage; - late MemoryFileSystem memoryFileSystem; - late BufferLogger testLogger; - late FakeMacOSProject macOSProject; - late File xcodeProjectInfoFile; - - setUp(() { - testUsage = TestUsage(); - memoryFileSystem = MemoryFileSystem.test(); - xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj'); - testLogger = BufferLogger.test(); - macOSProject = FakeMacOSProject(); - macOSProject.xcodeProjectInfoFile = xcodeProjectInfoFile; - }); - - testWithoutContext('skipped if files are missing', () { - final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = - RemoveMacOSFrameworkLinkAndEmbeddingMigration( - macOSProject, - testLogger, - testUsage, - ); - expect(macosProjectMigration.migrate(), isTrue); - expect(testUsage.events, isEmpty); - - expect(xcodeProjectInfoFile.existsSync(), isFalse); - - expect( - testLogger.traceText, - contains( - 'Xcode project not found, skipping framework link and embedding migration')); - expect(testLogger.statusText, isEmpty); - }); - - testWithoutContext('skipped if nothing to upgrade', () { - const String contents = 'Nothing to upgrade'; - xcodeProjectInfoFile.writeAsStringSync(contents); - final DateTime projectLastModified = - xcodeProjectInfoFile.lastModifiedSync(); - - final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = - RemoveMacOSFrameworkLinkAndEmbeddingMigration( - macOSProject, - testLogger, - testUsage, - ); - expect(macosProjectMigration.migrate(), isTrue); - expect(testUsage.events, isEmpty); - - expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified); - expect(xcodeProjectInfoFile.readAsStringSync(), contents); - - expect(testLogger.statusText, isEmpty); - }); - - testWithoutContext('skips migrating script with embed', () { - const String contents = r''' + group('remove link and embed migration', () { + late TestUsage testUsage; + late MemoryFileSystem memoryFileSystem; + late BufferLogger testLogger; + late FakeMacOSProject macOSProject; + late File xcodeProjectInfoFile; + + setUp(() { + testUsage = TestUsage(); + memoryFileSystem = MemoryFileSystem.test(); + xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj'); + testLogger = BufferLogger.test(); + macOSProject = FakeMacOSProject(); + macOSProject.xcodeProjectInfoFile = xcodeProjectInfoFile; + }); + + testWithoutContext('skipped if files are missing', () { + final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = + RemoveMacOSFrameworkLinkAndEmbeddingMigration( + macOSProject, + testLogger, + testUsage, + ); + expect(macosProjectMigration.migrate(), isTrue); + expect(testUsage.events, isEmpty); + + expect(xcodeProjectInfoFile.existsSync(), isFalse); + + expect( + testLogger.traceText, + contains( + 'Xcode project not found, skipping framework link and embedding migration')); + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('skipped if nothing to upgrade', () { + const String contents = 'Nothing to upgrade'; + xcodeProjectInfoFile.writeAsStringSync(contents); + final DateTime projectLastModified = + xcodeProjectInfoFile.lastModifiedSync(); + + final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = + RemoveMacOSFrameworkLinkAndEmbeddingMigration( + macOSProject, + testLogger, + testUsage, + ); + expect(macosProjectMigration.migrate(), isTrue); + expect(testUsage.events, isEmpty); + + expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified); + expect(xcodeProjectInfoFile.readAsStringSync(), contents); + + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('skips migrating script with embed', () { + const String contents = r''' shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; '''; - xcodeProjectInfoFile.writeAsStringSync(contents); - - final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = - RemoveMacOSFrameworkLinkAndEmbeddingMigration( - macOSProject, - testLogger, - testUsage, - ); - expect(macosProjectMigration.migrate(), isTrue); - expect(xcodeProjectInfoFile.readAsStringSync(), contents); - expect(testLogger.statusText, isEmpty); - }); - - testWithoutContext('Xcode project is migrated', () { - xcodeProjectInfoFile.writeAsStringSync(r''' + xcodeProjectInfoFile.writeAsStringSync(contents); + + final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = + RemoveMacOSFrameworkLinkAndEmbeddingMigration( + macOSProject, + testLogger, + testUsage, + ); + expect(macosProjectMigration.migrate(), isTrue); + expect(xcodeProjectInfoFile.readAsStringSync(), contents); + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('Xcode project is migrated', () { + xcodeProjectInfoFile.writeAsStringSync(r''' prefix D73912F022F37F9E000D13A0 D73912F222F3801D000D13A0 suffix D73912EF22F37F9E000D13A0 @@ -97,64 +99,156 @@ keep this 1 keep this 2 '''); - final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = - RemoveMacOSFrameworkLinkAndEmbeddingMigration( - macOSProject, - testLogger, - testUsage, - ); - expect(macosProjectMigration.migrate(), isTrue); - expect(testUsage.events, isEmpty); + final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = + RemoveMacOSFrameworkLinkAndEmbeddingMigration( + macOSProject, + testLogger, + testUsage, + ); + expect(macosProjectMigration.migrate(), isTrue); + expect(testUsage.events, isEmpty); - expect(xcodeProjectInfoFile.readAsStringSync(), r''' + expect(xcodeProjectInfoFile.readAsStringSync(), r''' keep this 1 shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; keep this 2 '''); - expect(testLogger.statusText, contains('Upgrading project.pbxproj')); - }); + expect(testLogger.statusText, contains('Upgrading project.pbxproj')); + }); - testWithoutContext('migration fails with leftover App.framework reference', - () { - xcodeProjectInfoFile.writeAsStringSync(''' + testWithoutContext('migration fails with leftover App.framework reference', () { + xcodeProjectInfoFile.writeAsStringSync(''' D73912F022F37F9bogus /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912F022F37F9bogus /* App.framework */; }; '''); - final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = - RemoveMacOSFrameworkLinkAndEmbeddingMigration( - macOSProject, - testLogger, - testUsage, - ); - - expect(macosProjectMigration.migrate, - throwsToolExit(message: 'Your Xcode project requires migration')); - expect(testUsage.events, contains( - const TestUsageEvent('macos-migration', 'remove-frameworks', label: 'failure'), - )); + final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = + RemoveMacOSFrameworkLinkAndEmbeddingMigration( + macOSProject, + testLogger, + testUsage, + ); + + expect(macosProjectMigration.migrate, + throwsToolExit(message: 'Your Xcode project requires migration')); + expect(testUsage.events, contains( + const TestUsageEvent('macos-migration', 'remove-frameworks', label: 'failure'), + )); + }); + + testWithoutContext( + 'migration fails with leftover FlutterMacOS.framework reference', () { + xcodeProjectInfoFile.writeAsStringSync(''' + 33D1A10522148B93bogus /* FlutterMacOS.framework in Bundle Framework */, +'''); + + final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = + RemoveMacOSFrameworkLinkAndEmbeddingMigration( + macOSProject, + testLogger, + testUsage, + ); + expect(macosProjectMigration.migrate, + throwsToolExit(message: 'Your Xcode project requires migration')); + expect(testUsage.events, contains( + const TestUsageEvent('macos-migration', 'remove-frameworks', label: 'failure'), + )); + }); }); - testWithoutContext( - 'migration fails with leftover FlutterMacOS.framework reference', () { - xcodeProjectInfoFile.writeAsStringSync(''' - 33D1A10522148B93bogus /* FlutterMacOS.framework in Bundle Framework */, + group('update deployment target version', () { + late MemoryFileSystem memoryFileSystem; + late BufferLogger testLogger; + late FakeMacOSProject project; + late File xcodeProjectInfoFile; + late File podfile; + + setUp(() { + memoryFileSystem = MemoryFileSystem(); + testLogger = BufferLogger.test(); + project = FakeMacOSProject(); + xcodeProjectInfoFile = memoryFileSystem.file('project.pbxproj'); + project.xcodeProjectInfoFile = xcodeProjectInfoFile; + + podfile = memoryFileSystem.file('Podfile'); + project.podfile = podfile; + }); + + testWithoutContext('skipped if files are missing', () { + final MacOSDeploymentTargetMigration macOSProjectMigration = MacOSDeploymentTargetMigration( + project, + testLogger, + ); + expect(macOSProjectMigration.migrate(), isTrue); + expect(xcodeProjectInfoFile.existsSync(), isFalse); + expect(podfile.existsSync(), isFalse); + + expect(testLogger.traceText, contains('Xcode project not found, skipping macOS deployment target version migration')); + expect(testLogger.traceText, contains('Podfile not found, skipping global platform macOS version migration')); + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('skipped if nothing to upgrade', () { + const String xcodeProjectInfoFileContents = 'IPHONEOS_DEPLOYMENT_TARGET = 11.0;'; + xcodeProjectInfoFile.writeAsStringSync(xcodeProjectInfoFileContents); + + final DateTime projectLastModified = xcodeProjectInfoFile.lastModifiedSync(); + + const String podfileFileContents = "# platform :osx, '10.13'"; + podfile.writeAsStringSync(podfileFileContents); + final DateTime podfileLastModified = podfile.lastModifiedSync(); + + final MacOSDeploymentTargetMigration macOSProjectMigration = MacOSDeploymentTargetMigration( + project, + testLogger, + ); + expect(macOSProjectMigration.migrate(), isTrue); + + expect(xcodeProjectInfoFile.lastModifiedSync(), projectLastModified); + expect(xcodeProjectInfoFile.readAsStringSync(), xcodeProjectInfoFileContents); + expect(podfile.lastModifiedSync(), podfileLastModified); + expect(podfile.readAsStringSync(), podfileFileContents); + + expect(testLogger.statusText, isEmpty); + }); + + testWithoutContext('Xcode project is migrated to 10.13', () { + xcodeProjectInfoFile.writeAsStringSync(''' + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.11; + MTL_ENABLE_DEBUG_INFO = YES; +'''); + + podfile.writeAsStringSync(''' +# platform :osx, '10.11' +platform :osx, '10.11' +'''); + + final MacOSDeploymentTargetMigration macOSProjectMigration = MacOSDeploymentTargetMigration( + project, + testLogger, + ); + expect(macOSProjectMigration.migrate(), isTrue); + + expect(xcodeProjectInfoFile.readAsStringSync(), ''' + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MTL_ENABLE_DEBUG_INFO = YES; '''); - final RemoveMacOSFrameworkLinkAndEmbeddingMigration macosProjectMigration = - RemoveMacOSFrameworkLinkAndEmbeddingMigration( - macOSProject, - testLogger, - testUsage, - ); - expect(macosProjectMigration.migrate, - throwsToolExit(message: 'Your Xcode project requires migration')); - expect(testUsage.events, contains( - const TestUsageEvent('macos-migration', 'remove-frameworks', label: 'failure'), - )); + expect(podfile.readAsStringSync(), ''' +# platform :osx, '10.13' +platform :osx, '10.13' +'''); + // Only print once even though 2 lines were changed. + expect('Updating minimum macOS deployment target to 10.13'.allMatches(testLogger.statusText).length, 1); + }); }); } class FakeMacOSProject extends Fake implements MacOSProject { @override File xcodeProjectInfoFile = MemoryFileSystem.test().file('xcodeProjectInfoFile'); + + @override + File podfile = MemoryFileSystem.test().file('Podfile'); } diff --git a/packages/flutter_tools/test/general.shard/pub_dependencies_project_validator_test.dart b/packages/flutter_tools/test/general.shard/pub_dependencies_project_validator_test.dart new file mode 100644 index 0000000000000..7591604f5dfd6 --- /dev/null +++ b/packages/flutter_tools/test/general.shard/pub_dependencies_project_validator_test.dart @@ -0,0 +1,77 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:file/memory.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; +import 'package:flutter_tools/src/project.dart'; +import 'package:flutter_tools/src/project_validator.dart'; +import 'package:flutter_tools/src/project_validator_result.dart'; + +import '../src/common.dart'; +import '../src/context.dart'; + +void main() { + late FileSystem fileSystem; + + group('PubDependenciesProjectValidator', () { + + setUp(() { + fileSystem = MemoryFileSystem.test(); + }); + + testWithoutContext('success when all dependencies are hosted', () async { + final ProcessManager processManager = FakeProcessManager.list([ + const FakeCommand( + command: ['dart', 'pub', 'deps', '--json'], + stdout: '{"packages": [{"dependencies": ["abc"], "source": "hosted"}]}', + ), + ]); + final PubDependenciesProjectValidator validator = PubDependenciesProjectValidator(processManager); + + final List result = await validator.start( + FlutterProject.fromDirectoryTest(fileSystem.currentDirectory) + ); + const String expected = 'All pub dependencies are hosted on https://pub.dartlang.org'; + expect(result.length, 1); + expect(result[0].value, expected); + expect(result[0].status, StatusProjectValidator.success); + }); + + testWithoutContext('error when command dart pub deps fails', () async { + final ProcessManager processManager = FakeProcessManager.list([ + const FakeCommand( + command: ['dart', 'pub', 'deps', '--json'], + stderr: 'command fail', + ), + ]); + final PubDependenciesProjectValidator validator = PubDependenciesProjectValidator(processManager); + + final List result = await validator.start( + FlutterProject.fromDirectoryTest(fileSystem.currentDirectory) + ); + const String expected = 'command fail'; + expect(result.length, 1); + expect(result[0].value, expected); + expect(result[0].status, StatusProjectValidator.error); + }); + + testWithoutContext('warning on dependencies not hosted', () async { + final ProcessManager processManager = FakeProcessManager.list([ + const FakeCommand( + command: ['dart', 'pub', 'deps', '--json'], + stdout: '{"packages": [{"dependencies": ["dep1", "dep2"], "source": "other"}]}', + ), + ]); + final PubDependenciesProjectValidator validator = PubDependenciesProjectValidator(processManager); + + final List result = await validator.start( + FlutterProject.fromDirectoryTest(fileSystem.currentDirectory) + ); + const String expected = 'dep1, dep2 are not hosted'; + expect(result.length, 1); + expect(result[0].value, expected); + expect(result[0].status, StatusProjectValidator.warning); + }); + }); +} diff --git a/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart b/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart index 52cbb17691ef3..cae469f244738 100644 --- a/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart +++ b/packages/flutter_tools/test/integration.shard/analyze_suggestions_integration_test.dart @@ -54,5 +54,36 @@ void main() { expect(loggerTest.statusText, contains(expected)); }); + + testUsingContext('PubDependenciesProjectValidator success ', () async { + final BufferLogger loggerTest = BufferLogger.test(); + final AnalyzeCommand command = AnalyzeCommand( + artifacts: globals.artifacts!, + fileSystem: fileSystem, + logger: loggerTest, + platform: globals.platform, + terminal: globals.terminal, + processManager: globals.processManager, + allProjectValidators: [ + PubDependenciesProjectValidator(globals.processManager), + ], + ); + final CommandRunner runner = createTestCommandRunner(command); + + await runner.run([ + 'analyze', + '--no-pub', + '--no-current-package', + '--suggestions', + '../../dev/integration_tests/flutter_gallery', + ]); + + const String expected = '\n' + '┌────────────────────────────────────────────────────────────────────────────────────┐\n' + '│ Pub dependencies │\n' + '│ [✓] Dart dependencies: All pub dependencies are hosted on https://pub.dartlang.org │\n' + '└────────────────────────────────────────────────────────────────────────────────────┘\n'; + expect(loggerTest.statusText, contains(expected)); + }); }); } diff --git a/packages/flutter_tools/test/src/common.dart b/packages/flutter_tools/test/src/common.dart index 6be11e1e60e79..804e79d8c0da9 100644 --- a/packages/flutter_tools/test/src/common.dart +++ b/packages/flutter_tools/test/src/common.dart @@ -16,7 +16,7 @@ import 'package:path/path.dart' as path; // flutter_ignore: package_path_import import 'package:test_api/test_api.dart' as test_package show test; // ignore: deprecated_member_use import 'package:test_api/test_api.dart' hide test; // ignore: deprecated_member_use -export 'package:test_api/test_api.dart' hide test, isInstanceOf; // ignore: deprecated_member_use +export 'package:test_api/test_api.dart' hide isInstanceOf, test; // ignore: deprecated_member_use void tryToDelete(FileSystemEntity fileEntity) { // This should not be necessary, but it turns out that diff --git a/packages/flutter_tools/test/src/context.dart b/packages/flutter_tools/test/src/context.dart index 39a1ebf24f3e4..82d76b0e81c9e 100644 --- a/packages/flutter_tools/test/src/context.dart +++ b/packages/flutter_tools/test/src/context.dart @@ -44,7 +44,7 @@ import 'throwing_pub.dart'; export 'package:flutter_tools/src/base/context.dart' show Generator; -export 'fake_process_manager.dart' show ProcessManager, FakeProcessManager, FakeCommand; +export 'fake_process_manager.dart' show FakeCommand, FakeProcessManager, ProcessManager; /// Return the test logger. This assumes that the current Logger is a BufferLogger. BufferLogger get testLogger => context.get()! as BufferLogger; diff --git a/packages/flutter_tools/test/src/fake_process_manager.dart b/packages/flutter_tools/test/src/fake_process_manager.dart index 59194a0343afe..d45baba64378a 100644 --- a/packages/flutter_tools/test/src/fake_process_manager.dart +++ b/packages/flutter_tools/test/src/fake_process_manager.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' as io show ProcessSignal, Process, ProcessStartMode, ProcessResult, systemEncoding; +import 'dart:io' as io show Process, ProcessResult, ProcessSignal, ProcessStartMode, systemEncoding; import 'package:file/file.dart'; import 'package:meta/meta.dart'; diff --git a/packages/flutter_tools/test/src/fake_vm_services.dart b/packages/flutter_tools/test/src/fake_vm_services.dart index 09e6931e9ae1e..1d978e5b8d31d 100644 --- a/packages/flutter_tools/test/src/fake_vm_services.dart +++ b/packages/flutter_tools/test/src/fake_vm_services.dart @@ -9,7 +9,7 @@ import 'package:flutter_tools/src/vmservice.dart'; import 'package:test_api/test_api.dart' hide test; // ignore: deprecated_member_use import 'package:vm_service/vm_service.dart' as vm_service; -export 'package:test_api/test_api.dart' hide test, isInstanceOf; // ignore: deprecated_member_use +export 'package:test_api/test_api.dart' hide isInstanceOf, test; // ignore: deprecated_member_use /// A fake implementation of a vm_service that mocks the JSON-RPC request /// and response structure. diff --git a/packages/flutter_tools/test/src/io.dart b/packages/flutter_tools/test/src/io.dart index 2a83448c2a0be..43cf2689e4b1f 100644 --- a/packages/flutter_tools/test/src/io.dart +++ b/packages/flutter_tools/test/src/io.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io' as io show IOOverrides, Directory, File, Link; +import 'dart:io' as io show Directory, File, IOOverrides, Link; import 'package:flutter_tools/src/base/file_system.dart'; diff --git a/packages/flutter_tools/test/src/test_flutter_command_runner.dart b/packages/flutter_tools/test/src/test_flutter_command_runner.dart index 528a01c4ef31a..22b68f1793a44 100644 --- a/packages/flutter_tools/test/src/test_flutter_command_runner.dart +++ b/packages/flutter_tools/test/src/test_flutter_command_runner.dart @@ -16,7 +16,7 @@ import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:flutter_tools/src/runner/flutter_command_runner.dart'; -export 'package:test_api/test_api.dart' hide test, isInstanceOf; // ignore: deprecated_member_use +export 'package:test_api/test_api.dart' hide isInstanceOf, test; // ignore: deprecated_member_use CommandRunner createTestCommandRunner([ FlutterCommand? command ]) { final FlutterCommandRunner runner = TestFlutterCommandRunner(); diff --git a/packages/integration_test/lib/integration_test.dart b/packages/integration_test/lib/integration_test.dart index a2f84c41d65d0..816158c857df6 100644 --- a/packages/integration_test/lib/integration_test.dart +++ b/packages/integration_test/lib/integration_test.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'dart:developer' as developer; -import 'dart:io' show SocketException, WebSocket, HttpClient; +import 'dart:io' show HttpClient, SocketException, WebSocket; import 'dart:ui'; import 'package:flutter/foundation.dart';