Skip to content

Commit 2218300

Browse files
authored
[google_maps_flutter] Started dispatching platform messages from platform thread (#6069)
Issue: flutter/flutter#135252 Testing: This adds no new functionality and thus should be covered in tests. The problem is that we are permissive to unsafe platform channel usage in the release flutter engine. We should maybe consider running tests against a debug version of the engine.
1 parent b21c542 commit 2218300

File tree

5 files changed

+73
-32
lines changed

5 files changed

+73
-32
lines changed

packages/google_maps_flutter/google_maps_flutter_ios/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.5.1
2+
3+
* Makes the tile overlay callback invoke the platform channel on the platform thread.
4+
15
## 2.5.0
26

37
* Adds support for `MapConfiguration.style`.

packages/google_maps_flutter/google_maps_flutter_ios/example/ios12/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
0DD7B6C32B744EEF00E857FD /* FLTTileProviderControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DD7B6C22B744EEF00E857FD /* FLTTileProviderControllerTests.m */; };
1011
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
1112
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
1213
4510D964F3B1259FEDD3ABA6 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7755F8F4BABC3D6A0BD4048B /* libPods-Runner.a */; };
@@ -54,6 +55,7 @@
5455
/* End PBXCopyFilesBuildPhase section */
5556

5657
/* Begin PBXFileReference section */
58+
0DD7B6C22B744EEF00E857FD /* FLTTileProviderControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FLTTileProviderControllerTests.m; sourceTree = "<group>"; };
5759
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
5860
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
5961
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
@@ -201,6 +203,7 @@
201203
982F2A6A27BADE17003C81F4 /* PartiallyMockedMapView.h */,
202204
982F2A6B27BADE17003C81F4 /* PartiallyMockedMapView.m */,
203205
F7151F14265D7ED70028CB91 /* Info.plist */,
206+
0DD7B6C22B744EEF00E857FD /* FLTTileProviderControllerTests.m */,
204207
);
205208
path = RunnerTests;
206209
sourceTree = "<group>";
@@ -460,6 +463,7 @@
460463
F7151F13265D7ED70028CB91 /* GoogleMapsTests.m in Sources */,
461464
6851F3562835BC180032B7C8 /* FLTGoogleMapJSONConversionsConversionTests.m in Sources */,
462465
982F2A6C27BADE17003C81F4 /* PartiallyMockedMapView.m in Sources */,
466+
0DD7B6C32B744EEF00E857FD /* FLTTileProviderControllerTests.m in Sources */,
463467
);
464468
runOnlyForDeploymentPostprocessing = 0;
465469
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2013 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 XCTest;
6+
@import GoogleMaps;
7+
@import google_maps_flutter_ios;
8+
9+
#import <OCMock/OCMock.h>
10+
11+
@interface FLTTileProviderControllerTests : XCTestCase
12+
@end
13+
14+
@implementation FLTTileProviderControllerTests
15+
16+
- (void)testCallChannelOnPlatformThread {
17+
id channel = OCMClassMock(FlutterMethodChannel.class);
18+
FLTTileProviderController *controller = [[FLTTileProviderController alloc] init:channel
19+
withTileOverlayIdentifier:@"foo"];
20+
XCTAssertNotNil(controller);
21+
XCTestExpectation *expectation = [self expectationWithDescription:@"invokeMethod"];
22+
OCMStub([channel invokeMethod:[OCMArg any] arguments:[OCMArg any] result:[OCMArg any]])
23+
.andDo(^(NSInvocation *invocation) {
24+
XCTAssertTrue([[NSThread currentThread] isMainThread]);
25+
[expectation fulfill];
26+
});
27+
id receiver = OCMProtocolMock(@protocol(GMSTileReceiver));
28+
[controller requestTileForX:0 y:0 zoom:0 receiver:receiver];
29+
[self waitForExpectations:@[ expectation ] timeout:10.0];
30+
}
31+
32+
@end

packages/google_maps_flutter/google_maps_flutter_ios/ios/Classes/FLTGoogleMapTileOverlayController.m

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -122,37 +122,38 @@ - (void)requestTileForX:(NSUInteger)x
122122
y:(NSUInteger)y
123123
zoom:(NSUInteger)zoom
124124
receiver:(id<GMSTileReceiver>)receiver {
125-
[self.methodChannel
126-
invokeMethod:@"tileOverlay#getTile"
127-
arguments:@{
128-
@"tileOverlayId" : self.tileOverlayIdentifier,
129-
@"x" : @(x),
130-
@"y" : @(y),
131-
@"zoom" : @(zoom)
132-
}
133-
result:^(id _Nullable result) {
134-
UIImage *tileImage;
135-
if ([result isKindOfClass:[NSDictionary class]]) {
136-
FlutterStandardTypedData *typedData = (FlutterStandardTypedData *)result[@"data"];
137-
if (typedData == nil) {
138-
tileImage = kGMSTileLayerNoTile;
139-
} else {
140-
tileImage = [UIImage imageWithData:typedData.data];
141-
}
142-
} else {
143-
if ([result isKindOfClass:[FlutterError class]]) {
144-
FlutterError *error = (FlutterError *)result;
145-
NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@",
146-
[error code], [error message], [error details]);
147-
}
148-
if ([result isKindOfClass:[FlutterMethodNotImplemented class]]) {
149-
NSLog(@"Can't get tile: notImplemented");
150-
}
151-
tileImage = kGMSTileLayerNoTile;
152-
}
153-
154-
[receiver receiveTileWithX:x y:y zoom:zoom image:tileImage];
155-
}];
125+
dispatch_async(dispatch_get_main_queue(), ^{
126+
[self.methodChannel invokeMethod:@"tileOverlay#getTile"
127+
arguments:@{
128+
@"tileOverlayId" : self.tileOverlayIdentifier,
129+
@"x" : @(x),
130+
@"y" : @(y),
131+
@"zoom" : @(zoom)
132+
}
133+
result:^(id _Nullable result) {
134+
UIImage *tileImage;
135+
if ([result isKindOfClass:[NSDictionary class]]) {
136+
FlutterStandardTypedData *typedData = (FlutterStandardTypedData *)result[@"data"];
137+
if (typedData == nil) {
138+
tileImage = kGMSTileLayerNoTile;
139+
} else {
140+
tileImage = [UIImage imageWithData:typedData.data];
141+
}
142+
} else {
143+
if ([result isKindOfClass:[FlutterError class]]) {
144+
FlutterError *error = (FlutterError *)result;
145+
NSLog(@"Can't get tile: errorCode = %@, errorMessage = %@, details = %@",
146+
[error code], [error message], [error details]);
147+
}
148+
if ([result isKindOfClass:[FlutterMethodNotImplemented class]]) {
149+
NSLog(@"Can't get tile: notImplemented");
150+
}
151+
tileImage = kGMSTileLayerNoTile;
152+
}
153+
154+
[receiver receiveTileWithX:x y:y zoom:zoom image:tileImage];
155+
}];
156+
});
156157
}
157158

158159
@end

packages/google_maps_flutter/google_maps_flutter_ios/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: google_maps_flutter_ios
22
description: iOS implementation of the google_maps_flutter plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_ios
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
5-
version: 2.5.0
5+
version: 2.5.1
66

77
environment:
88
sdk: ^3.2.3

0 commit comments

Comments
 (0)