Skip to content

Commit 1e7b2fa

Browse files
authored
Refactor PlatformChannel (#163)
1 parent 649809d commit 1e7b2fa

File tree

6 files changed

+211
-272
lines changed

6 files changed

+211
-272
lines changed

shell/platform/tizen/BUILD.gn

+4-4
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ template("embedder") {
115115
"channels/key_event_channel.cc",
116116
"channels/lifecycle_channel.cc",
117117
"channels/navigation_channel.cc",
118+
"channels/platform_channel.cc",
118119
"channels/platform_view_channel.cc",
120+
"channels/settings_channel.cc",
119121
"channels/text_input_channel.cc",
120122
"flutter_project_bundle.cc",
121123
"flutter_tizen.cc",
@@ -152,8 +154,7 @@ template("embedder") {
152154
sources += [
153155
"channels/app_control.cc",
154156
"channels/app_control_channel.cc",
155-
"channels/platform_channel.cc",
156-
"channels/settings_channel.cc",
157+
"channels/platform_channel_tizen.cc",
157158
"channels/settings_channel_tizen.cc",
158159
"external_texture_pixel_gl.cc",
159160
"external_texture_surface_gl.cc",
@@ -177,8 +178,7 @@ template("embedder") {
177178
]
178179
} else {
179180
sources += [
180-
"channels/platform_channel_stub.cc",
181-
"channels/settings_channel.cc",
181+
"channels/platform_channel_linux.cc",
182182
"channels/settings_channel_linux.cc",
183183
"external_texture_pixel_gl_stub.cc",
184184
"external_texture_surface_gl_stub.cc",

shell/platform/tizen/channels/platform_channel.cc

+44-252
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
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[] =
3429
constexpr 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

20845
PlatformChannel::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) {

shell/platform/tizen/channels/platform_channel.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#define EMBEDDER_PLATFORM_CHANNEL_H_
77

88
#include <memory>
9+
#include <string>
10+
#include <vector>
911

1012
#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h"
1113
#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h"
@@ -20,17 +22,20 @@ class PlatformChannel {
2022
virtual ~PlatformChannel();
2123

2224
private:
23-
#ifndef __X64_SHELL__
2425
void HandleMethodCall(
2526
const MethodCall<rapidjson::Document>& call,
2627
std::unique_ptr<MethodResult<rapidjson::Document>> result);
2728

29+
void SystemNavigatorPop();
30+
void PlaySystemSound(const std::string& sound_type);
31+
void HapticFeedbackVibrate(const std::string& feedback_type);
32+
void SetPreferredOrientations(const std::vector<std::string>& orientations);
33+
2834
std::unique_ptr<MethodChannel<rapidjson::Document>> channel_;
2935

3036
// A reference to the renderer object managed by FlutterTizenEngine.
3137
// This can be nullptr if the engine is running in headless mode.
3238
TizenRenderer* renderer_;
33-
#endif
3439
};
3540

3641
} // namespace flutter

0 commit comments

Comments
 (0)