Skip to content

Commit c105284

Browse files
committed
Remove the app_control reply channel (#183)
* Remove the app_control reply channel - Let the method channel directly return responses to the caller - Add NativeInitializeDartApi, NativeCreateAppControl - Create AppControlManager * Convert shared_ptr to unique_ptr * Fix memory leaks - Add NativeAttachAppControl - Move definitions to the header
1 parent 1513890 commit c105284

File tree

5 files changed

+206
-156
lines changed

5 files changed

+206
-156
lines changed

shell/platform/tizen/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ template("embedder") {
211211
"//flutter/shell/platform/common:common_cpp_input",
212212
"//flutter/shell/platform/common:common_cpp_library_headers",
213213
"//flutter/shell/platform/common/client_wrapper:client_wrapper",
214+
"//third_party/dart/runtime:dart_api",
214215
"//third_party/rapidjson",
215216
]
216217
}

shell/platform/tizen/channels/app_control.cc

Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,69 @@
55
#include "app_control.h"
66

77
#include "flutter/shell/platform/tizen/channels/app_control_channel.h"
8+
#include "flutter/shell/platform/tizen/logger.h"
9+
10+
intptr_t NativeInitializeDartApi(void* data) {
11+
return Dart_InitializeApiDL(data);
12+
}
13+
14+
int32_t NativeCreateAppControl(Dart_Handle handle) {
15+
auto app_control = std::make_unique<flutter::AppControl>();
16+
if (!app_control->handle()) {
17+
return -1;
18+
}
19+
auto id = app_control->id();
20+
Dart_NewFinalizableHandle_DL(
21+
handle, app_control.get(), 64,
22+
[](void* isolate_callback_data, void* peer) {
23+
auto app_control = reinterpret_cast<flutter::AppControl*>(peer);
24+
flutter::AppControlManager::GetInstance().Remove(app_control->id());
25+
});
26+
flutter::AppControlManager::GetInstance().Insert(std::move(app_control));
27+
return id;
28+
}
29+
30+
bool NativeAttachAppControl(int32_t id, Dart_Handle handle) {
31+
auto app_control = flutter::AppControlManager::GetInstance().FindById(id);
32+
if (!app_control || !app_control->handle()) {
33+
return false;
34+
}
35+
Dart_NewFinalizableHandle_DL(
36+
handle, app_control, 64, [](void* isolate_callback_data, void* peer) {
37+
auto app_control = reinterpret_cast<flutter::AppControl*>(peer);
38+
flutter::AppControlManager::GetInstance().Remove(app_control->id());
39+
});
40+
return true;
41+
}
842

