Skip to content

[google_maps_flutter] Issue165999 - add onActiveLevelChanged callback to GoogleMap #8923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

ChopinDavid
Copy link
Contributor

@ChopinDavid ChopinDavid commented Mar 28, 2025

This PR would introduce a listener on GoogleMap that notifies anytime the active floor changes on a building when the GoogleMap is indoorViewEnabled. This includes handling a null level when a building is unfocused.

floorSelectionDemo-ezgif com-video-to-gif-converter

Sample code:

String? _selectedFloor;

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_selectedFloor != null
            ? 'Selected floor: $_selectedFloor'
            : 'No floor selected'),
      ),
      body: GoogleMap(
        onActiveLevelChanged: (selectedLevel) {
          setState(() {
            _selectedFloor = selectedLevel?.shortName;
          });
        },
      ),
    );
  }

This would fix #165999

Pre-Review Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene page, which explains my responsibilities.
  • 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.
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • 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 I have commented below to indicate which version change exemption this PR falls under1.
  • I updated CHANGELOG.md to add a description of the change, following repository CHANGELOG style, or I have commented below to indicate which CHANGELOG exemption this PR falls under1.
  • I updated/added any relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or I have commented below to indicate which test exemption this PR falls under1.
  • All existing and new tests are passing.

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

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2 3

@ChopinDavid
Copy link
Contributor Author

I still need to update CHANGELOG, update versions, write new and run existing tests, but wanted to get some eyes on this. Will probably try to do some of the outstanding tasks over this weekend.

I am also curious whether adding this to google_maps_flutter_web would be required for the PR to be merged. I've not worked with flutter web before, but could give it a shot.

@ChopinDavid ChopinDavid force-pushed the Issue165999 branch 4 times, most recently from 96babe0 to 7f32eeb Compare March 28, 2025 13:32
@stuartmorgan-g
Copy link
Contributor

Thanks for the contribution! I did an initial skim of the app-facing and platform interface package changes, and the structure all looks good.

I am also curious whether adding this to google_maps_flutter_web would be required for the PR to be merged.

No, this would be fine to land without web support, and that be left as a follow-up issue for someone else to implement. It's clear that web wouldn't change the core design of this API (which is the main potential concern, per our policy), and having the callback not fire on web wouldn't be fundamentally confusing in the same way that, say, a significant new API throwing UnsupportedError on web could be.

git:
url: git@github.com:ChopinDavid/flutter_packages.git
ref: Issue165999
path: packages/google_maps_flutter/google_maps_flutter_platform_interface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use our tooling for multi-package changes, as our CI will recognize it and adjust some checks accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was one of the changes I was going to make this weekend. Due to the structure of the packages, and the way they all depend on eachother, we had to sort of use these git references for some dependencies to get things building.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the structure of the packages, and the way they all depend on eachother, we had to sort of use these git references for some dependencies to get things building.

That's exactly what make-deps-path-based is designed for, but without using git references.

@ChopinDavid
Copy link
Contributor Author

@stuartmorgan I also noticed that there were a lot of changes in packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/Messages.java that were introduced by my running of google-java-format. Is it the case that this file just wasn't properly formatted in previous PRs, or does it seem I used this formatter incorrectly?

I basically ran

brew install google-java-format
find . -name "*.java" | xargs google-java-format -I

@stuartmorgan-g
Copy link
Contributor

Is it the case that this file just wasn't properly formatted in previous PRs

Our CI enforces (with a few rare exceptions) autoformatting; what is checked in is by definition correct, since otherwise the PR wouldn't have passed CI.

I basically ran

brew install google-java-format
find . -name "*.java" | xargs google-java-format -I

You should run the repo tooling format command, which ensures that the correct Java formatter is installed, and calls it with the correct arguments.

@ChopinDavid
Copy link
Contributor Author

@stuartmorgan-g I think this PR is in a pretty good place now, but please let me know. I noticed in the contributing README that "changes that span multiple packages will need to be done in multiple PRs", so should this PR be closed and should individual PRs be made for each of the 4 changed packages?

@stuartmorgan-g
Copy link
Contributor

I noticed in the contributing README that "changes that span multiple packages will need to be done in multiple PRs", so should this PR be closed and should individual PRs be made for each of the 4 changed packages?

The PR needs to follow the step by step process that is described in the paragraph right after the sentence you quoted. Step 1 hasn't been completed yet, which is why this is failing all the CI checks.

@ChopinDavid ChopinDavid requested a review from ditman as a code owner April 1, 2025 00:48
@ChopinDavid ChopinDavid force-pushed the Issue165999 branch 2 times, most recently from c778e30 to d4dbf52 Compare April 1, 2025 01:46
@ChopinDavid ChopinDavid force-pushed the Issue165999 branch 2 times, most recently from 77c8523 to fe385e3 Compare April 1, 2025 02:29
@ChopinDavid
Copy link
Contributor Author

It sounds like this PR isn't responsible for ensuring the tree-status check passes, does that track?

@stuartmorgan-g
Copy link
Contributor

It sounds like this PR isn't responsible for ensuring the tree-status check passes, does that track?

Yes, that's correct. tree-status is a live check tracking the state of the tree (currently red due to some frequently-occurring flake we're working on).

@ChopinDavid
Copy link
Contributor Author

@stuartmorgan-g cool, in that case I believe this story is ready for review once the tree status is addressed. Please let me know if that is incorrect.

