Skip to content

Commit

Permalink
[google_maps_flutter_android] Convert Circle and Marker to Pigeon (#7326
Browse files Browse the repository at this point in the history
)

Utilize static typing for pigeon message objects for Marker and Circle
in `google_maps_flutter_android`.

Draft for now to run tests.

[*List which issues are fixed by this PR. You must list at least one
issue.*](flutter/flutter#152925)

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] page, which explains my
responsibilities.
- [x] I read and followed the [relevant style guides] and ran the
auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages
repo does use `dart format`.)
- [ ] I signed the [CLA].
- [x] The title of the PR starts with the name of the package surrounded
by square brackets, e.g. `[shared_preferences]`
- [x] I [linked to at least one issue that this PR fixes] in the
description above.
- [ ] I updated `pubspec.yaml` with an appropriate new version according
to the [pub versioning philosophy], or this PR is [exempt from version
changes].
- [ ] I updated `CHANGELOG.md` to add a description of the change,
[following repository CHANGELOG style], or this PR is [exempt from
CHANGELOG changes].
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/packages/blob/main/CONTRIBUTING.md
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md
[relevant style guides]:
https://github.com/flutter/packages/blob/main/CONTRIBUTING.md#style
[CLA]: https://cla.developers.google.com/
[Discord]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md
[linked to at least one issue that this PR fixes]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#overview
[pub versioning philosophy]: https://dart.dev/tools/pub/versioning
[exempt from version changes]:
https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#version
[following repository CHANGELOG style]:
https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changelog-style
[exempt from CHANGELOG changes]:
https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changelog
[test-exempt]:
https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#tests

---------

Co-authored-by: Reid Baker <[email protected]>
  • Loading branch information
yaakovschectman and reidbaker authored Aug 13, 2024
1 parent f118119 commit cec00a5
Show file tree
Hide file tree
Showing 14 changed files with 1,574 additions and 493 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.14.1

* Converts `PlatformCircle` and `PlatformMarker` to pigeon.

## 2.14.0