943
namespace flutter {
1044

11-
int AppControl::next_id_ = 0;
45+
int32_t AppControl::next_id_ = 0;
1246

13-
AppControl::AppControl(app_control_h app_control) : id_(next_id_++) {
14-
handle_ = app_control;
47+
AppControl::AppControl() : id_(next_id_++) {
48+
app_control_h handle = nullptr;
49+
AppControlResult ret = app_control_create(&handle);
50+
if (!ret) {
51+
FT_LOG(Error) << "app_control_create() failed: " << ret.message();
52+
return;
53+
}
54+
handle_ = handle;
55+
}
56+
57+
AppControl::AppControl(app_control_h handle) : id_(next_id_++) {
58+
app_control_h clone = nullptr;
59+
AppControlResult ret = app_control_clone(&clone, handle);
60+
if (!ret) {
61+
FT_LOG(Error) << "app_control_clone() failed: " << ret.message();
62+
return;
63+
}
64+
handle_ = clone;
1565
}
1666

1767
AppControl::~AppControl() {
18-
app_control_destroy(handle_);
68+
if (handle_) {
69+
app_control_destroy(handle_);
70+
}
1971
}
2072

2173
AppControlResult AppControl::GetString(std::string& str,
@@ -109,14 +161,6 @@ AppControlResult AppControl::SetExtraData(const EncodableMap& map) {
109161
return AppControlResult();
110162
}
111163

112-
void AppControl::SetManager(AppControlChannel* manager) {
113-
manager_ = manager;
114-
}
115-
116-
AppControlChannel* AppControl::GetManager() {
117-
return manager_;
118-
}
119-
120164
AppControlResult AppControl::GetOperation(std::string& operation) {
121165
return GetString(operation, app_control_get_operation);
122166
}
@@ -183,6 +227,12 @@ AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) {
183227
return AppControlResult(ret);
184228
}
185229

230+
bool AppControl::IsReplyRequested() {
231+
bool requested = false;
232+
app_control_is_reply_requested(handle_, &requested);
233+
return requested;
234+
}
235+
186236
EncodableValue AppControl::SerializeAppControlToMap() {
187237
std::string app_id, operation, mime, category, uri, caller_id, launch_mode;
188238
AppControlResult results[7];
@@ -202,43 +252,31 @@ EncodableValue AppControl::SerializeAppControlToMap() {
202252
}
203253
}
204254
EncodableMap map;
205-
map[EncodableValue("id")] = EncodableValue(GetId());
255+
map[EncodableValue("id")] = EncodableValue(id());
206256
map[EncodableValue("appId")] = EncodableValue(app_id);
207257
map[EncodableValue("operation")] = EncodableValue(operation);
208258
map[EncodableValue("mime")] = EncodableValue(mime);
209259
map[EncodableValue("category")] = EncodableValue(category);
210260
map[EncodableValue("uri")] = EncodableValue(uri);
211-
map[EncodableValue("callerId")] = EncodableValue(caller_id);
261+
map[EncodableValue("callerAppId")] = EncodableValue(caller_id);
212262
map[EncodableValue("launchMode")] = EncodableValue(launch_mode);
213263
map[EncodableValue("extraData")] = EncodableValue(extra_data);
264+
map[EncodableValue("shouldReply")] = EncodableValue(IsReplyRequested());
214265

215266
return EncodableValue(map);
216267
}
217268

218269
AppControlResult AppControl::SendLaunchRequest() {
219-
AppControlResult ret =
220-
app_control_send_launch_request(handle_, nullptr, nullptr);
221-
return ret;
270+
return app_control_send_launch_request(handle_, nullptr, nullptr);
222271
}
223272

224273
AppControlResult AppControl::SendLaunchRequestWithReply(
225-
std::shared_ptr<EventSink<EncodableValue>> reply_sink,
226-
AppControlChannel* manager) {
227-
SetManager(manager);
228-
auto on_reply = [](app_control_h request, app_control_h reply,
229-
app_control_result_e result, void* user_data) {
274+
ReplyCallback on_reply) {
275+
auto reply_callback = [](app_control_h request, app_control_h reply,
276+
app_control_result_e result, void* user_data) {
230277
AppControl* app_control = static_cast<AppControl*>(user_data);
231-
app_control_h clone = nullptr;
232-
AppControlResult ret = app_control_clone(&clone, reply);
233-
if (!ret) {
234-
FT_LOG(Error) << "Could not clone app_control: " << ret.message();
235-
return;
236-
}
237-
238-
std::shared_ptr<AppControl> app_control_reply =
239-
std::make_shared<AppControl>(clone);
278+
auto app_control_reply = std::make_unique<AppControl>(reply);
240279
EncodableMap map;
241-
map[EncodableValue("id")] = EncodableValue(app_control->GetId());
242280
map[EncodableValue("reply")] =
243281
app_control_reply->SerializeAppControlToMap();
244282
if (result == APP_CONTROL_RESULT_APP_STARTED) {
@@ -250,23 +288,20 @@ AppControlResult AppControl::SendLaunchRequestWithReply(
250288
} else if (result == APP_CONTROL_RESULT_CANCELED) {
251289
map[EncodableValue("result")] = EncodableValue("canceled");
252290
}
253-
254-
app_control->reply_sink_->Success(EncodableValue(map));
255-
app_control->GetManager()->AddExistingAppControl(
256-
std::move(app_control_reply));
291+
app_control->on_reply_(EncodableValue(map));
292+
app_control->on_reply_ = nullptr;
293+
AppControlManager::GetInstance().Insert(std::move(app_control_reply));
257294
};
258-
reply_sink_ = std::move(reply_sink);
259-
AppControlResult ret =
260-
app_control_send_launch_request(handle_, on_reply, this);
261-
return ret;
295+
on_reply_ = on_reply;
296+
return app_control_send_launch_request(handle_, reply_callback, this);
262297
}
263298

264299
AppControlResult AppControl::SendTerminateRequest() {
265300
AppControlResult ret = app_control_send_terminate_request(handle_);
266301
return ret;
267302
}
268303

269-
AppControlResult AppControl::Reply(std::shared_ptr<AppControl> reply,
304+
AppControlResult AppControl::Reply(AppControl* reply,
270305
const std::string& result) {
271306
app_control_result_e result_e;
272307
if (result == "appStarted") {
@@ -281,7 +316,7 @@ AppControlResult AppControl::Reply(std::shared_ptr<AppControl> reply,
281316
return AppControlResult(APP_CONTROL_ERROR_INVALID_PARAMETER);
282317
}
283318
AppControlResult ret = app_control_reply_to_launch_request(
284-
reply->Handle(), this->handle_, result_e);
319+
reply->handle(), this->handle_, result_e);
285320
return ret;
286321
}
287322

shell/platform/tizen/channels/app_control.h

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,34 @@
77

88
#include <app.h>
99

10+
#include <unordered_map>
11+
1012
#include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h"
1113
#include "flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h"
12-
#include "flutter/shell/platform/tizen/logger.h"
14+
#include "flutter/shell/platform/common/public/flutter_export.h"
15+
#include "third_party/dart/runtime/include/dart_api_dl.h"
16+
17+
// Called by Dart code through FFI to initialize dart_api_dl.h.
18+
DART_EXPORT FLUTTER_EXPORT intptr_t NativeInitializeDartApi(void* data);
19+
20+
// Creates an internally managed instance of AppControl and associates with
21+
// |handle|.
22+
//
23+
// A finalizer is attached to the created instance and invoked when the
24+
// associated |handle| is disposed by GC.
25+
//
26+
// Returns a unique AppControl ID on success, otherwise -1.
27+
DART_EXPORT FLUTTER_EXPORT int32_t NativeCreateAppControl(Dart_Handle handle);
28+
29+
// Finds an instance of AppControl with |id| and associates with |handle|.
30+
//
31+
// A finalizer is attached to the instance and invoked when the associated
32+
// |handle| is disposed by GC.
33+
//
34+
// Returns false if an instance of AppControl with the given |id| could not
35+
// be found, otherwise true.
36+
DART_EXPORT FLUTTER_EXPORT bool NativeAttachAppControl(int32_t id,
37+
Dart_Handle handle);
1338

1439
namespace flutter {
1540

@@ -25,15 +50,16 @@ struct AppControlResult {
2550
int error_code;
2651
};
2752

28-
class AppControlChannel;
29-
3053
class AppControl {
3154
public:
32-
AppControl(app_control_h app_control);
33-
~AppControl();
55+
using ReplyCallback = std::function<void(const EncodableValue& response)>;
56+
57+
explicit AppControl();
58+
explicit AppControl(app_control_h handle);
59+
virtual ~AppControl();
3460

35-
int GetId() { return id_; }
36-
app_control_h Handle() { return handle_; }
61+
int32_t id() { return id_; }
62+
app_control_h handle() { return handle_; }
3763

3864
AppControlResult GetOperation(std::string& operation);
3965
AppControlResult SetOperation(const std::string& operation);
@@ -48,24 +74,19 @@ class AppControl {
4874
AppControlResult GetCaller(std::string& caller);
4975
AppControlResult GetLaunchMode(std::string& launch_mode);
5076
AppControlResult SetLaunchMode(const std::string& launch_mode);
77+
bool IsReplyRequested();
5178

5279
EncodableValue SerializeAppControlToMap();
5380

5481
AppControlResult SendLaunchRequest();
55-
AppControlResult SendLaunchRequestWithReply(
56-
std::shared_ptr<EventSink<EncodableValue>> reply_sink,
57-
AppControlChannel* manager);
82+
AppControlResult SendLaunchRequestWithReply(ReplyCallback on_reply);
5883
AppControlResult SendTerminateRequest();
5984

60-
AppControlResult Reply(std::shared_ptr<AppControl> reply,
61-
const std::string& result);
85+
AppControlResult Reply(AppControl* reply, const std::string& result);
6286

6387
AppControlResult GetExtraData(EncodableMap& value);
6488
AppControlResult SetExtraData(const EncodableMap& value);
6589

66-
void SetManager(AppControlChannel* manager);
67-
AppControlChannel* GetManager();
68-
6990
private:
7091
AppControlResult GetString(std::string& str, int func(app_control_h, char**));
7192
AppControlResult SetString(const std::string& str,
@@ -74,12 +95,38 @@ class AppControl {
7495
AppControlResult AddExtraData(std::string key, EncodableValue value);
7596
AppControlResult AddExtraDataList(std::string& key, EncodableList& list);
7697

77-
app_control_h handle_;
78-
int id_;
79-
static int next_id_;
80-
std::shared_ptr<EventSink<EncodableValue>> reply_sink_;
98+
app_control_h handle_ = nullptr;
99+
int32_t id_;
100+
static int32_t next_id_;
101+
ReplyCallback on_reply_ = nullptr;
102+
};
103+
104+
class AppControlManager {
105+
public:
106+
// Returns an instance of this class.
107+
static AppControlManager& GetInstance() {
108+
static AppControlManager instance;
109+
return instance;
110+
}
111+
112+
void Insert(std::unique_ptr<AppControl> app_control) {
113+
map_.insert({app_control->id(), std::move(app_control)});
114+
}
115+
116+
void Remove(int32_t id) { map_.erase(id); }
117+
118+
AppControl* FindById(const int32_t id) {
119+
if (map_.find(id) == map_.end()) {
120+
return nullptr;
121+
}
122+
return map_[id].get();
123+
}
124+
125+
private:
126+
explicit AppControlManager() {}
127+
~AppControlManager() {}
81128

82-
AppControlChannel* manager_;
129+
std::unordered_map<int32_t, std::unique_ptr<AppControl>> map_;
83130
};
84131

85132
} // namespace flutter

0 commit comments

Comments
 (0)