Skip to content
This repository has been archived by the owner on Apr 23, 2023. It is now read-only.

Update engine's location requests #215

Merged
merged 5 commits into from
Jun 16, 2017
Merged

Update engine's location requests #215

merged 5 commits into from
Jun 16, 2017

Conversation

sarahsnow1
Copy link
Contributor

@sarahsnow1 sarahsnow1 commented Jun 7, 2017

Overview

Before this PR, LocationRequests were not removed from the underlying LocationEngine. This meant that the location requirements we requested from the system could sometimes be too aggressive. This PR adds behavior to remove all LocationRequests for a given LostApiClient + LocationListener/PendingIntent/LocationCallback pair which are not used by any other pairs.

Proposed Changes

  • Creates new LostRequestManager class to manage which LostApiClient + LocationListener/PendingIntent/LocationCallback pairs have made which LocationRequests
  • Creates new class ClientCallbackWrapper to allow for a multi-key hash in LostRequestManager
  • FusedLocationProviderApi#requestLocationUpdates has been updated to register ClientCallbackWrapper/LocationRequest pairs with the LostRequestManager
  • FusedLocationProviderApi#removeLocationUpdates has been updated to unregister ClientCallbackWrapper/LocationRequest pairs with the LostRequestManager, retrieve all LocationRequests used only by that ClientCallbackWrapper, and remove these LocationRequests from the LocationEngine
  • LocationEngine#setRequest has been removed and split into LocationEngine#addRequest, LocationEngine#removeRequest, and LocationEngine#removeAllRequests
  • Because LocationEngine#removeRequest disables and re-enables the engine (if there are still remaining requests), we no longer need to check to see if the engine should be disabled in FusedLocationProviderApi#checkAllListenersPendingIntentsAndCallbacks (ticket to remove this code in a follow up PR)

Followup work will add more tests

Closes #213

@tobrun
Copy link

tobrun commented Jun 8, 2017

Tested and resolves #213 🎉

@sarahsnow1 sarahsnow1 requested a review from ecgreb June 8, 2017 14:59
Copy link
Collaborator

@ecgreb ecgreb left a comment

Choose a reason for hiding this comment

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

Great work @sarahlensing !
Couple of questions and comments below.

.setFastestInterval(0)
.setSmallestDisplacement(0)
.setInterval(1000); // 1 sec
LocationServices.FusedLocationApi.requestLocationUpdates(client, request, noPowerListener);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Needs a runtime permission check here. Currently crashes on fresh install.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch, I'll create a new activity and migrate these examples in a future PR #217

.setSmallestDisplacement(0)
.setInterval(1000); // 1 sec

LocationServices.FusedLocationApi.requestLocationUpdates(otherClient, request,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here.

}
}

public void removeAllRequests() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

As a possible future enhancement, should this also be invoked when the last client is disconnected to avoid this issue of needing to explicitly remove all requests before shutting down a client?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, we've run into some recent issues with this behavior. I updated this ticket to capture the work: #214

Set<LocationRequest> requests = clientCallbackToLocationRequests.get(w);
requestsToRemove.removeAll(requests);
}
return requestsToRemove;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess we can't rule out the possibility of more than one client registering the same request but that seems kind of gross.

What if a LocationRequest generated a unique internal id for itself based on the time it was registered? Would that simplify the logic here?

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'm not sure this would simplify the logic because I'd still have to iterate over the request to unique id map to ensure the request id was the one corresponding to the client wrapper I wanted to remove requests for. I would also have to add a step to update request ids for remaining client wrappers after this step. Am I missing something though? Is this how you imagine it be used?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Mainly I was looking for a way to not have to search all other clients to see if another one is using any of the requestsToRemove before removing them but maybe a unique id is not the best way to achieve that.

What if we just made a copy of each incoming request so two clients could have equal requests without it being the same instance?

private Set<LocationRequest> getRequestOnlyUsedBy(ClientCallbackWrapper wrapper) {
Set<LocationRequest> requestsToRemove = clientCallbackToLocationRequests.get(wrapper);
if (requestsToRemove == null) {
return requestsToRemove;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could be simplified as return null;.

}
for (LocationRequest request : requests) {
try {
service.removeLocationUpdates(request);
Copy link
Collaborator

@ecgreb ecgreb Jun 12, 2017

Choose a reason for hiding this comment

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

Sending a separate request to the service for each request to be removed will cause a disable/enable cycle for each one. This has the side effect of sending out multiple location updates in rapid succession via FusionEngine#checkLastKnownAndNotify(provider).

I think active location listeners would be protected from this effect if they have a fastestInterval associated with their request but it might be worth considering a batch removal operation.

@zugaldia
Copy link

@sarahlensing anything that we could help with on our side to help getting this PR merged?

throw new RuntimeException(e);
}
try {
service.removeLocationUpdates(requests);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is great should really cut down on thrashing of the LocationManager listeners when multiple requests are removed!

@msmollin msmollin merged commit 40c3a4c into master Jun 16, 2017
@msmollin msmollin deleted the 213-rm-loc-requests branch June 16, 2017 18:31
GulajavaMinistudio added a commit to GulajavaMinistudio/lost that referenced this pull request Jun 16, 2017
Update engine's location requests (lostzen#215)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants