From ac48981f87c86f8804677910709d4a4987dc2251 Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 12:26:27 -0700 Subject: [PATCH 01/11] Clean up google_maps_flutter plugin: 1. A few minor formatting changes and additions of @Nullable annotations 2. Removed pass-through of activityHashCode. In the legacy plugin use case, the value is always -1 (which has been inlined). In the new plugin use case, the value should never be used because it uses DefaultLifecycleCallbacks instead of ActivityLifecycleCallbacks. 3. Replaced custom lifecycle state ints with androidx.lifecycle.Lifecycle.State enum. Also simplify paused/stopped states, which don't need their own dedicated states. Paused == started and stopped == created. 4. Fixed a bug where the Lifecycle object was being leaked onDetachFromActivity by nulling out the field. 5. Moved GoogleMapListener to its own file. Declaring multiple top level classes in the same file is bad practice. --- .../plugins/googlemaps/GoogleMapBuilder.java | 16 +- .../googlemaps/GoogleMapController.java | 499 ++++++++---------- .../plugins/googlemaps/GoogleMapFactory.java | 34 +- .../plugins/googlemaps/GoogleMapListener.java | 16 + .../plugins/googlemaps/GoogleMapsPlugin.java | 45 +- 5 files changed, 290 insertions(+), 320 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index 97af63c9f63b..5ac4c8494547 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -7,13 +7,14 @@ import android.app.Application; import android.content.Context; import android.graphics.Rect; +import androidx.annotation.Nullable; import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.Lifecycle.State; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLngBounds; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.PluginRegistry; -import java.util.concurrent.atomic.AtomicInteger; class GoogleMapBuilder implements GoogleMapOptionsSink { private final GoogleMapOptions options = new GoogleMapOptions(); @@ -32,24 +33,21 @@ class GoogleMapBuilder implements GoogleMapOptionsSink { GoogleMapController build( int id, Context context, - AtomicInteger state, + State lifecycleState, BinaryMessenger binaryMessenger, - Application application, - Lifecycle lifecycle, - PluginRegistry.Registrar registrar, - int activityHashCode) { + @Nullable Application application, + @Nullable Lifecycle lifecycle, + @Nullable PluginRegistry.Registrar registrar) { final GoogleMapController controller = new GoogleMapController( id, context, - state, binaryMessenger, application, lifecycle, registrar, - activityHashCode, options); - controller.init(); + controller.init(lifecycleState); controller.setMyLocationEnabled(myLocationEnabled); controller.setMyLocationButtonEnabled(myLocationButtonEnabled); controller.setIndoorEnabled(indoorEnabled); diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 58e8bb073bb7..3241e0c97557 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -4,13 +4,6 @@ package io.flutter.plugins.googlemaps; -import static io.flutter.plugins.googlemaps.GoogleMapsPlugin.CREATED; -import static io.flutter.plugins.googlemaps.GoogleMapsPlugin.DESTROYED; -import static io.flutter.plugins.googlemaps.GoogleMapsPlugin.PAUSED; -import static io.flutter.plugins.googlemaps.GoogleMapsPlugin.RESUMED; -import static io.flutter.plugins.googlemaps.GoogleMapsPlugin.STARTED; -import static io.flutter.plugins.googlemaps.GoogleMapsPlugin.STOPPED; - import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; @@ -26,6 +19,7 @@ import androidx.annotation.Nullable; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.Lifecycle.State; import androidx.lifecycle.LifecycleOwner; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.GoogleMap; @@ -53,22 +47,20 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; /** Controller of a single GoogleMaps MapView instance. */ final class GoogleMapController implements Application.ActivityLifecycleCallbacks, - DefaultLifecycleObserver, - ActivityPluginBinding.OnSaveInstanceStateListener, - GoogleMapOptionsSink, - MethodChannel.MethodCallHandler, - OnMapReadyCallback, - GoogleMapListener, - PlatformView { + DefaultLifecycleObserver, + ActivityPluginBinding.OnSaveInstanceStateListener, + GoogleMapOptionsSink, + MethodChannel.MethodCallHandler, + OnMapReadyCallback, + GoogleMapListener, + PlatformView { private static final String TAG = "GoogleMapController"; private final int id; - private final AtomicInteger activityState; private final MethodChannel methodChannel; private final GoogleMapOptions options; @Nullable private MapView mapView; @@ -83,13 +75,12 @@ final class GoogleMapController private boolean disposed = false; private final float density; private MethodChannel.Result mapReadyResult; - private final int - activityHashCode; // Do not use directly, use getActivityHashCode() instead to get correct hashCode for both v1 and v2 embedding. - private final Lifecycle lifecycle; + @Nullable private final Lifecycle lifecycle; private final Context context; - private final Application - mApplication; // Do not use direclty, use getApplication() instead to get correct application object for both v1 and v2 embedding. - private final PluginRegistry.Registrar registrar; // For v1 embedding only. + // Do not use directly, use getApplication() instead to get correct application object for both v1 + // and v2 embedding. + @Nullable private final Application mApplication; + @Nullable private final PluginRegistry.Registrar registrar; // For v1 embedding only. private final MarkersController markersController; private final PolygonsController polygonsController; private final PolylinesController polylinesController; @@ -102,16 +93,13 @@ final class GoogleMapController GoogleMapController( int id, Context context, - AtomicInteger activityState, BinaryMessenger binaryMessenger, - Application application, - Lifecycle lifecycle, - PluginRegistry.Registrar registrar, - int registrarActivityHashCode, + @Nullable Application application, + @Nullable Lifecycle lifecycle, + @Nullable PluginRegistry.Registrar registrar, GoogleMapOptions options) { this.id = id; this.context = context; - this.activityState = activityState; this.options = options; this.mapView = new MapView(context, options); this.density = context.getResources().getDisplayMetrics().density; @@ -120,7 +108,6 @@ final class GoogleMapController mApplication = application; this.lifecycle = lifecycle; this.registrar = registrar; - this.activityHashCode = registrarActivityHashCode; this.markersController = new MarkersController(methodChannel); this.polygonsController = new PolygonsController(methodChannel, density); this.polylinesController = new PolylinesController(methodChannel, density); @@ -132,21 +119,8 @@ public View getView() { return mapView; } - void init() { - switch (activityState.get()) { - case STOPPED: - mapView.onCreate(null); - mapView.onStart(); - mapView.onResume(); - mapView.onPause(); - mapView.onStop(); - break; - case PAUSED: - mapView.onCreate(null); - mapView.onStart(); - mapView.onResume(); - mapView.onPause(); - break; + void init(State lifecycleState) { + switch (lifecycleState) { case RESUMED: mapView.onCreate(null); mapView.onStart(); @@ -160,11 +134,9 @@ void init() { mapView.onCreate(null); break; case DESTROYED: - // Nothing to do, the activity has been completely destroyed. + case INITIALIZED: + // Nothing to do, the activity has been completely destroyed or not yet created. break; - default: - throw new IllegalArgumentException( - "Cannot interpret " + activityState.get() + " as an activity state"); } if (lifecycle != null) { lifecycle.addObserver(this); @@ -220,234 +192,234 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { mapReadyResult = result; break; case "map#update": - { - Convert.interpretGoogleMapOptions(call.argument("options"), this); - result.success(Convert.cameraPositionToJson(getCameraPosition())); - break; - } + { + Convert.interpretGoogleMapOptions(call.argument("options"), this); + result.success(Convert.cameraPositionToJson(getCameraPosition())); + break; + } case "map#getVisibleRegion": - { - if (googleMap != null) { - LatLngBounds latLngBounds = googleMap.getProjection().getVisibleRegion().latLngBounds; - result.success(Convert.latlngBoundsToJson(latLngBounds)); - } else { - result.error( - "GoogleMap uninitialized", - "getVisibleRegion called prior to map initialization", - null); - } - break; + { + if (googleMap != null) { + LatLngBounds latLngBounds = googleMap.getProjection().getVisibleRegion().latLngBounds; + result.success(Convert.latlngBoundsToJson(latLngBounds)); + } else { + result.error( + "GoogleMap uninitialized", + "getVisibleRegion called prior to map initialization", + null); } + break; + } case "map#getScreenCoordinate": - { - if (googleMap != null) { - LatLng latLng = Convert.toLatLng(call.arguments); - Point screenLocation = googleMap.getProjection().toScreenLocation(latLng); - result.success(Convert.pointToJson(screenLocation)); - } else { - result.error( - "GoogleMap uninitialized", - "getScreenCoordinate called prior to map initialization", - null); - } - break; + { + if (googleMap != null) { + LatLng latLng = Convert.toLatLng(call.arguments); + Point screenLocation = googleMap.getProjection().toScreenLocation(latLng); + result.success(Convert.pointToJson(screenLocation)); + } else { + result.error( + "GoogleMap uninitialized", + "getScreenCoordinate called prior to map initialization", + null); } + break; + } case "map#getLatLng": - { - if (googleMap != null) { - Point point = Convert.toPoint(call.arguments); - LatLng latLng = googleMap.getProjection().fromScreenLocation(point); - result.success(Convert.latLngToJson(latLng)); - } else { - result.error( - "GoogleMap uninitialized", "getLatLng called prior to map initialization", null); - } - break; + { + if (googleMap != null) { + Point point = Convert.toPoint(call.arguments); + LatLng latLng = googleMap.getProjection().fromScreenLocation(point); + result.success(Convert.latLngToJson(latLng)); + } else { + result.error( + "GoogleMap uninitialized", "getLatLng called prior to map initialization", null); } + break; + } case "map#takeSnapshot": - { - if (googleMap != null) { - final MethodChannel.Result _result = result; - googleMap.snapshot( - new SnapshotReadyCallback() { - @Override - public void onSnapshotReady(Bitmap bitmap) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); - byte[] byteArray = stream.toByteArray(); - bitmap.recycle(); - _result.success(byteArray); - } - }); - } else { - result.error("GoogleMap uninitialized", "takeSnapshot", null); - } - break; + { + if (googleMap != null) { + final MethodChannel.Result _result = result; + googleMap.snapshot( + new SnapshotReadyCallback() { + @Override + public void onSnapshotReady(Bitmap bitmap) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); + byte[] byteArray = stream.toByteArray(); + bitmap.recycle(); + _result.success(byteArray); + } + }); + } else { + result.error("GoogleMap uninitialized", "takeSnapshot", null); } + break; + } case "camera#move": - { - final CameraUpdate cameraUpdate = - Convert.toCameraUpdate(call.argument("cameraUpdate"), density); - moveCamera(cameraUpdate); - result.success(null); - break; - } + { + final CameraUpdate cameraUpdate = + Convert.toCameraUpdate(call.argument("cameraUpdate"), density); + moveCamera(cameraUpdate); + result.success(null); + break; + } case "camera#animate": - { - final CameraUpdate cameraUpdate = - Convert.toCameraUpdate(call.argument("cameraUpdate"), density); - animateCamera(cameraUpdate); - result.success(null); - break; - } + { + final CameraUpdate cameraUpdate = + Convert.toCameraUpdate(call.argument("cameraUpdate"), density); + animateCamera(cameraUpdate); + result.success(null); + break; + } case "markers#update": - { - Object markersToAdd = call.argument("markersToAdd"); - markersController.addMarkers((List) markersToAdd); - Object markersToChange = call.argument("markersToChange"); - markersController.changeMarkers((List) markersToChange); - Object markerIdsToRemove = call.argument("markerIdsToRemove"); - markersController.removeMarkers((List) markerIdsToRemove); - result.success(null); - break; - } + { + Object markersToAdd = call.argument("markersToAdd"); + markersController.addMarkers((List) markersToAdd); + Object markersToChange = call.argument("markersToChange"); + markersController.changeMarkers((List) markersToChange); + Object markerIdsToRemove = call.argument("markerIdsToRemove"); + markersController.removeMarkers((List) markerIdsToRemove); + result.success(null); + break; + } case "markers#showInfoWindow": - { - Object markerId = call.argument("markerId"); - markersController.showMarkerInfoWindow((String) markerId, result); - break; - } + { + Object markerId = call.argument("markerId"); + markersController.showMarkerInfoWindow((String) markerId, result); + break; + } case "markers#hideInfoWindow": - { - Object markerId = call.argument("markerId"); - markersController.hideMarkerInfoWindow((String) markerId, result); - break; - } + { + Object markerId = call.argument("markerId"); + markersController.hideMarkerInfoWindow((String) markerId, result); + break; + } case "markers#isInfoWindowShown": - { - Object markerId = call.argument("markerId"); - markersController.isInfoWindowShown((String) markerId, result); - break; - } + { + Object markerId = call.argument("markerId"); + markersController.isInfoWindowShown((String) markerId, result); + break; + } case "polygons#update": - { - Object polygonsToAdd = call.argument("polygonsToAdd"); - polygonsController.addPolygons((List) polygonsToAdd); - Object polygonsToChange = call.argument("polygonsToChange"); - polygonsController.changePolygons((List) polygonsToChange); - Object polygonIdsToRemove = call.argument("polygonIdsToRemove"); - polygonsController.removePolygons((List) polygonIdsToRemove); - result.success(null); - break; - } + { + Object polygonsToAdd = call.argument("polygonsToAdd"); + polygonsController.addPolygons((List) polygonsToAdd); + Object polygonsToChange = call.argument("polygonsToChange"); + polygonsController.changePolygons((List) polygonsToChange); + Object polygonIdsToRemove = call.argument("polygonIdsToRemove"); + polygonsController.removePolygons((List) polygonIdsToRemove); + result.success(null); + break; + } case "polylines#update": - { - Object polylinesToAdd = call.argument("polylinesToAdd"); - polylinesController.addPolylines((List) polylinesToAdd); - Object polylinesToChange = call.argument("polylinesToChange"); - polylinesController.changePolylines((List) polylinesToChange); - Object polylineIdsToRemove = call.argument("polylineIdsToRemove"); - polylinesController.removePolylines((List) polylineIdsToRemove); - result.success(null); - break; - } + { + Object polylinesToAdd = call.argument("polylinesToAdd"); + polylinesController.addPolylines((List) polylinesToAdd); + Object polylinesToChange = call.argument("polylinesToChange"); + polylinesController.changePolylines((List) polylinesToChange); + Object polylineIdsToRemove = call.argument("polylineIdsToRemove"); + polylinesController.removePolylines((List) polylineIdsToRemove); + result.success(null); + break; + } case "circles#update": - { - Object circlesToAdd = call.argument("circlesToAdd"); - circlesController.addCircles((List) circlesToAdd); - Object circlesToChange = call.argument("circlesToChange"); - circlesController.changeCircles((List) circlesToChange); - Object circleIdsToRemove = call.argument("circleIdsToRemove"); - circlesController.removeCircles((List) circleIdsToRemove); - result.success(null); - break; - } + { + Object circlesToAdd = call.argument("circlesToAdd"); + circlesController.addCircles((List) circlesToAdd); + Object circlesToChange = call.argument("circlesToChange"); + circlesController.changeCircles((List) circlesToChange); + Object circleIdsToRemove = call.argument("circleIdsToRemove"); + circlesController.removeCircles((List) circleIdsToRemove); + result.success(null); + break; + } case "map#isCompassEnabled": - { - result.success(googleMap.getUiSettings().isCompassEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isCompassEnabled()); + break; + } case "map#isMapToolbarEnabled": - { - result.success(googleMap.getUiSettings().isMapToolbarEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isMapToolbarEnabled()); + break; + } case "map#getMinMaxZoomLevels": - { - List zoomLevels = new ArrayList<>(2); - zoomLevels.add(googleMap.getMinZoomLevel()); - zoomLevels.add(googleMap.getMaxZoomLevel()); - result.success(zoomLevels); - break; - } + { + List zoomLevels = new ArrayList<>(2); + zoomLevels.add(googleMap.getMinZoomLevel()); + zoomLevels.add(googleMap.getMaxZoomLevel()); + result.success(zoomLevels); + break; + } case "map#isZoomGesturesEnabled": - { - result.success(googleMap.getUiSettings().isZoomGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isZoomGesturesEnabled()); + break; + } case "map#isLiteModeEnabled": - { - result.success(options.getLiteMode()); - break; - } + { + result.success(options.getLiteMode()); + break; + } case "map#isZoomControlsEnabled": - { - result.success(googleMap.getUiSettings().isZoomControlsEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isZoomControlsEnabled()); + break; + } case "map#isScrollGesturesEnabled": - { - result.success(googleMap.getUiSettings().isScrollGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isScrollGesturesEnabled()); + break; + } case "map#isTiltGesturesEnabled": - { - result.success(googleMap.getUiSettings().isTiltGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isTiltGesturesEnabled()); + break; + } case "map#isRotateGesturesEnabled": - { - result.success(googleMap.getUiSettings().isRotateGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isRotateGesturesEnabled()); + break; + } case "map#isMyLocationButtonEnabled": - { - result.success(googleMap.getUiSettings().isMyLocationButtonEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isMyLocationButtonEnabled()); + break; + } case "map#isTrafficEnabled": - { - result.success(googleMap.isTrafficEnabled()); - break; - } + { + result.success(googleMap.isTrafficEnabled()); + break; + } case "map#isBuildingsEnabled": - { - result.success(googleMap.isBuildingsEnabled()); - break; - } + { + result.success(googleMap.isBuildingsEnabled()); + break; + } case "map#getZoomLevel": - { - result.success(googleMap.getCameraPosition().zoom); - break; - } + { + result.success(googleMap.getCameraPosition().zoom); + break; + } case "map#setStyle": - { - String mapStyle = (String) call.arguments; - boolean mapStyleSet; - if (mapStyle == null) { - mapStyleSet = googleMap.setMapStyle(null); - } else { - mapStyleSet = googleMap.setMapStyle(new MapStyleOptions(mapStyle)); - } - ArrayList mapStyleResult = new ArrayList<>(2); - mapStyleResult.add(mapStyleSet); - if (!mapStyleSet) { - mapStyleResult.add( - "Unable to set the map style. Please check console logs for errors."); - } - result.success(mapStyleResult); - break; + { + String mapStyle = (String) call.arguments; + boolean mapStyleSet; + if (mapStyle == null) { + mapStyleSet = googleMap.setMapStyle(null); + } else { + mapStyleSet = googleMap.setMapStyle(new MapStyleOptions(mapStyle)); + } + ArrayList mapStyleResult = new ArrayList<>(2); + mapStyleResult.add(mapStyleSet); + if (!mapStyleSet) { + mapStyleResult.add( + "Unable to set the map style. Please check console logs for errors."); } + result.success(mapStyleResult); + break; + } default: result.notImplemented(); } @@ -552,18 +524,22 @@ private void setGoogleMapListener(@Nullable GoogleMapListener listener) { } // @Override - // The minimum supported version of Flutter doesn't have this method on the PlatformView interface, but the maximum - // does. This will override it when available even with the annotation commented out. + // The minimum supported version of Flutter doesn't have this method on the PlatformView + // interface, but the maximum does. This will override it when available even with the annotation + // commented out. public void onInputConnectionLocked() { - // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 is fixed in stable. - }; + // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 + // is fixed in stable. + } // @Override - // The minimum supported version of Flutter doesn't have this method on the PlatformView interface, but the maximum - // does. This will override it when available even with the annotation commented out. + // The minimum supported version of Flutter doesn't have this method on the PlatformView + // interface, but the maximum does. This will override it when available even with the annotation + // commented out. public void onInputConnectionUnlocked() { - // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 is fixed in stable. - }; + // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 + // is fixed in stable. + } // Application.ActivityLifecycleCallbacks methods @Override @@ -863,9 +839,9 @@ private void updateMyLocationSettings() { private boolean hasLocationPermission() { return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED + == PackageManager.PERMISSION_GRANTED || checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) - == PackageManager.PERMISSION_GRANTED; + == PackageManager.PERMISSION_GRANTED; } private int checkSelfPermission(String permission) { @@ -880,7 +856,7 @@ private int getActivityHashCode() { if (registrar != null && registrar.activity() != null) { return registrar.activity().hashCode(); } else { - return activityHashCode; + return -1; } } @@ -916,16 +892,3 @@ public void setBuildingsEnabled(boolean buildingsEnabled) { this.buildingsEnabled = buildingsEnabled; } } - -interface GoogleMapListener - extends GoogleMap.OnCameraIdleListener, - GoogleMap.OnCameraMoveListener, - GoogleMap.OnCameraMoveStartedListener, - GoogleMap.OnInfoWindowClickListener, - GoogleMap.OnMarkerClickListener, - GoogleMap.OnPolygonClickListener, - GoogleMap.OnPolylineClickListener, - GoogleMap.OnCircleClickListener, - GoogleMap.OnMapClickListener, - GoogleMap.OnMapLongClickListener, - GoogleMap.OnMarkerDragListener {} diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java index b6bc7e5d4c45..7d665d4e2377 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java @@ -6,7 +6,9 @@ import android.app.Application; import android.content.Context; +import androidx.annotation.Nullable; import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.Lifecycle.State; import com.google.android.gms.maps.model.CameraPosition; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.PluginRegistry; @@ -14,29 +16,26 @@ import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; public class GoogleMapFactory extends PlatformViewFactory { - private final AtomicInteger mActivityState; + private final AtomicReference lifecycleState; private final BinaryMessenger binaryMessenger; - private final Application application; - private final int activityHashCode; - private final Lifecycle lifecycle; - private final PluginRegistry.Registrar registrar; // V1 embedding only. + @Nullable private final Application application; + @Nullable private final Lifecycle lifecycle; + @Nullable private final PluginRegistry.Registrar registrar; // V1 embedding only. GoogleMapFactory( - AtomicInteger state, + AtomicReference lifecycleState, BinaryMessenger binaryMessenger, - Application application, - Lifecycle lifecycle, - PluginRegistry.Registrar registrar, - int activityHashCode) { + @Nullable Application application, + @Nullable Lifecycle lifecycle, + @Nullable PluginRegistry.Registrar registrar) { super(StandardMessageCodec.INSTANCE); - mActivityState = state; + this.lifecycleState = lifecycleState; this.binaryMessenger = binaryMessenger; this.application = application; - this.activityHashCode = activityHashCode; this.lifecycle = lifecycle; this.registrar = registrar; } @@ -65,13 +64,6 @@ public PlatformView create(Context context, int id, Object args) { builder.setInitialCircles(params.get("circlesToAdd")); } return builder.build( - id, - context, - mActivityState, - binaryMessenger, - application, - lifecycle, - registrar, - activityHashCode); + id, context, lifecycleState.get(), binaryMessenger, application, lifecycle, registrar); } } diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java new file mode 100644 index 000000000000..69dc5e30eb7b --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java @@ -0,0 +1,16 @@ +package io.flutter.plugins.googlemaps; + +import com.google.android.gms.maps.GoogleMap; + +interface GoogleMapListener + extends GoogleMap.OnCameraIdleListener, + GoogleMap.OnCameraMoveListener, + GoogleMap.OnCameraMoveStartedListener, + GoogleMap.OnInfoWindowClickListener, + GoogleMap.OnMarkerClickListener, + GoogleMap.OnPolygonClickListener, + GoogleMap.OnPolylineClickListener, + GoogleMap.OnCircleClickListener, + GoogleMap.OnMapClickListener, + GoogleMap.OnMapLongClickListener, + GoogleMap.OnMarkerDragListener {} diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java index f434a05bf1b7..0433b3e9f0e5 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java @@ -4,18 +4,25 @@ package io.flutter.plugins.googlemaps; +import static androidx.lifecycle.Lifecycle.State.CREATED; +import static androidx.lifecycle.Lifecycle.State.DESTROYED; +import static androidx.lifecycle.Lifecycle.State.INITIALIZED; +import static androidx.lifecycle.Lifecycle.State.RESUMED; +import static androidx.lifecycle.Lifecycle.State.STARTED; + import android.app.Activity; import android.app.Application; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.Lifecycle.State; import androidx.lifecycle.LifecycleOwner; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; /** * Plugin for controlling a set of GoogleMap views to be shown as overlays on top of the Flutter @@ -25,16 +32,10 @@ */ public class GoogleMapsPlugin implements Application.ActivityLifecycleCallbacks, - FlutterPlugin, - ActivityAware, - DefaultLifecycleObserver { - static final int CREATED = 1; - static final int STARTED = 2; - static final int RESUMED = 3; - static final int PAUSED = 4; - static final int STOPPED = 5; - static final int DESTROYED = 6; - private final AtomicInteger state = new AtomicInteger(0); + FlutterPlugin, + ActivityAware, + DefaultLifecycleObserver { + private final AtomicReference state = new AtomicReference<>(INITIALIZED); private int registrarActivityHashCode; private FlutterPluginBinding pluginBinding; private Lifecycle lifecycle; @@ -54,11 +55,15 @@ public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registra .platformViewRegistry() .registerViewFactory( VIEW_TYPE, - new GoogleMapFactory(plugin.state, registrar.messenger(), null, null, registrar, -1)); + new GoogleMapFactory(plugin.state, registrar.messenger(), null, null, registrar)); } public GoogleMapsPlugin() {} + private GoogleMapsPlugin(Activity activity) { + this.registrarActivityHashCode = activity.hashCode(); + } + // FlutterPlugin @Override @@ -86,13 +91,13 @@ public void onAttachedToActivity(ActivityPluginBinding binding) { pluginBinding.getBinaryMessenger(), binding.getActivity().getApplication(), lifecycle, - null, - binding.getActivity().hashCode())); + null)); } @Override public void onDetachedFromActivity() { lifecycle.removeObserver(this); + lifecycle = null; } @Override @@ -125,12 +130,12 @@ public void onResume(@NonNull LifecycleOwner owner) { @Override public void onPause(@NonNull LifecycleOwner owner) { - state.set(PAUSED); + state.set(STARTED); } @Override public void onStop(@NonNull LifecycleOwner owner) { - state.set(STOPPED); + state.set(CREATED); } @Override @@ -169,7 +174,7 @@ public void onActivityPaused(Activity activity) { if (activity.hashCode() != registrarActivityHashCode) { return; } - state.set(PAUSED); + state.set(STARTED); } @Override @@ -177,7 +182,7 @@ public void onActivityStopped(Activity activity) { if (activity.hashCode() != registrarActivityHashCode) { return; } - state.set(STOPPED); + state.set(CREATED); } @Override @@ -191,8 +196,4 @@ public void onActivityDestroyed(Activity activity) { activity.getApplication().unregisterActivityLifecycleCallbacks(this); state.set(DESTROYED); } - - private GoogleMapsPlugin(Activity activity) { - this.registrarActivityHashCode = activity.hashCode(); - } } From 50b200476d4d75f54dd433513a921082c9f21898 Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 12:41:14 -0700 Subject: [PATCH 02/11] Update version from 1.0.3 to 1.0.4 --- packages/google_maps_flutter/google_maps_flutter/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml index 5a9aae8fedef..1c6ba4a94871 100644 --- a/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter/pubspec.yaml @@ -1,7 +1,7 @@ name: google_maps_flutter description: A Flutter plugin for integrating Google Maps in iOS and Android applications. homepage: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter/google_maps_flutter -version: 1.0.3 +version: 1.0.4 dependencies: flutter: From af030dc139f3dae9ea0475bbda3551d0e385de54 Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 12:42:24 -0700 Subject: [PATCH 03/11] Update CHANGELOG.md --- packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 5135fdd6e2e2..2ce508fce0b1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.4 + +* Minor cleanup of Android code. + ## 1.0.3 * Update android compileSdkVersion to 29. From c1bf3970420a4a3d04f65a1883a0bf7a0b153f9e Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 12:55:27 -0700 Subject: [PATCH 04/11] Correct some tabbing --- .../googlemaps/GoogleMapController.java | 410 +++++++++--------- .../plugins/googlemaps/GoogleMapsPlugin.java | 6 +- 2 files changed, 208 insertions(+), 208 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 3241e0c97557..192bdf2d8620 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -51,13 +51,13 @@ /** Controller of a single GoogleMaps MapView instance. */ final class GoogleMapController implements Application.ActivityLifecycleCallbacks, - DefaultLifecycleObserver, - ActivityPluginBinding.OnSaveInstanceStateListener, - GoogleMapOptionsSink, - MethodChannel.MethodCallHandler, - OnMapReadyCallback, - GoogleMapListener, - PlatformView { + DefaultLifecycleObserver, + ActivityPluginBinding.OnSaveInstanceStateListener, + GoogleMapOptionsSink, + MethodChannel.MethodCallHandler, + OnMapReadyCallback, + GoogleMapListener, + PlatformView { private static final String TAG = "GoogleMapController"; private final int id; @@ -192,234 +192,234 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) { mapReadyResult = result; break; case "map#update": - { - Convert.interpretGoogleMapOptions(call.argument("options"), this); - result.success(Convert.cameraPositionToJson(getCameraPosition())); - break; - } + { + Convert.interpretGoogleMapOptions(call.argument("options"), this); + result.success(Convert.cameraPositionToJson(getCameraPosition())); + break; + } case "map#getVisibleRegion": - { - if (googleMap != null) { - LatLngBounds latLngBounds = googleMap.getProjection().getVisibleRegion().latLngBounds; - result.success(Convert.latlngBoundsToJson(latLngBounds)); - } else { - result.error( - "GoogleMap uninitialized", - "getVisibleRegion called prior to map initialization", - null); + { + if (googleMap != null) { + LatLngBounds latLngBounds = googleMap.getProjection().getVisibleRegion().latLngBounds; + result.success(Convert.latlngBoundsToJson(latLngBounds)); + } else { + result.error( + "GoogleMap uninitialized", + "getVisibleRegion called prior to map initialization", + null); + } + break; } - break; - } case "map#getScreenCoordinate": - { - if (googleMap != null) { - LatLng latLng = Convert.toLatLng(call.arguments); - Point screenLocation = googleMap.getProjection().toScreenLocation(latLng); - result.success(Convert.pointToJson(screenLocation)); - } else { - result.error( - "GoogleMap uninitialized", - "getScreenCoordinate called prior to map initialization", - null); + { + if (googleMap != null) { + LatLng latLng = Convert.toLatLng(call.arguments); + Point screenLocation = googleMap.getProjection().toScreenLocation(latLng); + result.success(Convert.pointToJson(screenLocation)); + } else { + result.error( + "GoogleMap uninitialized", + "getScreenCoordinate called prior to map initialization", + null); + } + break; } - break; - } case "map#getLatLng": - { - if (googleMap != null) { - Point point = Convert.toPoint(call.arguments); - LatLng latLng = googleMap.getProjection().fromScreenLocation(point); - result.success(Convert.latLngToJson(latLng)); - } else { - result.error( - "GoogleMap uninitialized", "getLatLng called prior to map initialization", null); + { + if (googleMap != null) { + Point point = Convert.toPoint(call.arguments); + LatLng latLng = googleMap.getProjection().fromScreenLocation(point); + result.success(Convert.latLngToJson(latLng)); + } else { + result.error( + "GoogleMap uninitialized", "getLatLng called prior to map initialization", null); + } + break; } - break; - } case "map#takeSnapshot": - { - if (googleMap != null) { - final MethodChannel.Result _result = result; - googleMap.snapshot( - new SnapshotReadyCallback() { - @Override - public void onSnapshotReady(Bitmap bitmap) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); - byte[] byteArray = stream.toByteArray(); - bitmap.recycle(); - _result.success(byteArray); - } - }); - } else { - result.error("GoogleMap uninitialized", "takeSnapshot", null); + { + if (googleMap != null) { + final MethodChannel.Result _result = result; + googleMap.snapshot( + new SnapshotReadyCallback() { + @Override + public void onSnapshotReady(Bitmap bitmap) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); + byte[] byteArray = stream.toByteArray(); + bitmap.recycle(); + _result.success(byteArray); + } + }); + } else { + result.error("GoogleMap uninitialized", "takeSnapshot", null); + } + break; } - break; - } case "camera#move": - { - final CameraUpdate cameraUpdate = - Convert.toCameraUpdate(call.argument("cameraUpdate"), density); - moveCamera(cameraUpdate); - result.success(null); - break; - } + { + final CameraUpdate cameraUpdate = + Convert.toCameraUpdate(call.argument("cameraUpdate"), density); + moveCamera(cameraUpdate); + result.success(null); + break; + } case "camera#animate": - { - final CameraUpdate cameraUpdate = - Convert.toCameraUpdate(call.argument("cameraUpdate"), density); - animateCamera(cameraUpdate); - result.success(null); - break; - } + { + final CameraUpdate cameraUpdate = + Convert.toCameraUpdate(call.argument("cameraUpdate"), density); + animateCamera(cameraUpdate); + result.success(null); + break; + } case "markers#update": - { - Object markersToAdd = call.argument("markersToAdd"); - markersController.addMarkers((List) markersToAdd); - Object markersToChange = call.argument("markersToChange"); - markersController.changeMarkers((List) markersToChange); - Object markerIdsToRemove = call.argument("markerIdsToRemove"); - markersController.removeMarkers((List) markerIdsToRemove); - result.success(null); - break; - } + { + Object markersToAdd = call.argument("markersToAdd"); + markersController.addMarkers((List) markersToAdd); + Object markersToChange = call.argument("markersToChange"); + markersController.changeMarkers((List) markersToChange); + Object markerIdsToRemove = call.argument("markerIdsToRemove"); + markersController.removeMarkers((List) markerIdsToRemove); + result.success(null); + break; + } case "markers#showInfoWindow": - { - Object markerId = call.argument("markerId"); - markersController.showMarkerInfoWindow((String) markerId, result); - break; - } + { + Object markerId = call.argument("markerId"); + markersController.showMarkerInfoWindow((String) markerId, result); + break; + } case "markers#hideInfoWindow": - { - Object markerId = call.argument("markerId"); - markersController.hideMarkerInfoWindow((String) markerId, result); - break; - } + { + Object markerId = call.argument("markerId"); + markersController.hideMarkerInfoWindow((String) markerId, result); + break; + } case "markers#isInfoWindowShown": - { - Object markerId = call.argument("markerId"); - markersController.isInfoWindowShown((String) markerId, result); - break; - } + { + Object markerId = call.argument("markerId"); + markersController.isInfoWindowShown((String) markerId, result); + break; + } case "polygons#update": - { - Object polygonsToAdd = call.argument("polygonsToAdd"); - polygonsController.addPolygons((List) polygonsToAdd); - Object polygonsToChange = call.argument("polygonsToChange"); - polygonsController.changePolygons((List) polygonsToChange); - Object polygonIdsToRemove = call.argument("polygonIdsToRemove"); - polygonsController.removePolygons((List) polygonIdsToRemove); - result.success(null); - break; - } + { + Object polygonsToAdd = call.argument("polygonsToAdd"); + polygonsController.addPolygons((List) polygonsToAdd); + Object polygonsToChange = call.argument("polygonsToChange"); + polygonsController.changePolygons((List) polygonsToChange); + Object polygonIdsToRemove = call.argument("polygonIdsToRemove"); + polygonsController.removePolygons((List) polygonIdsToRemove); + result.success(null); + break; + } case "polylines#update": - { - Object polylinesToAdd = call.argument("polylinesToAdd"); - polylinesController.addPolylines((List) polylinesToAdd); - Object polylinesToChange = call.argument("polylinesToChange"); - polylinesController.changePolylines((List) polylinesToChange); - Object polylineIdsToRemove = call.argument("polylineIdsToRemove"); - polylinesController.removePolylines((List) polylineIdsToRemove); - result.success(null); - break; - } + { + Object polylinesToAdd = call.argument("polylinesToAdd"); + polylinesController.addPolylines((List) polylinesToAdd); + Object polylinesToChange = call.argument("polylinesToChange"); + polylinesController.changePolylines((List) polylinesToChange); + Object polylineIdsToRemove = call.argument("polylineIdsToRemove"); + polylinesController.removePolylines((List) polylineIdsToRemove); + result.success(null); + break; + } case "circles#update": - { - Object circlesToAdd = call.argument("circlesToAdd"); - circlesController.addCircles((List) circlesToAdd); - Object circlesToChange = call.argument("circlesToChange"); - circlesController.changeCircles((List) circlesToChange); - Object circleIdsToRemove = call.argument("circleIdsToRemove"); - circlesController.removeCircles((List) circleIdsToRemove); - result.success(null); - break; - } + { + Object circlesToAdd = call.argument("circlesToAdd"); + circlesController.addCircles((List) circlesToAdd); + Object circlesToChange = call.argument("circlesToChange"); + circlesController.changeCircles((List) circlesToChange); + Object circleIdsToRemove = call.argument("circleIdsToRemove"); + circlesController.removeCircles((List) circleIdsToRemove); + result.success(null); + break; + } case "map#isCompassEnabled": - { - result.success(googleMap.getUiSettings().isCompassEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isCompassEnabled()); + break; + } case "map#isMapToolbarEnabled": - { - result.success(googleMap.getUiSettings().isMapToolbarEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isMapToolbarEnabled()); + break; + } case "map#getMinMaxZoomLevels": - { - List zoomLevels = new ArrayList<>(2); - zoomLevels.add(googleMap.getMinZoomLevel()); - zoomLevels.add(googleMap.getMaxZoomLevel()); - result.success(zoomLevels); - break; - } + { + List zoomLevels = new ArrayList<>(2); + zoomLevels.add(googleMap.getMinZoomLevel()); + zoomLevels.add(googleMap.getMaxZoomLevel()); + result.success(zoomLevels); + break; + } case "map#isZoomGesturesEnabled": - { - result.success(googleMap.getUiSettings().isZoomGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isZoomGesturesEnabled()); + break; + } case "map#isLiteModeEnabled": - { - result.success(options.getLiteMode()); - break; - } + { + result.success(options.getLiteMode()); + break; + } case "map#isZoomControlsEnabled": - { - result.success(googleMap.getUiSettings().isZoomControlsEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isZoomControlsEnabled()); + break; + } case "map#isScrollGesturesEnabled": - { - result.success(googleMap.getUiSettings().isScrollGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isScrollGesturesEnabled()); + break; + } case "map#isTiltGesturesEnabled": - { - result.success(googleMap.getUiSettings().isTiltGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isTiltGesturesEnabled()); + break; + } case "map#isRotateGesturesEnabled": - { - result.success(googleMap.getUiSettings().isRotateGesturesEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isRotateGesturesEnabled()); + break; + } case "map#isMyLocationButtonEnabled": - { - result.success(googleMap.getUiSettings().isMyLocationButtonEnabled()); - break; - } + { + result.success(googleMap.getUiSettings().isMyLocationButtonEnabled()); + break; + } case "map#isTrafficEnabled": - { - result.success(googleMap.isTrafficEnabled()); - break; - } + { + result.success(googleMap.isTrafficEnabled()); + break; + } case "map#isBuildingsEnabled": - { - result.success(googleMap.isBuildingsEnabled()); - break; - } + { + result.success(googleMap.isBuildingsEnabled()); + break; + } case "map#getZoomLevel": - { - result.success(googleMap.getCameraPosition().zoom); - break; - } - case "map#setStyle": - { - String mapStyle = (String) call.arguments; - boolean mapStyleSet; - if (mapStyle == null) { - mapStyleSet = googleMap.setMapStyle(null); - } else { - mapStyleSet = googleMap.setMapStyle(new MapStyleOptions(mapStyle)); + { + result.success(googleMap.getCameraPosition().zoom); + break; } - ArrayList mapStyleResult = new ArrayList<>(2); - mapStyleResult.add(mapStyleSet); - if (!mapStyleSet) { - mapStyleResult.add( - "Unable to set the map style. Please check console logs for errors."); + case "map#setStyle": + { + String mapStyle = (String) call.arguments; + boolean mapStyleSet; + if (mapStyle == null) { + mapStyleSet = googleMap.setMapStyle(null); + } else { + mapStyleSet = googleMap.setMapStyle(new MapStyleOptions(mapStyle)); + } + ArrayList mapStyleResult = new ArrayList<>(2); + mapStyleResult.add(mapStyleSet); + if (!mapStyleSet) { + mapStyleResult.add( + "Unable to set the map style. Please check console logs for errors."); + } + result.success(mapStyleResult); + break; } - result.success(mapStyleResult); - break; - } default: result.notImplemented(); } @@ -839,9 +839,9 @@ private void updateMyLocationSettings() { private boolean hasLocationPermission() { return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) - == PackageManager.PERMISSION_GRANTED + == PackageManager.PERMISSION_GRANTED || checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) - == PackageManager.PERMISSION_GRANTED; + == PackageManager.PERMISSION_GRANTED; } private int checkSelfPermission(String permission) { diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java index 0433b3e9f0e5..811ea97e4b80 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java @@ -32,9 +32,9 @@ */ public class GoogleMapsPlugin implements Application.ActivityLifecycleCallbacks, - FlutterPlugin, - ActivityAware, - DefaultLifecycleObserver { + FlutterPlugin, + ActivityAware, + DefaultLifecycleObserver { private final AtomicReference state = new AtomicReference<>(INITIALIZED); private int registrarActivityHashCode; private FlutterPluginBinding pluginBinding; From ddad09db240fa3b8531eb4889be1e2496122e847 Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 13:12:50 -0700 Subject: [PATCH 05/11] One more formatting fix --- .../io/flutter/plugins/googlemaps/GoogleMapBuilder.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index 5ac4c8494547..5b99da386a42 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -39,14 +39,7 @@ GoogleMapController build( @Nullable Lifecycle lifecycle, @Nullable PluginRegistry.Registrar registrar) { final GoogleMapController controller = - new GoogleMapController( - id, - context, - binaryMessenger, - application, - lifecycle, - registrar, - options); + new GoogleMapController(id, context, binaryMessenger, application, lifecycle, registrar, options); controller.init(lifecycleState); controller.setMyLocationEnabled(myLocationEnabled); controller.setMyLocationButtonEnabled(myLocationButtonEnabled); From 1d37fed5ba2a60ba63ce149c935d43153e3a7963 Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 13:23:17 -0700 Subject: [PATCH 06/11] Another more formatting fix --- .../java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java index 5b99da386a42..ca47be87f049 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapBuilder.java @@ -39,7 +39,8 @@ GoogleMapController build( @Nullable Lifecycle lifecycle, @Nullable PluginRegistry.Registrar registrar) { final GoogleMapController controller = - new GoogleMapController(id, context, binaryMessenger, application, lifecycle, registrar, options); + new GoogleMapController( + id, context, binaryMessenger, application, lifecycle, registrar, options); controller.init(lifecycleState); controller.setMyLocationEnabled(myLocationEnabled); controller.setMyLocationButtonEnabled(myLocationButtonEnabled); From a4b98b5f18b6108a51ce307b73e72fab9c24b6e2 Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 14:23:15 -0700 Subject: [PATCH 07/11] Update GoogleMapControllerTest to account for changes to constructor and init() methods. --- .../plugins/googlemaps/GoogleMapControllerTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java index 04b5f6fd3793..09f0c78da74a 100644 --- a/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java +++ b/packages/google_maps_flutter/google_maps_flutter/example/android/app/src/test/java/io/flutter/plugins/googlemaps/GoogleMapControllerTest.java @@ -5,11 +5,11 @@ import android.app.Application; import android.content.Context; +import androidx.lifecycle.Lifecycle.State; import androidx.lifecycle.LifecycleOwner; import androidx.test.core.app.ApplicationProvider; import com.google.android.gms.maps.GoogleMap; import io.flutter.plugin.common.BinaryMessenger; -import java.util.concurrent.atomic.AtomicInteger; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,9 +34,8 @@ public void before() { context = ApplicationProvider.getApplicationContext(); application = ApplicationProvider.getApplicationContext(); googleMapController = - new GoogleMapController( - 0, context, new AtomicInteger(1), mockMessenger, application, null, null, 0, null); - googleMapController.init(); + new GoogleMapController(0, context, mockMessenger, application, null, null, null); + googleMapController.init(State.CREATED); } @Test From 85d8220ce9a4ae24f765b60e95649967e205e019 Mon Sep 17 00:00:00 2001 From: math1man Date: Mon, 26 Oct 2020 16:31:12 -0700 Subject: [PATCH 08/11] Address comments: 1. Add license to GoogleMapListener.java 2. Revert some changes to comment linebreaking in GoogleMapController 3. In GoogleMapController#getActivityHashCode, throw an exception if the hash code cannot be obtained. --- .../googlemaps/GoogleMapController.java | 22 +++++++++---------- .../plugins/googlemaps/GoogleMapListener.java | 4 ++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 192bdf2d8620..59696d73eaf9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -524,21 +524,17 @@ private void setGoogleMapListener(@Nullable GoogleMapListener listener) { } // @Override - // The minimum supported version of Flutter doesn't have this method on the PlatformView - // interface, but the maximum does. This will override it when available even with the annotation - // commented out. + // The minimum supported version of Flutter doesn't have this method on the PlatformView interface, but the maximum + // does. This will override it when available even with the annotation commented out. public void onInputConnectionLocked() { - // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 - // is fixed in stable. + // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 is fixed in stable. } // @Override - // The minimum supported version of Flutter doesn't have this method on the PlatformView - // interface, but the maximum does. This will override it when available even with the annotation - // commented out. + // The minimum supported version of Flutter doesn't have this method on the PlatformView interface, but the maximum + // does. This will override it when available even with the annotation commented out. public void onInputConnectionUnlocked() { - // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 - // is fixed in stable. + // TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 is fixed in stable. } // Application.ActivityLifecycleCallbacks methods @@ -856,7 +852,11 @@ private int getActivityHashCode() { if (registrar != null && registrar.activity() != null) { return registrar.activity().hashCode(); } else { - return -1; + // This method should only be invoked in cases where registrar != null, and only at lifecycle + // times when registrar.activity() != null. If these constraints are violated, we should fail + // fast and loudly. + throw new NullPointerException( + "Tried to retrieve the activity hash code with null registrar or null activity"); } } diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java index 69dc5e30eb7b..518d45c4a9f6 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapListener.java @@ -1,3 +1,7 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + package io.flutter.plugins.googlemaps; import com.google.android.gms.maps.GoogleMap; From 440209e6805c2306e12986459b1747b0c140730e Mon Sep 17 00:00:00 2001 From: math1man Date: Tue, 27 Oct 2020 09:49:24 -0700 Subject: [PATCH 09/11] Add a lot more details to the CHANGELOG.md --- .../google_maps_flutter/google_maps_flutter/CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md index 2ce508fce0b1..afe8638e0fe1 100644 --- a/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter/CHANGELOG.md @@ -1,6 +1,11 @@ ## 1.0.4 -* Minor cleanup of Android code. +* Cleanup of Android code: +* A few minor formatting changes and additions of `@Nullable` annotations. +* Removed pass-through of `activityHashCode` to `GoogleMapController`. +* Replaced custom lifecycle state ints with `androidx.lifecycle.Lifecycle.State` enum. +* Fixed a bug where the Lifecycle object was being leaked `onDetachFromActivity`, by nulling out the field. +* Moved GoogleMapListener to its own file. Declaring multiple top level classes in the same file is discouraged. ## 1.0.3 From af6476d9f624a2fe0f6c83e5966592e65564ca1c Mon Sep 17 00:00:00 2001 From: math1man Date: Tue, 27 Oct 2020 10:16:45 -0700 Subject: [PATCH 10/11] Update gradle version to Flutter's recommended version 3.5.0 and add androidx.annotation gradle dependency. --- .../google_maps_flutter/android/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/android/build.gradle b/packages/google_maps_flutter/google_maps_flutter/android/build.gradle index f12e3f211131..a1d7da08a8d9 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/build.gradle +++ b/packages/google_maps_flutter/google_maps_flutter/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.3.2' + classpath 'com.android.tools.build:gradle:3.5.0' } } @@ -33,6 +33,7 @@ android { } dependencies { + implementation "androidx.annotation:annotation:1.1.0" implementation 'com.google.android.gms:play-services-maps:17.0.0' androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0' From a8ad9c1ae1a431af4604c8fcfef4b1e4473b42f6 Mon Sep 17 00:00:00 2001 From: math1man Date: Tue, 27 Oct 2020 11:21:11 -0700 Subject: [PATCH 11/11] Revert to return -1 from getActivityHashCode() if activity cannot be accessed. Updating this behavior will be tracked in https://github.com/flutter/flutter/issues/69128 --- .../flutter/plugins/googlemaps/GoogleMapController.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java index 59696d73eaf9..ea3322d4f3e8 100644 --- a/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java +++ b/packages/google_maps_flutter/google_maps_flutter/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapController.java @@ -852,11 +852,9 @@ private int getActivityHashCode() { if (registrar != null && registrar.activity() != null) { return registrar.activity().hashCode(); } else { - // This method should only be invoked in cases where registrar != null, and only at lifecycle - // times when registrar.activity() != null. If these constraints are violated, we should fail - // fast and loudly. - throw new NullPointerException( - "Tried to retrieve the activity hash code with null registrar or null activity"); + // TODO(cyanglaz): Remove `getActivityHashCode()` and use a cached hashCode when creating the view for V1 embedding. + // https://github.com/flutter/flutter/issues/69128 + return -1; } }