44
55#include " platform_channel.h"
66
7- #include < app.h>
8- #include < feedback.h>
9-
10- #include < map>
11-
127#include " flutter/shell/platform/common/json_method_codec.h"
138#include " flutter/shell/platform/tizen/logger.h"
149
@@ -34,176 +29,18 @@ constexpr char kRestoreSystemUIOverlaysMethod[] =
3429constexpr char kSetSystemUIOverlayStyleMethod [] =
3530 " SystemChrome.setSystemUIOverlayStyle" ;
3631
37- constexpr char kSoundTypeClick [] = " SystemSoundType.click" ;
38-
39- class FeedbackManager {
40- public:
41- enum class ResultCode {
42- kOk ,
43- kNotSupportedError ,
44- kPermissionDeniedError ,
45- kUnknownError
46- };
47-
48- enum class FeedbackPattern {
49- kClick = FEEDBACK_PATTERN_TAP,
50- kAlert = FEEDBACK_PATTERN_GENERAL,
51- kSip = FEEDBACK_PATTERN_SIP
52- };
53-
54- enum class FeedbackType {
55- kVibration = FEEDBACK_TYPE_VIBRATION,
56- kSound = FEEDBACK_TYPE_SOUND
57- };
58-
59- static std::string GetVibrateVariantName (const char * haptic_feedback_type) {
60- if (!haptic_feedback_type) {
61- return " HapticFeedback.vibrate" ;
62- }
63-
64- const size_t kPrefixToRemoveLen = strlen (" HapticFeedbackType." );
65-
66- assert (strlen (haptic_feedback_type) >= kPrefixToRemoveLen );
67-
68- const std::string kHapticFeedbackPrefix = " HapticFeedback." ;
69-
70- return kHapticFeedbackPrefix +
71- std::string{haptic_feedback_type + kPrefixToRemoveLen };
72- }
73-
74- static std::string GetErrorMessage (ResultCode result_code,
75- const std::string& method_name,
76- const std::string& args = " " ) {
77- const auto method_name_with_args = method_name + " (" + args + " )" ;
78-
79- switch (result_code) {
80- case ResultCode::kNotSupportedError :
81- return method_name_with_args + " is not supported" ;
82- case ResultCode::kPermissionDeniedError :
83- return std::string{" No permission to run " } + method_name_with_args +
84- " . Add \" http://tizen.org/privilege/haptic\" privilege to "
85- " tizen-manifest.xml to use this method" ;
86- case ResultCode::kUnknownError :
87- default :
88- return std::string{" An unknown error on " } + method_name_with_args +
89- " call" ;
90- }
91- }
92-
93- static FeedbackManager& GetInstance () {
94- static FeedbackManager instance;
95- return instance;
96- }
97-
98- FeedbackManager (const FeedbackManager&) = delete ;
99- FeedbackManager& operator =(const FeedbackManager&) = delete ;
100-
101- ResultCode Play (FeedbackType type, FeedbackPattern pattern) {
102- if (ResultCode::kOk != initialization_status_) {
103- return initialization_status_;
104- }
105-
106- auto ret = feedback_play_type (static_cast <feedback_type_e>(type),
107- static_cast <feedback_pattern_e>(pattern));
108- if (FEEDBACK_ERROR_NONE == ret) {
109- return ResultCode::kOk ;
110- }
111- FT_LOG (Error) << " feedback_play_type() failed with error: "
112- << get_error_message (ret);
113-
114- return NativeErrorToResultCode (ret);
115- }
116-
117- private:
118- static ResultCode NativeErrorToResultCode (int native_error_code) {
119- switch (native_error_code) {
120- case FEEDBACK_ERROR_NONE:
121- return ResultCode::kOk ;
122- case FEEDBACK_ERROR_NOT_SUPPORTED:
123- return ResultCode::kNotSupportedError ;
124- case FEEDBACK_ERROR_PERMISSION_DENIED:
125- return ResultCode::kPermissionDeniedError ;
126- case FEEDBACK_ERROR_OPERATION_FAILED:
127- case FEEDBACK_ERROR_INVALID_PARAMETER:
128- case FEEDBACK_ERROR_NOT_INITIALIZED:
129- default :
130- return ResultCode::kUnknownError ;
131- }
132- }
133-
134- FeedbackManager () {
135- auto ret = feedback_initialize ();
136- if (FEEDBACK_ERROR_NONE != ret) {
137- FT_LOG (Error) << " feedback_initialize() failed with error: "
138- << get_error_message (ret);
139- initialization_status_ = NativeErrorToResultCode (ret);
140- return ;
141- }
142-
143- initialization_status_ = ResultCode::kOk ;
144- }
145-
146- ~FeedbackManager () {
147- auto ret = feedback_deinitialize ();
148- if (FEEDBACK_ERROR_NONE != ret) {
149- FT_LOG (Error) << " feedback_deinitialize() failed with error: "
150- << get_error_message (ret);
151- return ;
152- }
153- }
154-
155- ResultCode initialization_status_ = ResultCode::kUnknownError ;
156- };
157-
158- } // namespace
159-
160- // Clipboard constants and variables
161- namespace clipboard {
162-
163- // naive implementation using std::string as a container of internal clipboard
164- // data
165- std::string string_clipboard = " " ;
166-
167- static constexpr char kTextKey [] = " text" ;
168- static constexpr char kTextPlainFormat [] = " text/plain" ;
169- static constexpr char kUnknownClipboardFormatError [] =
32+ constexpr char kTextKey [] = " text" ;
33+ constexpr char kTextPlainFormat [] = " text/plain" ;
34+ constexpr char kUnknownClipboardFormatError [] =
17035 " Unknown clipboard format error" ;
171- static constexpr char kUnknownClipboardError [] =
36+ constexpr char kUnknownClipboardError [] =
17237 " Unknown error during clipboard data retrieval" ;
17338
174- void GetData ( const MethodCall<rapidjson::Document>& call,
175- std::unique_ptr<MethodResult<rapidjson::Document>> result) {
176- const rapidjson::Value& format = call. arguments ()[ 0 ] ;
39+ // Naive implementation using std::string as a container of internal clipboard
40+ // data.
41+ std::string text_clipboard = " " ;
17742
178- // https://api.flutter.dev/flutter/services/Clipboard/kTextPlain-constant.html
179- // API supports only kTextPlain format
180- if (strcmp (format.GetString (), kTextPlainFormat ) != 0 ) {
181- result->Error (kUnknownClipboardFormatError ,
182- " Clipboard API only supports text." );
183- return ;
184- }
185-
186- rapidjson::Document document;
187- document.SetObject ();
188- rapidjson::Document::AllocatorType& allocator = document.GetAllocator ();
189- document.AddMember (rapidjson::Value (kTextKey , allocator),
190- rapidjson::Value (string_clipboard, allocator), allocator);
191- result->Success (document);
192- }
193-
194- void SetData (const MethodCall<rapidjson::Document>& call,
195- std::unique_ptr<MethodResult<rapidjson::Document>> result) {
196- const rapidjson::Value& document = *call.arguments ();
197- rapidjson::Value::ConstMemberIterator itr = document.FindMember (kTextKey );
198- if (itr == document.MemberEnd ()) {
199- result->Error (kUnknownClipboardError , " Invalid message format" );
200- return ;
201- }
202- string_clipboard = itr->value .GetString ();
203- result->Success ();
204- }
205-
206- } // namespace clipboard
43+ } // namespace
20744
20845PlatformChannel::PlatformChannel (BinaryMessenger* messenger,
20946 TizenRenderer* renderer)
@@ -225,97 +62,52 @@ void PlatformChannel::HandleMethodCall(
22562 const MethodCall<rapidjson::Document>& call,
22663 std::unique_ptr<MethodResult<rapidjson::Document>> result) {
22764 const auto method = call.method_name ();
65+ const auto arguments = call.arguments ();
22866
22967 if (method == kSystemNavigatorPopMethod ) {
230- ui_app_exit ();
68+ SystemNavigatorPop ();
23169 result->Success ();
23270 } else if (method == kPlaySoundMethod ) {
233- const std::string pattern_str = call.arguments ()[0 ].GetString ();
234-
235- const FeedbackManager::FeedbackPattern pattern =
236- (pattern_str == kSoundTypeClick )
237- ? FeedbackManager::FeedbackPattern::kClick
238- : FeedbackManager::FeedbackPattern::kAlert ;
239-
240- auto ret = FeedbackManager::GetInstance ().Play (
241- FeedbackManager::FeedbackType::kSound , pattern);
242- if (FeedbackManager::ResultCode::kOk == ret) {
243- result->Success ();
244- return ;
245- }
246-
247- const auto error_cause =
248- FeedbackManager::GetErrorMessage (ret, kPlaySoundMethod , pattern_str);
249- const std::string error_message = " Could not play sound" ;
250- FT_LOG (Error) << error_cause << " : " << error_message;
251-
252- result->Error (error_cause, error_message);
253-
71+ PlaySystemSound (arguments[0 ].GetString ());
72+ result->Success ();
25473 } else if (method == kHapticFeedbackVibrateMethod ) {
255- /*
256- * We use a single type of vibration (FEEDBACK_PATTERN_SIP) to implement
257- * HapticFeedback's vibrate, lightImpact, mediumImpact, heavyImpact
258- * and selectionClick methods, because Tizen's "feedback" module
259- * has no dedicated vibration types for them.
260- * Thus, we ignore the "arguments" contents for "HapticFeedback.vibrate"
261- * calls.
262- */
263-
264- auto ret = FeedbackManager::GetInstance ().Play (
265- FeedbackManager::FeedbackType::kVibration ,
266- FeedbackManager::FeedbackPattern::kSip );
267- if (FeedbackManager::ResultCode::kOk == ret) {
268- result->Success ();
269- return ;
74+ std::string type;
75+ if (arguments->IsString ()) {
76+ type = arguments[0 ].GetString ();
27077 }
271-
272- const auto vibrate_variant_name =
273- FeedbackManager::GetVibrateVariantName (call.arguments ()[0 ].GetString ());
274- const auto error_cause =
275- FeedbackManager::GetErrorMessage (ret, vibrate_variant_name);
276- const std::string error_message = " Could not vibrate" ;
277-
278- FT_LOG (Error) << error_cause << " : " << error_message;
279-
280- result->Error (error_cause, error_message);
78+ HapticFeedbackVibrate (type);
79+ result->Success ();
28180 } else if (method == kGetClipboardDataMethod ) {
282- clipboard::GetData (call, std::move (result));
81+ // https://api.flutter.dev/flutter/services/Clipboard/kTextPlain-constant.html
82+ // The API supports only kTextPlain format.
83+ if (strcmp (arguments[0 ].GetString (), kTextPlainFormat ) != 0 ) {
84+ result->Error (kUnknownClipboardFormatError ,
85+ " Clipboard API only supports text." );
86+ return ;
87+ }
88+ rapidjson::Document document;
89+ document.SetObject ();
90+ rapidjson::Document::AllocatorType& allocator = document.GetAllocator ();
91+ document.AddMember (rapidjson::Value (kTextKey , allocator),
92+ rapidjson::Value (text_clipboard, allocator), allocator);
93+ result->Success (document);
28394 } else if (method == kSetClipboardDataMethod ) {
284- clipboard::SetData (call, std::move (result));
95+ const rapidjson::Value& document = *arguments;
96+ auto iter = document.FindMember (kTextKey );
97+ if (iter == document.MemberEnd ()) {
98+ result->Error (kUnknownClipboardError , " Invalid message format." );
99+ return ;
100+ }
101+ text_clipboard = iter->value .GetString ();
102+ result->Success ();
285103 } else if (method == kSetPreferredOrientationsMethod ) {
286- if (renderer_) {
287- static const std::string kPortraitUp = " DeviceOrientation.portraitUp" ;
288- static const std::string kPortraitDown = " DeviceOrientation.portraitDown" ;
289- static const std::string kLandscapeLeft =
290- " DeviceOrientation.landscapeLeft" ;
291- static const std::string kLandscapeRight =
292- " DeviceOrientation.landscapeRight" ;
293- static const std::map<std::string, int > orientation_mapping = {
294- {kPortraitUp , 0 },
295- {kLandscapeLeft , 90 },
296- {kPortraitDown , 180 },
297- {kLandscapeRight , 270 },
298- };
299-
300- const auto & list = call.arguments ()[0 ];
301- std::vector<int > rotations;
302- for (rapidjson::Value::ConstValueIterator itr = list.Begin ();
303- itr != list.End (); ++itr) {
304- const std::string& rot = itr->GetString ();
305- rotations.push_back (orientation_mapping.at (rot));
306- }
307- if (rotations.size () == 0 ) {
308- // According do docs
309- // https://api.flutter.dev/flutter/services/SystemChrome/setPreferredOrientations.html
310- // "The empty list causes the application to defer to the operating
311- // system default."
312- rotations = {0 , 90 , 180 , 270 };
313- }
314- renderer_->SetPreferredOrientations (rotations);
315- result->Success ();
316- } else {
317- result->Error (" Not supported for service applications" );
104+ const auto & list = arguments[0 ];
105+ std::vector<std::string> orientations;
106+ for (auto iter = list.Begin (); iter != list.End (); ++iter) {
107+ orientations.push_back (iter->GetString ());
318108 }
109+ SetPreferredOrientations (orientations);
110+ result->Success ();
319111 } else if (method == kSetApplicationSwitcherDescriptionMethod ) {
320112 result->NotImplemented ();
321113 } else if (method == kSetEnabledSystemUIOverlaysMethod ) {
0 commit comments