Skip to content

Commit 14077d6

Browse files
authored
[video_player_videohole] Remove Ecore API (#1048)
1 parent 27324e8 commit 14077d6

7 files changed

Lines changed: 184 additions & 36 deletions

File tree

packages/video_player_videohole/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
## NEXT
1+
## 0.5.9
22

33
* Adds compatibility with `http` 1.0 in example.
44
* Removed unused proxy APIs.
5+
* Remove Ecore API.
56

67
## 0.5.8
78

packages/video_player_videohole/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ To use this package, add `video_player_videohole` as a dependency in your `pubsp
1212

1313
```yaml
1414
dependencies:
15-
video_player_videohole: ^0.5.8
15+
video_player_videohole: ^0.5.9
1616
```
1717
1818
Then you can import `video_player_videohole` in your Dart code:

packages/video_player_videohole/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: video_player_videohole
22
description: Flutter plugin for displaying inline video on Tizen TV devices.
33
homepage: https://github.com/flutter-tizen/plugins
44
repository: https://github.com/flutter-tizen/plugins/tree/master/packages/video_player_videohole
5-
version: 0.5.8
5+
version: 0.5.9
66

77
environment:
88
sdk: ">=3.1.0 <4.0.0"

packages/video_player_videohole/tizen/src/drm_manager.cc

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,31 @@ DrmManager::DrmManager() : drm_type_(DM_TYPE_NONE) {
3434
} else {
3535
LOG_ERROR("[DrmManager] Fail to dlopen libdrmmanager.");
3636
}
37-
license_request_pipe_ = ecore_pipe_add(
38-
[](void *data, void *buffer, unsigned int nbyte) -> void {
39-
auto *self = static_cast<DrmManager *>(data);
40-
self->ExecuteRequest();
41-
},
42-
this);
37+
38+
// Initialize GMainContext and license request state
39+
main_context_ = std::unique_ptr<GMainContext, GMainContextDeleter>(
40+
g_main_context_ref_thread_default());
41+
license_request_state_ = std::make_shared<DrmManager::LicenseRequestState>();
42+
license_request_state_->manager = this;
4343
}
4444

4545
DrmManager::~DrmManager() {
4646
ReleaseDrmSession();
47-
if (license_request_pipe_) {
48-
ecore_pipe_del(license_request_pipe_);
47+
48+
// Mark license request state as disposed and cancel pending event source
49+
if (license_request_state_) {
50+
std::lock_guard<std::mutex> lock(license_request_state_->mutex);
51+
license_request_state_->disposed = true;
52+
license_request_state_->manager = nullptr;
53+
54+
if (license_request_state_->pending_source_id != 0) {
55+
g_source_remove(license_request_state_->pending_source_id);
56+
license_request_state_->pending_source_id = 0;
57+
}
4958
}
59+
60+
main_context_.reset();
61+
5062
if (drm_manager_proxy_) {
5163
CloseDrmManagerProxy(drm_manager_proxy_);
5264
drm_manager_proxy_ = nullptr;
@@ -325,10 +337,53 @@ void DrmManager::RequestLicense(std::string &session_id, std::string &message) {
325337
std::move(result_handler));
326338
}
327339

340+
void DrmManager::ScheduleProcessLicenseRequest() {
341+
std::lock_guard<std::mutex> lock(license_request_state_->mutex);
342+
343+
// Check conditions and deduplicate
344+
if (!main_context_ || !license_request_state_ ||
345+
license_request_state_->disposed ||
346+
license_request_state_->pending_source_id != 0) {
347+
return;
348+
}
349+
350+
auto *state =
351+
new std::shared_ptr<LicenseRequestState>(license_request_state_);
352+
353+
GSource *source = g_idle_source_new();
354+
g_source_set_callback(
355+
source,
356+
[](gpointer data) -> gboolean {
357+
auto state = static_cast<std::shared_ptr<LicenseRequestState> *>(data);
358+
DrmManager *manager = nullptr;
359+
{
360+
std::lock_guard<std::mutex> lock((*state)->mutex);
361+
if (!(*state)->disposed && (*state)->manager) {
362+
(*state)->pending_source_id = 0;
363+
manager = (*state)->manager;
364+
}
365+
}
366+
if (manager) {
367+
manager->ExecuteRequest();
368+
}
369+
return G_SOURCE_REMOVE;
370+
},
371+
state,
372+
[](gpointer data) {
373+
delete static_cast<std::shared_ptr<LicenseRequestState> *>(data);
374+
});
375+
376+
license_request_state_->pending_source_id =
377+
g_source_attach(source, main_context_.get());
378+
g_source_unref(source);
379+
}
380+
328381
void DrmManager::PushLicenseRequestData(DataForLicenseProcess &data) {
329-
std::lock_guard<std::mutex> lock(queue_mutex_);
330-
license_request_queue_.push(data);
331-
ecore_pipe_write(license_request_pipe_, nullptr, 0);
382+
{
383+
std::lock_guard<std::mutex> lock(queue_mutex_);
384+
license_request_queue_.push(data);
385+
}
386+
ScheduleProcessLicenseRequest();
332387
}
333388

334389
void DrmManager::ExecuteRequest() {

packages/video_player_videohole/tizen/src/drm_manager.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
#ifndef FLUTTER_PLUGIN_DRM_MANAGER_H_
66
#define FLUTTER_PLUGIN_DRM_MANAGER_H_
77

8-
#include <Ecore.h>
98
#include <flutter/method_channel.h>
9+
#include <glib.h>
1010

1111
#include <mutex>
1212
#include <queue>
@@ -66,8 +66,26 @@ class DrmManager {
6666
std::string license_server_url_;
6767
bool initialized_ = false;
6868
std::mutex queue_mutex_;
69-
Ecore_Pipe *license_request_pipe_ = nullptr;
7069
std::queue<DataForLicenseProcess> license_request_queue_;
70+
71+
struct GMainContextDeleter {
72+
void operator()(GMainContext *context) const {
73+
g_main_context_unref(context);
74+
}
75+
};
76+
77+
// GLib license request dispatch state
78+
struct LicenseRequestState {
79+
std::mutex mutex;
80+
DrmManager *manager = nullptr;
81+
bool disposed = false;
82+
guint pending_source_id = 0;
83+
};
84+
85+
std::shared_ptr<LicenseRequestState> license_request_state_;
86+
std::unique_ptr<GMainContext, GMainContextDeleter> main_context_;
87+
88+
void ScheduleProcessLicenseRequest();
7189
};
7290

7391
#endif // FLUTTER_PLUGIN_DRM_MANAGER_H_

packages/video_player_videohole/tizen/src/video_player.cc

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,35 @@ VideoPlayer::VideoPlayer(flutter::BinaryMessenger *messenger,
1818
: ecore_wl2_window_proxy_(std::make_unique<EcoreWl2WindowProxy>()),
1919
binary_messenger_(messenger),
2020
flutter_view_(flutter_view) {
21-
sink_event_pipe_ = ecore_pipe_add(
22-
[](void *data, void *buffer, unsigned int nbyte) -> void {
23-
auto *self = static_cast<VideoPlayer *>(data);
24-
self->ExecuteSinkEvents();
25-
},
26-
this);
21+
// Initialize GMainContext and event dispatch state
22+
main_context_ = std::unique_ptr<GMainContext, GMainContextDeleter>(
23+
g_main_context_ref_thread_default());
24+
event_dispatch_state_ = std::make_shared<VideoPlayer::EventDispatchState>();
25+
event_dispatch_state_->player = this;
2726
}
2827

2928
VideoPlayer::~VideoPlayer() {
30-
if (sink_event_pipe_) {
31-
ecore_pipe_del(sink_event_pipe_);
32-
sink_event_pipe_ = nullptr;
29+
// Mark event dispatch state as disposed and cancel pending event source
30+
if (event_dispatch_state_) {
31+
std::lock_guard<std::mutex> lock(event_dispatch_state_->mutex);
32+
event_dispatch_state_->disposed = true;
33+
event_dispatch_state_->player = nullptr;
34+
35+
if (event_dispatch_state_->pending_source_id != 0) {
36+
g_source_remove(event_dispatch_state_->pending_source_id);
37+
event_dispatch_state_->pending_source_id = 0;
38+
}
3339
}
40+
41+
main_context_.reset();
3442
}
3543

3644
void VideoPlayer::ClearUpEventChannel() {
3745
is_initialized_ = false;
38-
event_sink_ = nullptr;
46+
{
47+
std::lock_guard<std::mutex> lock(queue_mutex_);
48+
event_sink_ = nullptr;
49+
}
3950
if (event_channel_) {
4051
event_channel_->SetStreamHandler(nullptr);
4152
}
@@ -90,14 +101,56 @@ void VideoPlayer::ExecuteSinkEvents() {
90101
}
91102
}
92103

93-
void VideoPlayer::PushEvent(flutter::EncodableValue encodable_value) {
94-
std::lock_guard<std::mutex> lock(queue_mutex_);
95-
if (event_sink_ == nullptr) {
96-
LOG_ERROR("[VideoPlayer] event sink is nullptr.");
104+
void VideoPlayer::ScheduleSendPendingEvents() {
105+
std::lock_guard<std::mutex> lock(event_dispatch_state_->mutex);
106+
107+
// Check conditions and deduplicate
108+
if (!main_context_ || !event_dispatch_state_ ||
109+
event_dispatch_state_->disposed ||
110+
event_dispatch_state_->pending_source_id != 0) {
97111
return;
98112
}
99-
encodable_event_queue_.push(encodable_value);
100-
ecore_pipe_write(sink_event_pipe_, nullptr, 0);
113+
114+
auto *state = new std::shared_ptr<EventDispatchState>(event_dispatch_state_);
115+
116+
GSource *source = g_idle_source_new();
117+
g_source_set_callback(
118+
source,
119+
[](gpointer data) -> gboolean {
120+
auto state = static_cast<std::shared_ptr<EventDispatchState> *>(data);
121+
VideoPlayer *player = nullptr;
122+
{
123+
std::lock_guard<std::mutex> lock((*state)->mutex);
124+
if (!(*state)->disposed && (*state)->player) {
125+
(*state)->pending_source_id = 0;
126+
player = (*state)->player;
127+
}
128+
}
129+
if (player) {
130+
player->ExecuteSinkEvents();
131+
}
132+
return G_SOURCE_REMOVE;
133+
},
134+
state,
135+
[](gpointer data) {
136+
delete static_cast<std::shared_ptr<EventDispatchState> *>(data);
137+
});
138+
139+
event_dispatch_state_->pending_source_id =
140+
g_source_attach(source, main_context_.get());
141+
g_source_unref(source);
142+
}
143+
144+
void VideoPlayer::PushEvent(flutter::EncodableValue encodable_value) {
145+
{
146+
std::lock_guard<std::mutex> lock(queue_mutex_);
147+
if (!event_sink_) {
148+
LOG_ERROR("[VideoPlayer] event sink is nullptr.");
149+
return;
150+
}
151+
encodable_event_queue_.push(encodable_value);
152+
}
153+
ScheduleSendPendingEvents();
101154
}
102155

103156
void VideoPlayer::SendInitialized() {
@@ -197,11 +250,15 @@ void VideoPlayer::SendRestored() {
197250

198251
void VideoPlayer::SendError(const std::string &error_code,
199252
const std::string &error_message) {
200-
if (event_sink_) {
253+
{
201254
std::lock_guard<std::mutex> lock(queue_mutex_);
255+
if (!event_sink_) {
256+
LOG_ERROR("[VideoPlayer] event sink is nullptr.");
257+
return;
258+
}
202259
error_event_queue_.push(std::make_pair(error_code, error_message));
203-
ecore_pipe_write(sink_event_pipe_, nullptr, 0);
204260
}
261+
ScheduleSendPendingEvents();
205262
}
206263

207264
void *VideoPlayer::GetWindowHandle() {

packages/video_player_videohole/tizen/src/video_player.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
#ifndef FLUTTER_PLUGIN_VIDEO_PLAYER_H_
66
#define FLUTTER_PLUGIN_VIDEO_PLAYER_H_
77

8-
#include <Ecore.h>
98
#include <flutter/encodable_value.h>
109
#include <flutter/event_channel.h>
1110
#include <flutter_tizen.h>
11+
#include <glib.h>
1212

1313
#include <memory>
1414
#include <mutex>
@@ -79,15 +79,32 @@ class VideoPlayer {
7979
bool is_restored_ = false;
8080

8181
private:
82+
struct GMainContextDeleter {
83+
void operator()(GMainContext *context) const {
84+
g_main_context_unref(context);
85+
}
86+
};
87+
88+
// Event dispatch state structure for lifecycle management
89+
struct EventDispatchState {
90+
std::mutex mutex;
91+
VideoPlayer *player = nullptr;
92+
bool disposed = false;
93+
guint pending_source_id = 0;
94+
};
95+
96+
std::shared_ptr<EventDispatchState> event_dispatch_state_;
97+
std::unique_ptr<GMainContext, GMainContextDeleter> main_context_;
98+
8299
void ExecuteSinkEvents();
100+
void ScheduleSendPendingEvents();
83101
void PushEvent(flutter::EncodableValue encodable_value);
84102

85103
std::queue<flutter::EncodableValue> encodable_event_queue_;
86104
std::queue<std::pair<std::string, std::string>> error_event_queue_;
87105
std::unique_ptr<flutter::EventChannel<flutter::EncodableValue>>
88106
event_channel_;
89107
std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> event_sink_;
90-
Ecore_Pipe *sink_event_pipe_ = nullptr;
91108
};
92109

93110
} // namespace video_player_videohole_tizen

0 commit comments

Comments
 (0)