-
Notifications
You must be signed in to change notification settings - Fork 52
[geolocator] Refactor the C++ code #387
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
Conversation
|
Tip) Applying https://github.com/flutter-tizen/flutter-tizen/wiki/Style-guide and https://github.com/flutter-tizen/flutter-tizen/wiki/Recommended-settings-for-VS-Code will help formatting your code. |
|
@swift-kim Thank you for tip and I have a question regarding some github action failures related to this PR. Please let me know if there are any additional actions I need to take [build test] [dart_analyze fail] [integration test] |
|
@JSUYA Please check my M Chat message. It could be a DNS issue that should be resolved by the GitHub team. |
| @@ -1,12 +1,11 @@ | |||
| // Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. | |||
| // Use of this source code is governed by a BSD-style license that can be | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our plan was to use the same implementation of PermissionManager for all plugins that need permissions (camera, image_picker, geolocator, and permission_handler). You can replace the files in this package with the files copied from image_picker_tizen. Please let me know if there's any issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the PermissionManager by referencing another package.
I added ChangePermissionResulttoLocationPermission and ChangePermissionStatustoLocationPermission because we have to keep the enum order used by the geolocator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can change the values of the PermissionStatus enum as necessary (and modify the implementation of PermissionManager accordingly) without having to convert between the types. Please refer to #379. The PermissionManager class in the permission_handler_tizen package has been copied from image_picker_tizen, but has only a single return type PermissionStatus because its corresponding Dart type is already defined in the plugin's platform interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the PermissionStatus enum of PermissionManager.
| #include <app_control.h> | ||
| #include <package_manager.h> | ||
|
|
||
| namespace { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed to app_settings_manager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the original AppControl class seems to make more sense than individual methods in new AppSettingsManager because it can better represent the lifecycle of an app_control handle. Just error handling was missing there. In that way you will have two classes:
AppSettingsManager(has only public methods)AppControl(statically defined inapp_settings_manager.cc, used byAppSettingsManager)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed app_control_h to a local variable and deleted the private methods of AppSettingsManager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright. I'm okay with either way but you might discuss with the author of the original code (@bbrto21) about the change just in case.
| OnCancelGeolocatorUpdates(); | ||
| return nullptr; | ||
| }); | ||
| geolocator_updates_channel_->SetStreamHandler(std::move(handler)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please consider extending the flutter::StreamHandler (FlStreamHandler) class to create a stream handler class as I've done for battery_plus_tizen and connectivity_plus_tizen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't applied the StreamHandler class yet. Because I still don't perfect understand both StreamHandler and LocationManager. If that's okay with you, I'd like to make this a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to refactor the LocationManager class, you may refer to
Connection::StartListen()of connectivity_plus_tizen which returns false on immediate error and takes a result callback which returns aConnectionTypeon completion (Note that theConnectionTypeenum has akErrorvalue to represent an error state.)ServiceManagerof permission_handler_tizen whose return type isServiceStatus
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I extended 'LocationStream' and 'ServiceStatusStream' from 'LocationManager' to StreamHandler.
And I changed Error handling of LocationManager from TizenResult to throw exception. (For minimize use of output parameters)
| #include <app_control.h> | ||
| #include <package_manager.h> | ||
|
|
||
| namespace { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the original AppControl class seems to make more sense than individual methods in new AppSettingsManager because it can better represent the lifecycle of an app_control handle. Just error handling was missing there. In that way you will have two classes:
AppSettingsManager(has only public methods)AppControl(statically defined inapp_settings_manager.cc, used byAppSettingsManager)
89b42aa to
d826bf6
Compare
|
oh.. I will upload a patch for fix this soon |
313eff4 to
1754e7a
Compare
| LOG_ERROR("Unknown ppm_request_result_e."); | ||
| on_failure(TizenResult(ret)); | ||
| break; | ||
| throw PermissionManagerError("Failed to request permission."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the original PermissionManager class, the method should return kDenied here (although the default case should never happen). Please keep the logic consistent if there's no other special reason.
Also I'm okay with using PermissionManagerError instead of the error value kError but still, using kError should slightly be better in terms of consistency. Please always feel free to ask me before making changes when you're in doubt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a kError enum and modified it to return this. and removed PermissionManagerError class
| [result_ptr](LocationManagerError error) { | ||
| if (result_ptr) { | ||
| result_ptr->Error("Operation failed", error.GetErrorString()); | ||
| delete result_ptr; | ||
| } | ||
| }); | ||
| } catch (const LocationManagerError &error) { | ||
| if (result_ptr) { | ||
| result_ptr->Error("Operation failed", error.GetErrorString()); | ||
| delete result_ptr; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use only one error handling mechanism at a time (either error callback or exception). You can remove the try-catch block here and modify GetCurrentPosition accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error callback is the error handling of the callback function of location_manager_request_single_location called in GetCurrentPosition. As far as i know, since this callback is called asynchronously, it was not possible to throw an exception inside the callback.
There is a way to change GetCurrentPosition's return type to bool type and not use exception. (maybe the way you want)
I thought these three methods of LocationManager should be implemented in the same context: GetCurrentPosition, GetLastKnownPosition, IsLocationServiceEnabled.
(Reduce output arguments. Use Exceptions Rather Than Return Codes(maybe clean code?))
I don't think there is any particular problem with this way. Do you still think you should fix GetCurrentPosition to type bool and remove exception throwing? If you want to change it, I'll change it. Or please let me know if there is another way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for not being clear. What I meant by the above comment was just
@@ -93,7 +93,8 @@ void LocationManager::GetCurrentPosition(
},
this);
if (LOCATIONS_ERROR_NONE != ret) {
- throw LocationManagerError(ret);
+ on_error_callback_(LocationManagerError(ret));
+ on_error_callback_ = nullptr;
}
}In this way, you don't need a try-catch. Thank you for your careful consideration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I modified it according to your guide.
- Remove unused header - Change header's macro name - Fix wrong file name - Use typedefs of long commonly-used types - Cleanup error message
a4a1c7c to
9b4f99d
Compare
9b4f99d to
ef7448e
Compare
| LocationCallback on_location_callback, | ||
| LocationErrorCallback on_error_callback) { | ||
| on_location_callback_ = on_location_callback; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Callback arguments can be named like on_foo or foo_callback but you shouldn't mix the two.
| LocationCallback on_location_callback, | |
| LocationErrorCallback on_error_callback) { | |
| on_location_callback_ = on_location_callback; | |
| LocationCallback on_location_update, | |
| LocationErrorCallback on_error) { | |
| location_callback_ = on_location_update; |
This is what I meant in #387 (comment). I don't think we need to rename LocationCallback to LocationUpdateCallback and location_callback_ to location_update_callback_.
You might also refer to https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#naming-rules-for-typedefs-and-function-variables although it's not specifically for C++ code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@swift-kim
Thank you for detail review.
I have a question. about "the method that is called" in link.
According to the link, the location_callback_ you suggest should be handle_location_, shouldn't it?
And there are two cases of using LocationCallback. (stream, getCurrentPosition).
So I think this is appropriate. What do you think?
LocationCallback handle_location_update_;
LocationCallback handle_location_;
...
StartListenLocationUpdate(LocationCallback on_location_update)
handle_location_update_ = on_location_update;
...
GetCurrentPosition(LocationCallback on_location,LocationErrorCallback on_error
handle_location_ = on_location;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
location_callback_should behandle_location_, shouldn't it?
No, handleFoo in the document refers to an explicit method or function like this:
static void HandleFoo(void* value) {
// Handle the value.
}
SetFooHandler(HandleFoo);What do you think?
Yes, that looks good but the data member names would be:
LocationCallback location_callback_;
LocationCallback location_update_callback_;There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for guide. I changed it
7b4b12c to
b8444e3
Compare
swift-kim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much!
Part of the code refactoring project.