Skip to content

Commit d547723

Browse files
authored
Merge branch 'main' into dimi/upgrade-analyzer
2 parents 6779331 + 5cae9ca commit d547723

File tree

57 files changed

+1281
-1785
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1281
-1785
lines changed

.ci/flutter_master.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6f8abdd77820aeb15bca424dd53ad0bf9ef222aa
1+
027f2e410241400eab2cd88dd08b2b3d9af83136

packages/espresso/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.4.0+18
2+
3+
* Bumps `com.squareup.okhttp3:okhttp` from 5.1.0 to 5.3.0.
4+
15
## 0.4.0+17
26

37
* Resolves Gradle 9 deprecations.

packages/espresso/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ android {
5858

5959
dependencies {
6060
implementation 'com.google.guava:guava:33.5.0-android'
61-
implementation 'com.squareup.okhttp3:okhttp:5.1.0'
61+
implementation 'com.squareup.okhttp3:okhttp:5.3.0'
6262
implementation 'com.google.code.gson:gson:2.13.2'
6363
androidTestImplementation 'org.hamcrest:hamcrest:3.0'
6464

packages/espresso/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Java classes for testing Flutter apps using Espresso.
33
Allows driving Flutter widgets from a native Espresso test.
44
repository: https://github.com/flutter/packages/tree/main/packages/espresso
55
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+espresso%22
6-
version: 0.4.0+17
6+
version: 0.4.0+18
77

88
environment:
99
sdk: ^3.9.0

packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.14.0
2+
3+
* Adds a check that raises a `StateError`
4+
when map controller is used after its widget has been disposed.
5+
16
## 2.13.1
27

38
* Fixes exception when dispose is called while asynchronous update from

packages/google_maps_flutter/google_maps_flutter/lib/src/controller.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class GoogleMapController {
264264
/// in-memory cache of tiles. If you want to cache tiles for longer, you
265265
/// should implement an on-disk cache.
266266
Future<void> clearTileCache(TileOverlayId tileOverlayId) async {
267+
_checkWidgetMountedOrThrow();
267268
return GoogleMapsFlutterPlatform.instance.clearTileCache(
268269
tileOverlayId,
269270
mapId: mapId,
@@ -278,6 +279,7 @@ class GoogleMapController {
278279
/// The returned [Future] completes after the change has been started on the
279280
/// platform side.
280281
Future<void> animateCamera(CameraUpdate cameraUpdate, {Duration? duration}) {
282+
_checkWidgetMountedOrThrow();
281283
return GoogleMapsFlutterPlatform.instance.animateCameraWithConfiguration(
282284
cameraUpdate,
283285
CameraUpdateAnimationConfiguration(duration: duration),
@@ -290,6 +292,7 @@ class GoogleMapController {
290292
/// The returned [Future] completes after the change has been made on the
291293
/// platform side.
292294
Future<void> moveCamera(CameraUpdate cameraUpdate) {
295+
_checkWidgetMountedOrThrow();
293296
return GoogleMapsFlutterPlatform.instance.moveCamera(
294297
cameraUpdate,
295298
mapId: mapId,
@@ -311,6 +314,7 @@ class GoogleMapController {
311314
/// style reference for more information regarding the supported styles.
312315
@Deprecated('Use GoogleMap.style instead.')
313316
Future<void> setMapStyle(String? mapStyle) {
317+
_checkWidgetMountedOrThrow();
314318
return GoogleMapsFlutterPlatform.instance.setMapStyle(
315319
mapStyle,
316320
mapId: mapId,
@@ -319,11 +323,13 @@ class GoogleMapController {
319323

320324
/// Returns the last style error, if any.
321325
Future<String?> getStyleError() {
326+
_checkWidgetMountedOrThrow();
322327
return GoogleMapsFlutterPlatform.instance.getStyleError(mapId: mapId);
323328
}
324329

325330
/// Return [LatLngBounds] defining the region that is visible in a map.
326331
Future<LatLngBounds> getVisibleRegion() {
332+
_checkWidgetMountedOrThrow();
327333
return GoogleMapsFlutterPlatform.instance.getVisibleRegion(mapId: mapId);
328334
}
329335

@@ -333,6 +339,7 @@ class GoogleMapController {
333339
/// Screen location is in screen pixels (not display pixels) with respect to the top left corner
334340
/// of the map, not necessarily of the whole screen.
335341
Future<ScreenCoordinate> getScreenCoordinate(LatLng latLng) {
342+
_checkWidgetMountedOrThrow();
336343
return GoogleMapsFlutterPlatform.instance.getScreenCoordinate(
337344
latLng,
338345
mapId: mapId,
@@ -344,6 +351,7 @@ class GoogleMapController {
344351
/// Returned [LatLng] corresponds to a screen location. The screen location is specified in screen
345352
/// pixels (not display pixels) relative to the top left of the map, not top left of the whole screen.
346353
Future<LatLng> getLatLng(ScreenCoordinate screenCoordinate) {
354+
_checkWidgetMountedOrThrow();
347355
return GoogleMapsFlutterPlatform.instance.getLatLng(
348356
screenCoordinate,
349357
mapId: mapId,
@@ -359,6 +367,7 @@ class GoogleMapController {
359367
/// * [hideMarkerInfoWindow] to hide the Info Window.
360368
/// * [isMarkerInfoWindowShown] to check if the Info Window is showing.
361369
Future<void> showMarkerInfoWindow(MarkerId markerId) {
370+
_checkWidgetMountedOrThrow();
362371
return GoogleMapsFlutterPlatform.instance.showMarkerInfoWindow(
363372
markerId,
364373
mapId: mapId,
@@ -374,6 +383,7 @@ class GoogleMapController {
374383
/// * [showMarkerInfoWindow] to show the Info Window.
375384
/// * [isMarkerInfoWindowShown] to check if the Info Window is showing.
376385
Future<void> hideMarkerInfoWindow(MarkerId markerId) {
386+
_checkWidgetMountedOrThrow();
377387
return GoogleMapsFlutterPlatform.instance.hideMarkerInfoWindow(
378388
markerId,
379389
mapId: mapId,
@@ -389,6 +399,7 @@ class GoogleMapController {
389399
/// * [showMarkerInfoWindow] to show the Info Window.
390400
/// * [hideMarkerInfoWindow] to hide the Info Window.
391401
Future<bool> isMarkerInfoWindowShown(MarkerId markerId) {
402+
_checkWidgetMountedOrThrow();
392403
return GoogleMapsFlutterPlatform.instance.isMarkerInfoWindowShown(
393404
markerId,
394405
mapId: mapId,
@@ -397,11 +408,13 @@ class GoogleMapController {
397408

398409
/// Returns the current zoom level of the map
399410
Future<double> getZoomLevel() {
411+
_checkWidgetMountedOrThrow();
400412
return GoogleMapsFlutterPlatform.instance.getZoomLevel(mapId: mapId);
401413
}
402414

403415
/// Returns the image bytes of the map
404416
Future<Uint8List?> takeSnapshot() {
417+
_checkWidgetMountedOrThrow();
405418
return GoogleMapsFlutterPlatform.instance.takeSnapshot(mapId: mapId);
406419
}
407420

@@ -414,4 +427,21 @@ class GoogleMapController {
414427
_streamSubscriptions.clear();
415428
GoogleMapsFlutterPlatform.instance.dispose(mapId: mapId);
416429
}
430+
431+
/// It is relatively easy to mistakenly call a method on the controller
432+
/// after the [GoogleMap] widget has already been disposed.
433+
/// Historically, this led to Platform-side errors such as
434+
/// `MissingPluginException` or `Unable to establish connection on channel`
435+
/// errors.
436+
///
437+
/// To facilitate debugging, this guard function
438+
/// raises a use-after-disposed [StateError].
439+
void _checkWidgetMountedOrThrow() {
440+
if (!_googleMapState.mounted) {
441+
throw StateError(
442+
'GoogleMapController for map ID $mapId was used after '
443+
'the associated GoogleMap widget had already been disposed.',
444+
);
445+
}
446+
}
417447
}

packages/google_maps_flutter/google_maps_flutter/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: google_maps_flutter
22
description: A Flutter plugin for integrating Google Maps in iOS and Android applications.
33
repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
5-
version: 2.13.1
5+
version: 2.14.0
66

77
environment:
88
sdk: ^3.7.0
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2013 The Flutter Authors
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/widgets.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
import 'package:google_maps_flutter/google_maps_flutter.dart';
8+
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
9+
10+
import 'fake_google_maps_flutter_platform.dart';
11+
12+
void main() {
13+
late FakeGoogleMapsFlutterPlatform platform;
14+
15+
setUp(() {
16+
platform = FakeGoogleMapsFlutterPlatform();
17+
GoogleMapsFlutterPlatform.instance = platform;
18+
});
19+
20+
testWidgets('onMapCreated is called with controller', (
21+
WidgetTester tester,
22+
) async {
23+
GoogleMapController? controller;
24+
25+
await tester.pumpWidget(
26+
Directionality(
27+
textDirection: TextDirection.ltr,
28+
child: GoogleMap(
29+
initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)),
30+
onMapCreated: (GoogleMapController value) => controller = value,
31+
),
32+
),
33+
);
34+
35+
expect(controller, isNotNull);
36+
await expectLater(controller?.getZoomLevel(), isNotNull);
37+
});
38+
39+
testWidgets('controller throws when used after dispose', (
40+
WidgetTester tester,
41+
) async {
42+
GoogleMapController? controller;
43+
44+
await tester.pumpWidget(
45+
Directionality(
46+
textDirection: TextDirection.ltr,
47+
child: GoogleMap(
48+
initialCameraPosition: const CameraPosition(target: LatLng(0.0, 0.0)),
49+
onMapCreated: (GoogleMapController value) => controller = value,
50+
),
51+
),
52+
);
53+
54+
// Now dispose of the map...
55+
await tester.pumpWidget(Container());
56+
57+
await expectLater(
58+
() => controller?.getZoomLevel(),
59+
throwsA(isA<StateError>()),
60+
);
61+
});
62+
}

packages/google_sign_in/google_sign_in_ios/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 6.2.3
2+
3+
* Internal restructuring to improve testability.
4+
15
## 6.2.2
26

37
* Updates minimum supported version to iOS 13.

0 commit comments

Comments
 (0)