Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Convert initialization wait
  • Loading branch information
stuartmorgan-g committed Jun 21, 2024
commit d1c44c605467c795da010a99fa22e8abfb0404d0
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugins.googlemaps.Messages.MapsApi;
import io.flutter.plugins.googlemaps.Messages.MapsInspectorApi;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
Expand All @@ -67,6 +68,7 @@ class GoogleMapController
DefaultLifecycleObserver,
GoogleMapListener,
GoogleMapOptionsSink,
Messages.MapsApi,
MapsInspectorApi,
MethodChannel.MethodCallHandler,
OnMapReadyCallback,
Expand All @@ -88,7 +90,7 @@ class GoogleMapController
private boolean buildingsEnabled = true;
private boolean disposed = false;
@VisibleForTesting final float density;
private MethodChannel.Result mapReadyResult;
private @Nullable Messages.VoidResult mapReadyResult;
private final Context context;
private final LifecycleProvider lifecycleProvider;
private final MarkersController markersController;
Expand Down Expand Up @@ -125,6 +127,7 @@ class GoogleMapController
methodChannel =
new MethodChannel(binaryMessenger, "plugins.flutter.dev/google_maps_android_" + id);
methodChannel.setMethodCallHandler(this);
MapsApi.setUp(binaryMessenger, Integer.toString(id), this);
MapsInspectorApi.setUp(binaryMessenger, Integer.toString(id), this);
AssetManager assetManager = context.getAssets();
this.lifecycleProvider = lifecycleProvider;
Expand Down Expand Up @@ -203,7 +206,7 @@ public void onMapReady(@NonNull GoogleMap googleMap) {
this.googleMap.setBuildingsEnabled(this.buildingsEnabled);
installInvalidator();
if (mapReadyResult != null) {
mapReadyResult.success(null);
mapReadyResult.success();
mapReadyResult = null;
}
setGoogleMapListener(this);
Expand Down Expand Up @@ -308,13 +311,6 @@ public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {
@Override
public void onMethodCall(MethodCall call, @NonNull MethodChannel.Result result) {
switch (call.method) {
case "map#waitForMap":
if (googleMap != null) {
result.success(null);
return;
}
mapReadyResult = result;
break;
case "map#update":
{
Convert.interpretGoogleMapOptions(call.argument("options"), this);
Expand Down Expand Up @@ -602,6 +598,7 @@ public void dispose() {
}
disposed = true;
methodChannel.setMethodCallHandler(null);
MapsApi.setUp(binaryMessenger, Integer.toString(id), null);
MapsInspectorApi.setUp(binaryMessenger, Integer.toString(id), null);
setGoogleMapListener(null);
setMarkerCollectionListener(null);
Expand Down Expand Up @@ -1016,6 +1013,17 @@ private boolean updateMapStyle(String style) {
return set;
}

/** MapsApi implementation */
@Override
public void waitForMap(@NonNull Messages.VoidResult result) {
if (googleMap == null) {
mapReadyResult = result;
} else {
result.success();
}
}

/** MapsInspectorApi implementation */
@Override
public @NonNull Boolean areBuildingsEnabled() {
return googleMap.isBuildingsEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,87 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
}
}

/** Asynchronous error handling return type for non-nullable API method returns. */
public interface Result<T> {
/** Success case callback method for handling returns. */
void success(@NonNull T result);

/** Failure case callback method for handling errors. */
void error(@NonNull Throwable error);
}
/** Asynchronous error handling return type for nullable API method returns. */
public interface NullableResult<T> {
/** Success case callback method for handling returns. */
void success(@Nullable T result);

/** Failure case callback method for handling errors. */
void error(@NonNull Throwable error);
}
/** Asynchronous error handling return type for void API method returns. */
public interface VoidResult {
/** Success case callback method for handling returns. */
void success();

/** Failure case callback method for handling errors. */
void error(@NonNull Throwable error);
}
/**
* Interface for non-test interactions with the native SDK.
*
* <p>For test-only state queries, see [MapsInspectorApi].
*
* <p>Generated interface from Pigeon that represents a handler of messages from Flutter.
*/
public interface MapsApi {
/** Returns once the map instance is available. */
void waitForMap(@NonNull VoidResult result);

/** The codec used by MapsApi. */
static @NonNull MessageCodec<Object> getCodec() {
return PigeonCodec.INSTANCE;
}
/** Sets up an instance of `MapsApi` to handle messages through the `binaryMessenger`. */
static void setUp(@NonNull BinaryMessenger binaryMessenger, @Nullable MapsApi api) {
setUp(binaryMessenger, "", api);
}

static void setUp(
@NonNull BinaryMessenger binaryMessenger,
@NonNull String messageChannelSuffix,
@Nullable MapsApi api) {
messageChannelSuffix = messageChannelSuffix.isEmpty() ? "" : "." + messageChannelSuffix;
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger,
"dev.flutter.pigeon.google_maps_flutter_android.MapsApi.waitForMap"
+ messageChannelSuffix,
getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
VoidResult resultCallback =
new VoidResult() {
public void success() {
wrapped.add(0, null);
reply.reply(wrapped);
}

public void error(Throwable error) {
ArrayList<Object> wrappedError = wrapError(error);
reply.reply(wrappedError);
}
};

api.waitForMap(resultCallback);
});
} else {
channel.setMessageHandler(null);
}
}
}
}
/**
* Inspector API only intended for use in integration tests.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
// Every method call passes the int mapId
final Map<int, MethodChannel> _channels = <int, MethodChannel>{};

final Map<int, MapsApi> _hostMaps = <int, MapsApi>{};

/// Accesses the MethodChannel associated to the passed mapId.
MethodChannel _channel(int mapId) {
final MethodChannel? channel = _channels[mapId];
Expand All @@ -77,6 +79,15 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
return channel;
}

/// Accesses the MapsApi associated to the passed mapId.
MapsApi _hostApi(int mapId) {
final MapsApi? api = _hostMaps[mapId];
if (api == null) {
throw UnknownMapIDError(mapId);
}
return api;
}

// Keep a collection of mapId to a map of TileOverlays.
final Map<int, Map<TileOverlayId, TileOverlay>> _tileOverlays =
<int, Map<TileOverlayId, TileOverlay>>{};
Expand All @@ -94,10 +105,23 @@ class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
return channel;
}

/// Returns the API instance for [mapId], creating it if it doesn't already
/// exist.
@visibleForTesting
MapsApi ensureApiInitialized(int mapId) {
MapsApi? api = _hostMaps[mapId];
if (api == null) {
api = MapsApi(messageChannelSuffix: mapId.toString());
_hostMaps[mapId] = api;
}
return api;
}

@override
Future<void> init(int mapId) {
final MethodChannel channel = ensureChannelInitialized(mapId);
return channel.invokeMethod<void>('map#waitForMap');
ensureChannelInitialized(mapId);
final MapsApi hostApi = ensureApiInitialized(mapId);
return hostApi.waitForMap();
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,49 @@ class _PigeonCodec extends StandardMessageCodec {
}
}

/// Interface for non-test interactions with the native SDK.
///
/// For test-only state queries, see [MapsInspectorApi].
class MapsApi {
/// Constructor for [MapsApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
MapsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
: __pigeon_binaryMessenger = binaryMessenger,
__pigeon_messageChannelSuffix =
messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
final BinaryMessenger? __pigeon_binaryMessenger;

static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();

final String __pigeon_messageChannelSuffix;

/// Returns once the map instance is available.
Future<void> waitForMap() async {
final String __pigeon_channelName =
'dev.flutter.pigeon.google_maps_flutter_android.MapsApi.waitForMap$__pigeon_messageChannelSuffix';
final BasicMessageChannel<Object?> __pigeon_channel =
BasicMessageChannel<Object?>(
__pigeon_channelName,
pigeonChannelCodec,
binaryMessenger: __pigeon_binaryMessenger,
);
final List<Object?>? __pigeon_replyList =
await __pigeon_channel.send(null) as List<Object?>?;
if (__pigeon_replyList == null) {
throw _createConnectionError(__pigeon_channelName);
} else if (__pigeon_replyList.length > 1) {
throw PlatformException(
code: __pigeon_replyList[0]! as String,
message: __pigeon_replyList[1] as String?,
details: __pigeon_replyList[2],
);
} else {
return;
}
}
}

/// Inspector API only intended for use in integration tests.
class MapsInspectorApi {
/// Constructor for [MapsInspectorApi]. The [binaryMessenger] named argument is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ class PlatformZoomRange {
final double max;
}

/// Interface for non-test interactions with the native SDK.
///
/// For test-only state queries, see [MapsInspectorApi].
@HostApi()
abstract class MapsApi {
/// Returns once the map instance is available.
@async
void waitForMap();
}

/// Inspector API only intended for use in integration tests.
@HostApi()
abstract class MapsInspectorApi {
Expand Down