@stuartmorgan-g stuartmorgan-g removed the request for review from ditman April 17, 2025 17:36
@stuartmorgan-g stuartmorgan-g added triage-ios Should be looked at in iOS triage triage-android Should be looked at in Android triage labels Apr 17, 2025
Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any testing of the actual implementations, only the Dart passthroughs. The native code should have native unit tests, and if possible (it looks like both the Android and iOS SDKs have a way of programmatically setting building levels), end-to-end integration testing.

On the API itself, after looking at the implementations here and the native SDKs: levels are a component of buildings, and yet this is only reflecting levels; what's the reason for that? It seems like the API would make a lot more sense if it included buildings and the building-change notifications as well.

@@ -17,13 +17,14 @@ flutter:
default_package: google_maps_flutter_ios
web:
default_package: google_maps_flutter_web
publish_to: none
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be removed, as it is disabling some CI checks.

@@ -54,7 +54,8 @@ Tile getTile() {
new Messages.PlatformPoint.Builder().setX((long) x).setY((long) y).build();
handler.post(() -> flutterApi.getTileOverlayTile(tileOverlayId, location, (long) zoom, this));
try {
// `flutterApi.getTileOverlayTile` is async, so use a `countDownLatch` to make it synchronized.
// `flutterApi.getTileOverlayTile` is async, so use a `countDownLatch` to make it
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are there formatting changes in a bunch of unrelated files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can resolve these. Not sure, could've ran the wrong formatter maybe? But I figured a CI check would fail if I had.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code formatters generally don't remove line breaks in comments, so adding extra line breaks won't fail CI.


/// Describes a single level in a building.
///
/// Multiple buildings can share a level - in this case the level instances will compare as equal,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What code in the class below makes this comment true?

@@ -167,6 +167,12 @@ class MethodChannelGoogleMapsFlutter extends GoogleMapsFlutterPlatform {
return _events(mapId).whereType<MapLongPressEvent>();
}

@override
Stream<MapActiveLevelChangedEvent> onActiveLevelChanged(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to this file should be reverted; the method channel code is only for compatibility with any legacy third-party implementations, and by definition legacy implementations won't have support for new features.

@ash2moon
Copy link
Contributor

@ChopinDavid are you still waiting on something or can this just be rebased and reviewed?

@ChopinDavid
Copy link
Contributor Author

@ash2moon Sorry, been meaning to get around to @stuartmorgan-g's other comments but have been having a hard time finding free time to do so. I believed this PR was ready to review, but it sounds like Stuart had some concerns so I'd hold off from merging until I address those, but I'd say feel free to review. As much feedback as possible is appreciated.

@jmagman jmagman requested review from vashworth and removed request for hellohuanlin May 15, 2025 21:17
@ChopinDavid
Copy link
Contributor Author

ChopinDavid commented May 17, 2025

On the API itself, after looking at the implementations here and the native SDKs: levels are a component of buildings, and yet this is only reflecting levels; what's the reason for that? It seems like the API would make a lot more sense if it included buildings and the building-change notifications as well.

@stuartmorgan-g
I see that on the Android side, we are tying into both onIndoorBuildingFocused and onIndoorLevelActivated. This is probably what prompted the suggestion to reflect the indoor building as well as the indoor level.

The idea originally was that, at least on the iOS side, the only native methods we are tying into are reflecting changes in the indoor level and not the indoor building. I thought we were doing the same on Android, but now see we are for some reason tying into both building and floor listeners. I will try to make it so that we do not need to override onIndoorBuildingFocused as this was not the original intention of this PR.

I would think this PR makes sense to merge if we can get it to a point where we are only tying into native methods reflecting changes in indoor levels and not buildings as well. If I can make it so we no longer tie into onIndoorBuildingFocused in GoogleMapController.java, I would think it makes sense to move forward with only passing the indoor level object to the dart-side methods.

If it is the case that we do, in fact, need to continue to tie into onIndoorBuildingFocused to accurately reflect all changes in indoor levels on the Android side, it probably does make sense to have buildings being reflected be a requirement for this PR being merged. That being said, this fix no longer represents a need for my company and I will have very little bandwidth to make those changes.

I'm curious what others think re: whether we move this forward if we can make it so that we are no longer tying into native methods reflecting indoor building changes. If we don't think this is the right path forward, I'm afraid this PR will more than likely sit in an open state for a long time without contributions from others. As you can see, its taken me 3 weeks to find the time to even take another look at these requested changes and I'm still trying to work through them.

@vashworth
Copy link
Contributor

The idea originally was that, at least on the iOS side, the only native methods we are tying into are reflecting changes in the indoor level and not the indoor building.

It seems weird to me to only partially implement the GMSIndoorDisplayDelegate. However, I understand that's all you need for your particular use case.

From the iOS side, other than it being confusing on why we don't implement the entire GMSIndoorDisplayDelegate, I don't see anything inherently wrong with this.

As mentioned before, though, this would need more tests.

@stuartmorgan-g
Copy link
Contributor

I would think this PR makes sense to merge if we can get it to a point where we are only tying into native methods reflecting changes in indoor levels and not buildings as well.

Could you elaborate (either here or in the issue) on what your use case is? I'm trying to understand under what circumstances it's useful to know what floor of a building is being displayed without knowing what the building is.

@vashworth
Copy link
Contributor

@ChopinDavid Are you still working on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p: google_maps_flutter platform-android platform-ios triage-android Should be looked at in Android triage triage-ios Should be looked at in iOS triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[google_maps_flutter] add onActiveLevelChanged callback to GoogleMap
6 participants