* Updates map configuration and platform view creation parameters to use Pigeon.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ void setGoogleMap(GoogleMap googleMap) {

void addCircles(@NonNull List<Messages.PlatformCircle> circlesToAdd) {
for (Messages.PlatformCircle circleToAdd : circlesToAdd) {
addJsonCircle(circleToAdd.getJson());
addCircle(circleToAdd);
}
}

void changeCircles(@NonNull List<Messages.PlatformCircle> circlesToChange) {
for (Messages.PlatformCircle circleToChange : circlesToChange) {
changeJsonCircle(circleToChange.getJson());
changeCircle(circleToChange);
}
}

Expand All @@ -67,10 +67,7 @@ boolean onCircleTap(String googleCircleId) {
return false;
}

private void addJsonCircle(Map<String, ?> circle) {
if (circle == null) {
return;
}
void addCircle(@NonNull Messages.PlatformCircle circle) {
CircleBuilder circleBuilder = new CircleBuilder(density);
String circleId = Convert.interpretCircleOptions(circle, circleBuilder);
CircleOptions options = circleBuilder.build();
Expand All @@ -84,18 +81,11 @@ private void addCircle(String circleId, CircleOptions circleOptions, boolean con
googleMapsCircleIdToDartCircleId.put(circle.getId(), circleId);
}

private void changeJsonCircle(Map<String, ?> circle) {
if (circle == null) {
return;
}
String circleId = getCircleId(circle);
private void changeCircle(@NonNull Messages.PlatformCircle circle) {
String circleId = circle.getCircleId();
CircleController circleController = circleIdToController.get(circleId);
if (circleController != null) {
Convert.interpretCircleOptions(circle, circleController);
}
}

private static String getCircleId(Map<String, ?> circle) {
return (String) circle.get("circleId");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ class Convert {

private static BitmapDescriptor toBitmapDescriptor(
Object o, AssetManager assetManager, float density) {
return toBitmapDescriptor(o, assetManager, density, new BitmapDescriptorFactoryWrapper());
}

private static BitmapDescriptor toBitmapDescriptor(
Object o, AssetManager assetManager, float density, BitmapDescriptorFactoryWrapper wrapper) {
final List<?> data = toList(o);
final String descriptorType = toString(data.get(0));
switch (descriptorType) {
Expand Down Expand Up @@ -101,17 +106,13 @@ private static BitmapDescriptor toBitmapDescriptor(
}
final Map<?, ?> assetData = toMap(data.get(1));
return getBitmapFromAsset(
assetData,
assetManager,
density,
new BitmapDescriptorFactoryWrapper(),
new FlutterInjectorWrapper());
assetData, assetManager, density, wrapper, new FlutterInjectorWrapper());
case "bytes":
if (!(data.get(1) instanceof Map)) {
throw new IllegalArgumentException("'bytes' expected a map as the second parameter");
}
final Map<?, ?> byteData = toMap(data.get(1));
return getBitmapFromBytes(byteData, density, new BitmapDescriptorFactoryWrapper());
return getBitmapFromBytes(byteData, density, wrapper);
default:
throw new IllegalArgumentException("Cannot interpret " + o + " as BitmapDescriptor");
}
Expand Down Expand Up @@ -659,68 +660,34 @@ static void interpretMapConfiguration(

/** Set the options in the given object to marker options sink. */
static void interpretMarkerOptions(
Map<String, ?> data, MarkerOptionsSink sink, AssetManager assetManager, float density) {
final Object alpha = data.get("alpha");
if (alpha != null) {
sink.setAlpha(toFloat(alpha));
}
final Object anchor = data.get("anchor");
if (anchor != null) {
final List<?> anchorData = toList(anchor);
sink.setAnchor(toFloat(anchorData.get(0)), toFloat(anchorData.get(1)));
}
final Object consumeTapEvents = data.get("consumeTapEvents");
if (consumeTapEvents != null) {
sink.setConsumeTapEvents(toBoolean(consumeTapEvents));
}
final Object draggable = data.get("draggable");
if (draggable != null) {
sink.setDraggable(toBoolean(draggable));
}
final Object flat = data.get("flat");
if (flat != null) {
sink.setFlat(toBoolean(flat));
}
final Object icon = data.get("icon");
if (icon != null) {
sink.setIcon(toBitmapDescriptor(icon, assetManager, density));
}

final Object infoWindow = data.get("infoWindow");
if (infoWindow != null) {
interpretInfoWindowOptions(sink, toObjectMap(infoWindow));
}
final Object position = data.get("position");
if (position != null) {
sink.setPosition(toLatLng(position));
}
final Object rotation = data.get("rotation");
if (rotation != null) {
sink.setRotation(toFloat(rotation));
}
final Object visible = data.get("visible");
if (visible != null) {
sink.setVisible(toBoolean(visible));
}
final Object zIndex = data.get("zIndex");
if (zIndex != null) {
sink.setZIndex(toFloat(zIndex));
}
Messages.PlatformMarker marker,
MarkerOptionsSink sink,
AssetManager assetManager,
float density,
BitmapDescriptorFactoryWrapper wrapper) {
sink.setAlpha(marker.getAlpha().floatValue());
sink.setAnchor(
marker.getAnchor().getDx().floatValue(), marker.getAnchor().getDy().floatValue());
sink.setConsumeTapEvents(marker.getConsumeTapEvents());
sink.setDraggable(marker.getDraggable());
sink.setFlat(marker.getFlat());
sink.setIcon(toBitmapDescriptor(marker.getIcon(), assetManager, density, wrapper));
interpretInfoWindowOptions(sink, marker.getInfoWindow());
sink.setPosition(toLatLng(marker.getPosition().toList()));
sink.setRotation(marker.getRotation().floatValue());
sink.setVisible(marker.getVisible());
sink.setZIndex(marker.getZIndex().floatValue());
}

private static void interpretInfoWindowOptions(
MarkerOptionsSink sink, Map<String, Object> infoWindow) {
String title = (String) infoWindow.get("title");
String snippet = (String) infoWindow.get("snippet");
// snippet is nullable.
MarkerOptionsSink sink, Messages.PlatformInfoWindow infoWindow) {
String title = infoWindow.getTitle();
if (title != null) {
sink.setInfoWindowText(title, snippet);
}
Object infoWindowAnchor = infoWindow.get("anchor");
if (infoWindowAnchor != null) {
final List<?> anchorData = toList(infoWindowAnchor);
sink.setInfoWindowAnchor(toFloat(anchorData.get(0)), toFloat(anchorData.get(1)));
sink.setInfoWindowText(title, infoWindow.getSnippet());
}
Messages.PlatformOffset infoWindowAnchor = infoWindow.getAnchor();
sink.setInfoWindowAnchor(
infoWindowAnchor.getDx().floatValue(), infoWindowAnchor.getDy().floatValue());
}

static String interpretPolygonOptions(Map<String, ?> data, PolygonOptionsSink sink) {
Expand Down Expand Up @@ -822,45 +789,16 @@ static String interpretPolylineOptions(
}
}

static String interpretCircleOptions(Map<String, ?> data, CircleOptionsSink sink) {
final Object consumeTapEvents = data.get("consumeTapEvents");
if (consumeTapEvents != null) {
sink.setConsumeTapEvents(toBoolean(consumeTapEvents));
}
final Object fillColor = data.get("fillColor");
if (fillColor != null) {
sink.setFillColor(toInt(fillColor));
}
final Object strokeColor = data.get("strokeColor");
if (strokeColor != null) {
sink.setStrokeColor(toInt(strokeColor));
}
final Object visible = data.get("visible");
if (visible != null) {
sink.setVisible(toBoolean(visible));
}
final Object strokeWidth = data.get("strokeWidth");
if (strokeWidth != null) {
sink.setStrokeWidth(toInt(strokeWidth));
}
final Object zIndex = data.get("zIndex");
if (zIndex != null) {
sink.setZIndex(toFloat(zIndex));
}
final Object center = data.get("center");
if (center != null) {
sink.setCenter(toLatLng(center));
}
final Object radius = data.get("radius");
if (radius != null) {
sink.setRadius(toDouble(radius));
}
final String circleId = (String) data.get("circleId");
if (circleId == null) {
throw new IllegalArgumentException("circleId was null");
} else {
return circleId;
}
static String interpretCircleOptions(Messages.PlatformCircle circle, CircleOptionsSink sink) {
sink.setConsumeTapEvents(circle.getConsumeTapEvents());
sink.setFillColor(circle.getFillColor().intValue());
sink.setStrokeColor(circle.getStrokeColor().intValue());
sink.setStrokeWidth(circle.getStrokeWidth());
sink.setZIndex(circle.getZIndex().floatValue());
sink.setCenter(toLatLng(circle.getCenter().toList()));
sink.setRadius(circle.getRadius());
sink.setVisible(circle.getVisible());
return circle.getCircleId();
}

/**
Expand Down Expand Up @@ -1069,7 +1007,6 @@ static Tile tileFromPigeon(Messages.PlatformTile tile) {
return new Tile(tile.getWidth().intValue(), tile.getHeight().intValue(), tile.getData());
}

@VisibleForTesting
static class BitmapDescriptorFactoryWrapper {
/**
* Creates a BitmapDescriptor from the provided asset key using the {@link
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,12 @@ class GoogleMapController
this.lifecycleProvider = lifecycleProvider;
this.clusterManagersController = new ClusterManagersController(flutterApi, context);
this.markersController =
new MarkersController(flutterApi, clusterManagersController, assetManager, density);
new MarkersController(
flutterApi,
clusterManagersController,
assetManager,
density,
new Convert.BitmapDescriptorFactoryWrapper());
this.polygonsController = new PolygonsController(flutterApi, density);
this.polylinesController = new PolylinesController(flutterApi, assetManager, density);
this.circlesController = new CirclesController(flutterApi, density);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import io.flutter.plugins.googlemaps.Messages.MapsCallbackApi;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

class MarkersController {
Expand All @@ -25,19 +24,22 @@ class MarkersController {
private final ClusterManagersController clusterManagersController;
private final AssetManager assetManager;
private final float density;
private final Convert.BitmapDescriptorFactoryWrapper bitmapDescriptorFactoryWrapper;

MarkersController(
@NonNull MapsCallbackApi flutterApi,
ClusterManagersController clusterManagersController,
AssetManager assetManager,
float density) {
float density,
Convert.BitmapDescriptorFactoryWrapper bitmapDescriptorFactoryWrapper) {
this.markerIdToMarkerBuilder = new HashMap<>();
this.markerIdToController = new HashMap<>();
this.googleMapsMarkerIdToDartMarkerId = new HashMap<>();
this.flutterApi = flutterApi;
this.clusterManagersController = clusterManagersController;
this.assetManager = assetManager;
this.density = density;
this.bitmapDescriptorFactoryWrapper = bitmapDescriptorFactoryWrapper;
}

void setCollection(MarkerManager.Collection markerCollection) {
Expand All @@ -46,13 +48,13 @@ void setCollection(MarkerManager.Collection markerCollection) {

void addMarkers(@NonNull List<Messages.PlatformMarker> markersToAdd) {
for (Messages.PlatformMarker markerToAdd : markersToAdd) {
addJsonMarker(markerToAdd.getJson());
addMarker(markerToAdd);
}
}

void changeMarkers(@NonNull List<Messages.PlatformMarker> markersToChange) {
for (Messages.PlatformMarker markerToChange : markersToChange) {
changeJsonMarker(markerToChange.getJson());
changeMarker(markerToChange);
}
}

Expand Down Expand Up @@ -169,17 +171,12 @@ public void onClusterItemRendered(MarkerBuilder markerBuilder, Marker marker) {
}
}

private void addJsonMarker(Map<String, ?> marker) {
if (marker == null) {
return;
}
String markerId = getMarkerId(marker);
if (markerId == null) {
throw new IllegalArgumentException("markerId was null");
}
String clusterManagerId = getClusterManagerId(marker);
private void addMarker(@NonNull Messages.PlatformMarker marker) {
String markerId = marker.getMarkerId();
String clusterManagerId = marker.getClusterManagerId();
MarkerBuilder markerBuilder = new MarkerBuilder(markerId, clusterManagerId);
Convert.interpretMarkerOptions(marker, markerBuilder, assetManager, density);
Convert.interpretMarkerOptions(
marker, markerBuilder, assetManager, density, bitmapDescriptorFactoryWrapper);
addMarker(markerBuilder);
}

Expand Down Expand Up @@ -215,43 +212,34 @@ private void createControllerForMarker(String markerId, Marker marker, boolean c
googleMapsMarkerIdToDartMarkerId.put(marker.getId(), markerId);
}

private void changeJsonMarker(Map<String, ?> marker) {
if (marker == null) {
return;
}
String markerId = getMarkerId(marker);
private void changeMarker(@NonNull Messages.PlatformMarker marker) {
String markerId = marker.getMarkerId();

MarkerBuilder markerBuilder = markerIdToMarkerBuilder.get(markerId);
if (markerBuilder == null) {
return;
}

String clusterManagerId = getClusterManagerId(marker);
String clusterManagerId = marker.getClusterManagerId();
String oldClusterManagerId = markerBuilder.clusterManagerId();

// If the cluster ID on the updated marker has changed, the marker needs to
// be removed and re-added to update its cluster manager state.
if (!(Objects.equals(clusterManagerId, oldClusterManagerId))) {
removeMarker(markerId);
addJsonMarker(marker);
addMarker(marker);
return;
}

// Update marker builder.
Convert.interpretMarkerOptions(marker, markerBuilder, assetManager, density);
Convert.interpretMarkerOptions(
marker, markerBuilder, assetManager, density, bitmapDescriptorFactoryWrapper);

// Update existing marker on map.
MarkerController markerController = markerIdToController.get(markerId);
if (markerController != null) {
Convert.interpretMarkerOptions(marker, markerController, assetManager, density);
Convert.interpretMarkerOptions(
marker, markerController, assetManager, density, bitmapDescriptorFactoryWrapper);
}
}

private static String getMarkerId(Map<String, ?> marker) {
return (String) marker.get("markerId");
}

private static String getClusterManagerId(Map<String, ?> marker) {
return (String) marker.get("clusterManagerId");
}
}
Loading

0 comments on commit cec00a5

Please sign in to comment.