Skip to content

Commit a9d6a5c

Browse files
authored
Merge branch 'master' into rm-sbl-framework_tests_misc
2 parents 4380837 + f31dae2 commit a9d6a5c

File tree

34 files changed

+1282
-231
lines changed

34 files changed

+1282
-231
lines changed

.ci.yaml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4034,9 +4034,10 @@ targets:
40344034
- bin/**
40354035
- .ci.yaml
40364036

4037-
- name: Windows build_tests_1_3
4037+
- name: Windows build_tests_1_4
40384038
recipe: flutter/flutter_drone
40394039
timeout: 60
4040+
bringup: true
40404041
properties:
40414042
add_recipes_cq: "true"
40424043
dependencies: >-
@@ -4048,13 +4049,14 @@ targets:
40484049
{"dependency": "vs_build", "version": "version:vs2019"}
40494050
]
40504051
shard: build_tests
4051-
subshard: "1_3"
4052+
subshard: "1_4"
40524053
tags: >
40534054
["framework", "hostonly", "shard", "windows"]
40544055
4055-
- name: Windows build_tests_2_3
4056+
- name: Windows build_tests_2_4
40564057
recipe: flutter/flutter_drone
40574058
timeout: 60
4059+
bringup: true
40584060
properties:
40594061
add_recipes_cq: "true"
40604062
dependencies: >-
@@ -4066,13 +4068,14 @@ targets:
40664068
{"dependency": "vs_build", "version": "version:vs2019"}
40674069
]
40684070
shard: build_tests
4069-
subshard: "2_3"
4071+
subshard: "2_4"
40704072
tags: >
40714073
["framework", "hostonly", "shard", "windows"]
40724074
4073-
- name: Windows build_tests_3_3
4075+
- name: Windows build_tests_3_4
40744076
recipe: flutter/flutter_drone
40754077
timeout: 60
4078+
bringup: true
40764079
properties:
40774080
add_recipes_cq: "true"
40784081
dependencies: >-
@@ -4084,7 +4087,26 @@ targets:
40844087
{"dependency": "vs_build", "version": "version:vs2019"}
40854088
]
40864089
shard: build_tests
4087-
subshard: "3_3"
4090+
subshard: "3_4"
4091+
tags: >
4092+
["framework", "hostonly", "shard", "windows"]
4093+
4094+
- name: Windows build_tests_4_4
4095+
recipe: flutter/flutter_drone
4096+
timeout: 60
4097+
bringup: true
4098+
properties:
4099+
add_recipes_cq: "true"
4100+
dependencies: >-
4101+
[
4102+
{"dependency": "android_sdk", "version": "version:33v6"},
4103+
{"dependency": "chrome_and_driver", "version": "version:96.2"},
4104+
{"dependency": "open_jdk", "version": "version:11"},
4105+
{"dependency": "goldctl", "version": "git_revision:3a77d0b12c697a840ca0c7705208e8622dc94603"},
4106+
{"dependency": "vs_build", "version": "version:vs2019"}
4107+
]
4108+
shard: build_tests
4109+
subshard: "4_4"
40884110
tags: >
40894111
["framework", "hostonly", "shard", "windows"]
40904112

.github/workflows/labeler.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
# Source available at https://github.com/actions/labeler/blob/main/README.md
20-
- uses: actions/labeler@9471598e3b7ff22b2fa181bd79addf94cb3e0847
20+
- uses: actions/labeler@6b107e7a7ee5e054e0bcce60de5181d21e2f00fb

bin/internal/engine.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1c775e34e2d57331c532b29a5925394c18939d6a
1+
d97037077963dac1f9b4355390f6ccb9e1adb56d
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
b9718302b30f9883d99d5662361231d0136d35a7
1+
5c6991400e91e1a9f66fb780e1ef3841023e652d

bin/internal/fuchsia-linux.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
D_EOM3rJ8AMk3-WexatyJMtC-gqcf7EEO6BThUEP6CQC
1+
SDKw1RvH0dWiJXERoXnf29rcKiqIgUsguKrlJ7CmvNoC

bin/internal/fuchsia-mac.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
N4LwCRxg0oIevhQ_OAtrHsdzFjvIzDp3XHf1VT-3N90C
1+
wNfsef5we4l8hxEIInAneq33eH-afSvrZ4qntHWghSAC

dev/benchmarks/macrobenchmarks/pubspec.yaml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ dependencies:
1818
# flutter update-packages --force-upgrade
1919
flutter_gallery_assets: 1.0.2
2020

21-
url_launcher: 6.1.11
22-
2321
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
2422
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
2523
characters: 1.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -40,13 +38,6 @@ dependencies:
4038
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
4139
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
4240
test_api: 0.5.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
43-
url_launcher_android: 6.0.17 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
44-
url_launcher_ios: 6.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
45-
url_launcher_linux: 3.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
46-
url_launcher_macos: 3.0.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
47-
url_launcher_platform_interface: 2.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
48-
url_launcher_web: 2.0.16 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
49-
url_launcher_windows: 3.0.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
5041
vector_math: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
5142
vm_service: 11.6.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
5243
webdriver: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -218,4 +209,4 @@ flutter:
218209
fonts:
219210
- asset: packages/flutter_gallery_assets/fonts/GalleryIcons.ttf
220211

221-
# PUBSPEC CHECKSUM: 5bbf
212+
# PUBSPEC CHECKSUM: 1586

dev/integration_tests/gradle_deprecated_settings/pubspec.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@ dependencies:
88
flutter:
99
sdk: flutter
1010
camera: 0.10.5
11-
# This is explicit to allow pinning for https://github.com/flutter/flutter/issues/126710
12-
camera_android: 0.10.7
1311
# This is explicit to allow pinning for https://github.com/flutter/flutter/issues/122039
1412
flutter_plugin_android_lifecycle: 2.0.8
1513

1614
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
1715
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
16+
camera_android: 0.10.8+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
1817
camera_avfoundation: 0.9.13+1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
1918
camera_platform_interface: 2.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
2019
camera_web: 0.3.1+3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -40,4 +39,4 @@ dependencies:
4039
flutter:
4140
uses-material-design: true
4241

43-
# PUBSPEC CHECKSUM: 9fbb
42+
# PUBSPEC CHECKSUM: 6b19
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
7+
/// Flutter code sample for [Autocomplete] that shows how to fetch the options
8+
/// from a remote API.
9+
10+
const Duration fakeAPIDuration = Duration(seconds: 1);
11+
12+
void main() => runApp(const AutocompleteExampleApp());
13+
14+
class AutocompleteExampleApp extends StatelessWidget {
15+
const AutocompleteExampleApp({super.key});
16+
17+
@override
18+
Widget build(BuildContext context) {
19+
return MaterialApp(
20+
home: Scaffold(
21+
appBar: AppBar(
22+
title: const Text('Autocomplete - async'),
23+
),
24+
body: const Center(
25+
child: _AsyncAutocomplete(),
26+
),
27+
),
28+
);
29+
}
30+
}
31+
32+
class _AsyncAutocomplete extends StatefulWidget {
33+
const _AsyncAutocomplete();
34+
35+
@override
36+
State<_AsyncAutocomplete > createState() => _AsyncAutocompleteState();
37+
}
38+
39+
class _AsyncAutocompleteState extends State<_AsyncAutocomplete > {
40+
// The query currently being searched for. If null, there is no pending
41+
// request.
42+
String? _searchingWithQuery;
43+
44+
// The most recent options received from the API.
45+
late Iterable<String> _lastOptions = <String>[];
46+
47+
@override
48+
Widget build(BuildContext context) {
49+
return Autocomplete<String>(
50+
optionsBuilder: (TextEditingValue textEditingValue) async {
51+
_searchingWithQuery = textEditingValue.text;
52+
final Iterable<String> options = await _FakeAPI.search(_searchingWithQuery!);
53+
54+
// If another search happened after this one, throw away these options.
55+
// Use the previous options intead and wait for the newer request to
56+
// finish.
57+
if (_searchingWithQuery != textEditingValue.text) {
58+
return _lastOptions;
59+
}
60+
61+
_lastOptions = options;
62+
return options;
63+
},
64+
onSelected: (String selection) {
65+
debugPrint('You just selected $selection');
66+
},
67+
);
68+
}
69+
}
70+
71+
// Mimics a remote API.
72+
class _FakeAPI {
73+
static const List<String> _kOptions = <String>[
74+
'aardvark',
75+
'bobcat',
76+
'chameleon',
77+
];
78+
79+
// Searches the options, but injects a fake "network" delay.
80+
static Future<Iterable<String>> search(String query) async {
81+
await Future<void>.delayed(fakeAPIDuration); // Fake 1 second delay.
82+
if (query == '') {
83+
return const Iterable<String>.empty();
84+
}
85+
return _kOptions.where((String option) {
86+
return option.contains(query.toLowerCase());
87+
});
88+
}
89+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package:flutter/material.dart';
8+
9+
/// Flutter code sample for [Autocomplete] that demonstrates fetching the
10+
/// options asynchronously and debouncing the network calls.
11+
12+
const Duration fakeAPIDuration = Duration(seconds: 1);
13+
const Duration debounceDuration = Duration(milliseconds: 500);
14+
15+
void main() => runApp(const AutocompleteExampleApp());
16+
17+
class AutocompleteExampleApp extends StatelessWidget {
18+
const AutocompleteExampleApp({super.key});
19+
20+
@override
21+
Widget build(BuildContext context) {
22+
return MaterialApp(
23+
home: Scaffold(
24+
appBar: AppBar(
25+
title: const Text('Autocomplete - async and debouncing'),
26+
),
27+
body: const Center(
28+
child: _AsyncAutocomplete(),
29+
),
30+
),
31+
);
32+
}
33+
}
34+
35+
class _AsyncAutocomplete extends StatefulWidget {
36+
const _AsyncAutocomplete();
37+
38+
@override
39+
State<_AsyncAutocomplete > createState() => _AsyncAutocompleteState();
40+
}
41+
42+
class _AsyncAutocompleteState extends State<_AsyncAutocomplete > {
43+
// The query currently being searched for. If null, there is no pending
44+
// request.
45+
String? _currentQuery;
46+
47+
// The most recent options received from the API.
48+
late Iterable<String> _lastOptions = <String>[];
49+
50+
late final _Debounceable<Iterable<String>?, String> _debouncedSearch;
51+
52+
// Calls the "remote" API to search with the given query. Returns null when
53+
// the call has been made obsolete.
54+
Future<Iterable<String>?> _search(String query) async {
55+
_currentQuery = query;
56+
57+
// In a real application, there should be some error handling here.
58+
final Iterable<String> options = await _FakeAPI.search(_currentQuery!);
59+
60+
// If another search happened after this one, throw away these options.
61+
if (_currentQuery != query) {
62+
_currentQuery = null;
63+
return null;
64+
}
65+
_currentQuery = null;
66+
67+
return options;
68+
}
69+
70+
@override
71+
void initState() {
72+
super.initState();
73+
_debouncedSearch = _debounce<Iterable<String>?, String>(_search);
74+
}
75+
76+
@override
77+
Widget build(BuildContext context) {
78+
return Autocomplete<String>(
79+
optionsBuilder: (TextEditingValue textEditingValue) async {
80+
final Iterable<String>? options = await _debouncedSearch(textEditingValue.text);
81+
if (options == null) {
82+
return _lastOptions;
83+
}
84+
_lastOptions = options;
85+
return options;
86+
},
87+
onSelected: (String selection) {
88+
debugPrint('You just selected $selection');
89+
},
90+
);
91+
}
92+
}
93+
94+
// Mimics a remote API.
95+
class _FakeAPI {
96+
static const List<String> _kOptions = <String>[
97+
'aardvark',
98+
'bobcat',
99+
'chameleon',
100+
];
101+
102+
// Searches the options, but injects a fake "network" delay.
103+
static Future<Iterable<String>> search(String query) async {
104+
await Future<void>.delayed(fakeAPIDuration); // Fake 1 second delay.
105+
if (query == '') {
106+
return const Iterable<String>.empty();
107+
}
108+
return _kOptions.where((String option) {
109+
return option.contains(query.toLowerCase());
110+
});
111+
}
112+
}
113+
114+
typedef _Debounceable<S, T> = Future<S?> Function(T parameter);
115+
116+
/// Returns a new function that is a debounced version of the given function.
117+
///
118+
/// This means that the original function will be called only after no calls
119+
/// have been made for the given Duration.
120+
_Debounceable<S, T> _debounce<S, T>(_Debounceable<S?, T> function) {
121+
_DebounceTimer? debounceTimer;
122+
123+
return (T parameter) async {
124+
if (debounceTimer != null && !debounceTimer!.isCompleted) {
125+
debounceTimer!.cancel();
126+
}
127+
debounceTimer = _DebounceTimer();
128+
try {
129+
await debounceTimer!.future;
130+
} catch (error) {
131+
if (error is _CancelException) {
132+
return null;
133+
}
134+
rethrow;
135+
}
136+
return function(parameter);
137+
};
138+
}
139+
140+
// A wrapper around Timer used for debouncing.
141+
class _DebounceTimer {
142+
_DebounceTimer(
143+
) {
144+
_timer = Timer(debounceDuration, _onComplete);
145+
}
146+
147+
late final Timer _timer;
148+
final Completer<void> _completer = Completer<void>();
149+
150+
void _onComplete() {
151+
_completer.complete();
152+
}
153+
154+
Future<void> get future => _completer.future;
155+
156+
bool get isCompleted => _completer.isCompleted;
157+
158+
void cancel() {
159+
_timer.cancel();
160+
_completer.completeError(const _CancelException());
161+
}
162+
}
163+
164+
// An exception indicating that the timer was canceled.
165+
class _CancelException implements Exception {
166+
const _CancelException();
167+
}

0 commit comments

Comments
 (0)