4
4
5
5
#include " platform_channel.h"
6
6
7
+ #include < mutex>
7
8
#include < app.h>
9
+ #include < cbhm.h>
8
10
9
11
#include " flutter/shell/platform/common/cpp/json_method_codec.h"
10
12
#include " flutter/shell/platform/tizen/tizen_log.h"
11
13
12
14
static constexpr char kChannelName [] = " flutter/platform" ;
13
15
16
+ // Clipboard.getData constants and variables
17
+ std::mutex is_processing_mutex;
18
+ static bool is_processing = false ;
19
+ static constexpr char kTextKey [] = " text" ;
20
+ static constexpr char kTextPlainFormat [] = " text/plain" ;
21
+ static constexpr char kUnknownClipboardFormatError [] =
22
+ " Unknown clipboard format error" ;
23
+ static constexpr char kUnknownClipboardError [] =
24
+ " Unknown error during clipboard data retrieval" ;
25
+
14
26
PlatformChannel::PlatformChannel (flutter::BinaryMessenger* messenger)
15
27
: channel_(std::make_unique<flutter::MethodChannel<rapidjson::Document>>(
16
28
messenger, kChannelName , &flutter::JsonMethodCodec::GetInstance ())) {
@@ -37,7 +49,77 @@ void PlatformChannel::HandleMethodCall(
37
49
} else if (method == " HapticFeedback.vibrate" ) {
38
50
result->NotImplemented ();
39
51
} else if (method == " Clipboard.getData" ) {
40
- result->NotImplemented ();
52
+ const rapidjson::Value& format = call.arguments ()[0 ];
53
+
54
+ // https://api.flutter.dev/flutter/services/Clipboard/kTextPlain-constant.html
55
+ // API supports only kTextPlain format, hovewer cbhm API supports also other formats
56
+ if (strcmp (format.GetString (), kTextPlainFormat ) != 0 ) {
57
+ result->Error (kUnknownClipboardFormatError ,
58
+ " Clipboard API only supports text." );
59
+ return ;
60
+ }
61
+
62
+ cbhm_sel_type_e selection_type = CBHM_SEL_TYPE_TEXT;
63
+
64
+ cbhm_h cbhm_handle = nullptr ;
65
+ int ret = cbhm_open_service (&cbhm_handle);
66
+ if (CBHM_ERROR_NONE != ret) {
67
+ result->Error (kUnknownClipboardError , " Failed to initialize cbhm service." );
68
+ return ;
69
+ }
70
+
71
+ // Report error on next calls until current will be finished.
72
+ // Native API - cbhm_selection_get works on static struct, so accessing clipboard parallelly will end
73
+ // with race regarding returning values - cbhm_selection_data_cb will be triggered only for latest call.
74
+ // TODO consider some queuing mechnism instead of returning error for next calls
75
+ {
76
+ std::lock_guard<std::mutex> lock (is_processing_mutex);
77
+ if (is_processing) {
78
+ result->Error (kUnknownClipboardError , " Already processing by other thread." );
79
+ return ;
80
+ }
81
+ is_processing = true ;
82
+ }
83
+ struct method_data_t {
84
+ std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result;
85
+ cbhm_h cbhm_handle;
86
+ };
87
+ // invalidates the result pointer
88
+ method_data_t * data = new method_data_t {};
89
+ data->result = std::move (result);
90
+ data->cbhm_handle = cbhm_handle;
91
+
92
+ auto cbhm_selection_data_cb = [](cbhm_h cbhm_handle, const char *buf, size_t len, void *user_data) -> int {
93
+ auto data = static_cast <method_data_t *>(user_data);
94
+ // move unique_ptr from method_data_t and then release memory
95
+ auto result = std::move (data->result );
96
+ delete data;
97
+ cbhm_close_service (data->cbhm_handle );
98
+
99
+ FT_LOGD (" cbhm_selection_get SUCCESS (%d) %s" , len, buf);
100
+ {
101
+ std::lock_guard<std::mutex> lock (is_processing_mutex);
102
+ is_processing = false ;
103
+ }
104
+ if (buf) {
105
+ rapidjson::Document document;
106
+ document.SetObject ();
107
+ rapidjson::Document::AllocatorType& allocator = document.GetAllocator ();
108
+ document.AddMember (rapidjson::Value (kTextKey , allocator),
109
+ rapidjson::Value (std::string{buf, len}, allocator), allocator);
110
+ result->Success (document);
111
+ return CBHM_ERROR_NONE;
112
+ } else {
113
+ result->Error (kUnknownClipboardError , " Data buffer is null." );
114
+ return CBHM_ERROR_NO_DATA;
115
+ }
116
+ };
117
+
118
+ ret = cbhm_selection_get (cbhm_handle, selection_type, cbhm_selection_data_cb, data);
119
+ if (CBHM_ERROR_NONE != ret) {
120
+ result->Error (kUnknownClipboardError , " Failed to gather data." );
121
+ return ;
122
+ }
41
123
} else if (method == " Clipboard.setData" ) {
42
124
result->NotImplemented ();
43
125
} else if (method == " Clipboard.hasStrings" ) {
0 commit comments