-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement message queue for native license request
1.Create a new thread for native license request. 2.Spearate channel and native code from drm manager.
- Loading branch information
1 parent
0d363f0
commit 393dc17
Showing
12 changed files
with
401 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
28 changes: 28 additions & 0 deletions
28
packages/video_player_videohole/tizen/src/drm/drm_license_request.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_PLUGIN_DRM_LICENSE_REQUEST_H_ | ||
#define FLUTTER_PLUGIN_DRM_LICENSE_REQUEST_H_ | ||
|
||
#include <functional> | ||
#include <string> | ||
|
||
using OnLicenseRequestDone = std::function<void( | ||
const std::string& session_id, std::vector<uint8_t>& response_data)>; | ||
class DrmLicenseRequest | ||
: public std::enable_shared_from_this<DrmLicenseRequest> { | ||
public: | ||
DrmLicenseRequest(OnLicenseRequestDone on_license_request_done_callback) | ||
: on_license_request_done_callback_(on_license_request_done_callback) {} | ||
virtual ~DrmLicenseRequest(){}; | ||
virtual void RequestLicense(void* session_id, int message_type, void* message, | ||
int message_length) = 0; | ||
virtual void OnLicenseResponse(const std::string& session_id, | ||
std::vector<uint8_t>& response_data) = 0; | ||
|
||
protected: | ||
std::shared_ptr<DrmLicenseRequest> getShared() { return shared_from_this(); } | ||
OnLicenseRequestDone on_license_request_done_callback_ = nullptr; | ||
}; | ||
#endif // FLUTTER_PLUGIN_DRM_LICENSE_REQUEST_H_ |
100 changes: 100 additions & 0 deletions
100
packages/video_player_videohole/tizen/src/drm/drm_license_request_channel.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "drm_license_request_channel.h" | ||
|
||
#include <flutter/method_result_functions.h> | ||
#include <flutter/standard_method_codec.h> | ||
|
||
#include "log.h" | ||
|
||
DrmLicenseRequestChannel::DrmLicenseRequestChannel( | ||
flutter::BinaryMessenger *binary_messenger, | ||
OnLicenseRequestDone on_license_request_done_callback) | ||
: DrmLicenseRequest(on_license_request_done_callback), | ||
request_license_channel_( | ||
std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>( | ||
binary_messenger, "dev.flutter.videoplayer.drm", | ||
&flutter::StandardMethodCodec::GetInstance())) { | ||
license_request_pipe_ = ecore_pipe_add( | ||
[](void *data, void *buffer, unsigned int nbyte) -> void { | ||
auto *self = static_cast<DrmLicenseRequestChannel *>(data); | ||
self->ExecuteRequest(); | ||
}, | ||
this); | ||
} | ||
|
||
void DrmLicenseRequestChannel::RequestLicense(void *session_id, | ||
int message_type, void *message, | ||
int message_length) { | ||
DataForLicenseProcess process_message(session_id, message, message_length); | ||
PushLicenseRequestData(process_message); | ||
} | ||
|
||
void DrmLicenseRequestChannel::ExecuteRequest() { | ||
std::lock_guard<std::mutex> lock(queue_mutex_); | ||
while (!license_request_queue_.empty()) { | ||
DataForLicenseProcess data = license_request_queue_.front(); | ||
RequestLicense(data.session_id, data.message); | ||
license_request_queue_.pop(); | ||
} | ||
} | ||
|
||
void DrmLicenseRequestChannel::PushLicenseRequestData( | ||
DataForLicenseProcess &data) { | ||
std::lock_guard<std::mutex> lock(queue_mutex_); | ||
license_request_queue_.push(data); | ||
ecore_pipe_write(license_request_pipe_, nullptr, 0); | ||
} | ||
|
||
void DrmLicenseRequestChannel::RequestLicense(std::string &session_id, | ||
std::string &message) { | ||
LOG_INFO("[DrmLicenseRequestChannel] Start request license."); | ||
|
||
if (request_license_channel_ == nullptr) { | ||
LOG_ERROR("[DrmLicenseRequestChannel] request license channel is null."); | ||
return; | ||
} | ||
|
||
std::vector<uint8_t> message_vec(message.begin(), message.end()); | ||
flutter::EncodableMap args_map = { | ||
{flutter::EncodableValue("message"), | ||
flutter::EncodableValue(message_vec)}, | ||
}; | ||
auto result_handler = | ||
std::make_unique<flutter::MethodResultFunctions<flutter::EncodableValue>>( | ||
|
||
[session_id, this](const flutter::EncodableValue *success_value) { | ||
std::vector<uint8_t> response; | ||
if (std::holds_alternative<std::vector<uint8_t>>(*success_value)) { | ||
response = std::get<std::vector<uint8_t>>(*success_value); | ||
} else { | ||
LOG_ERROR("[DrmLicenseRequestChannel] Fail to get response."); | ||
return; | ||
} | ||
LOG_INFO("[DrmLicenseRequestChannel] Response length : %d", | ||
response.size()); | ||
OnLicenseResponse(session_id, response); | ||
}, | ||
nullptr, nullptr); | ||
request_license_channel_->InvokeMethod( | ||
"requestLicense", | ||
std::make_unique<flutter::EncodableValue>( | ||
flutter::EncodableValue(args_map)), | ||
std::move(result_handler)); | ||
} | ||
|
||
void DrmLicenseRequestChannel::OnLicenseResponse( | ||
const std::string &session_id, std::vector<uint8_t> &response_data) { | ||
if (on_license_request_done_callback_) { | ||
on_license_request_done_callback_(session_id, response_data); | ||
} | ||
} | ||
|
||
DrmLicenseRequestChannel::~DrmLicenseRequestChannel() { | ||
if (license_request_pipe_) { | ||
ecore_pipe_del(license_request_pipe_); | ||
license_request_pipe_ = nullptr; | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
packages/video_player_videohole/tizen/src/drm/drm_license_request_channel.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_PLUGIN_DRM_LICENSE_REQUEST_CHANNEL_H_ | ||
#define FLUTTER_PLUGIN_DRM_LICENSE_REQUEST_CHANNEL_H_ | ||
|
||
#include <Ecore.h> | ||
#include <flutter/method_channel.h> | ||
|
||
#include <memory> | ||
#include <mutex> | ||
#include <queue> | ||
|
||
#include "drm_license_request.h" | ||
|
||
struct DataForLicenseProcess { | ||
DataForLicenseProcess(void *session_id, void *message, int message_length) | ||
: session_id(static_cast<char *>(session_id)), | ||
message(static_cast<char *>(message), message_length) {} | ||
std::string session_id; | ||
std::string message; | ||
}; | ||
|
||
class DrmLicenseRequestChannel : public DrmLicenseRequest { | ||
public: | ||
explicit DrmLicenseRequestChannel( | ||
flutter::BinaryMessenger *binary_messenger, | ||
OnLicenseRequestDone on_license_request_done_callback); | ||
void RequestLicense(void *session_id, int message_type, void *message, | ||
int message_length) override; | ||
~DrmLicenseRequestChannel(); | ||
void OnLicenseResponse(const std::string& session_id, | ||
std::vector<uint8_t>& response_data) override; | ||
|
||
private: | ||
void ExecuteRequest(); | ||
void PushLicenseRequestData(DataForLicenseProcess &data); | ||
void RequestLicense(std::string &session_id, std::string &message); | ||
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> | ||
request_license_channel_; | ||
std::mutex queue_mutex_; | ||
Ecore_Pipe *license_request_pipe_ = nullptr; | ||
std::queue<DataForLicenseProcess> license_request_queue_; | ||
}; | ||
#endif |
159 changes: 159 additions & 0 deletions
159
packages/video_player_videohole/tizen/src/drm/drm_license_request_native.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "drm_license_request_native.h" | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include "drm_license_helper.h" | ||
#include "log.h" | ||
|
||
constexpr int kMessageQuit = -1; | ||
constexpr int kMessageRequestLicense = 0; | ||
|
||
struct Message { | ||
Eina_Thread_Queue_Msg head; | ||
int event; | ||
std::string license_server_url; | ||
std::string challenge; | ||
std::string session_id; | ||
int drm_type; | ||
}; | ||
|
||
DrmLicenseRequestNative::DrmLicenseRequestNative( | ||
int drm_type, const std::string& license_server_url, | ||
OnLicenseRequestDone on_license_request_done_callback) | ||
: DrmLicenseRequest(on_license_request_done_callback), | ||
drm_type_(drm_type), | ||
license_server_url_(license_server_url) { | ||
license_request_thread_ = ecore_thread_feedback_run(RunLoop, nullptr, nullptr, | ||
nullptr, this, EINA_TRUE); | ||
license_response_pipe_ = ecore_pipe_add( | ||
[](void* data, void* buffer, unsigned int nbyte) -> void { | ||
auto* self = static_cast<DrmLicenseRequestNative*>(data); | ||
self->ExecuteResponse(); | ||
}, | ||
this); | ||
} | ||
|
||
void DrmLicenseRequestNative::RequestLicense(void* session_id, int message_type, | ||
void* message, | ||
int message_length) { | ||
if (!license_request_thread_ || ecore_thread_check(license_request_thread_)) { | ||
LOG_ERROR("Invalid license request thread."); | ||
return; | ||
} | ||
|
||
if (!license_request_queue_) { | ||
LOG_ERROR("Invalid license request thread queue."); | ||
return; | ||
} | ||
|
||
void* ref; | ||
Message* request_message = static_cast<Message*>( | ||
eina_thread_queue_send(license_request_queue_, sizeof(Message), &ref)); | ||
request_message->event = kMessageRequestLicense; | ||
request_message->drm_type = drm_type_; | ||
request_message->challenge = | ||
std::string(static_cast<char*>(message), message_length); | ||
request_message->license_server_url = license_server_url_; | ||
request_message->session_id = std::string(static_cast<char*>(session_id)); | ||
eina_thread_queue_send_done(license_request_queue_, ref); | ||
} | ||
|
||
void DrmLicenseRequestNative::StopMessageQueue() { | ||
if (!license_request_thread_ || ecore_thread_check(license_request_thread_)) { | ||
LOG_ERROR("Invalid license request thread."); | ||
return; | ||
} | ||
|
||
if (!license_request_queue_) { | ||
LOG_ERROR("Invalid license request thread queue."); | ||
return; | ||
} | ||
|
||
void* ref; | ||
Message* message = static_cast<Message*>( | ||
eina_thread_queue_send(license_request_queue_, sizeof(Message), &ref)); | ||
message->event = kMessageQuit; | ||
eina_thread_queue_send_done(license_request_queue_, ref); | ||
} | ||
|
||
void DrmLicenseRequestNative::RunLoop(void* data, Ecore_Thread* thread) { | ||
Eina_Thread_Queue* license_request_queue = eina_thread_queue_new(); | ||
if (!license_request_queue) { | ||
LOG_ERROR("Invalid license request thread queue."); | ||
ecore_thread_cancel(thread); | ||
return; | ||
} | ||
auto* self = static_cast<DrmLicenseRequestNative*>(data); | ||
self->license_request_queue_ = license_request_queue; | ||
std::weak_ptr<DrmLicenseRequest> weak_self = self->getShared(); | ||
while (!ecore_thread_check(thread)) { | ||
void* ref; | ||
Message* message = static_cast<Message*>( | ||
eina_thread_queue_wait(license_request_queue, &ref)); | ||
if (message->event == kMessageQuit) { | ||
eina_thread_queue_wait_done(license_request_queue, ref); | ||
break; | ||
} | ||
std::string license_server_url = message->license_server_url; | ||
std::string challenge = message->challenge; | ||
std::string session_id = message->session_id; | ||
int drm_type = message->drm_type; | ||
eina_thread_queue_wait_done(license_request_queue, ref); | ||
// Get license via the license server. | ||
unsigned char* response_data = nullptr; | ||
unsigned long response_len = 0; | ||
std::vector<uint8_t> response; | ||
DRM_RESULT ret = DrmLicenseHelper::DoTransactionTZ( | ||
license_server_url.c_str(), challenge.c_str(), challenge.size(), | ||
&response_data, &response_len, | ||
static_cast<DrmLicenseHelper::DrmType>(drm_type), nullptr, nullptr); | ||
if (DRM_SUCCESS != ret || nullptr == response_data || 0 == response_len) { | ||
LOG_ERROR("Fail to get respone by license server url."); | ||
continue; | ||
} | ||
LOG_INFO("Response length : %lu", response_len); | ||
if (weak_self.expired()) { | ||
free(response_data); | ||
break; | ||
} | ||
auto response_vec = | ||
std::vector<uint8_t>(response_data, response_data + response_len); | ||
weak_self.lock()->OnLicenseResponse(session_id, response_vec); | ||
free(response_data); | ||
} | ||
if (license_request_queue) { | ||
eina_thread_queue_free(license_request_queue); | ||
} | ||
} | ||
|
||
void DrmLicenseRequestNative::ExecuteResponse() { | ||
std::lock_guard<std::mutex> lock(queue_mutex_); | ||
while (!license_response_queue_.empty()) { | ||
if (on_license_request_done_callback_) { | ||
auto response_data = license_response_queue_.front(); | ||
on_license_request_done_callback_(response_data.first, | ||
response_data.second); | ||
} | ||
license_response_queue_.pop(); | ||
} | ||
} | ||
|
||
void DrmLicenseRequestNative::OnLicenseResponse( | ||
const std::string& session_id, std::vector<uint8_t>& response_data) { | ||
std::lock_guard<std::mutex> lock(queue_mutex_); | ||
license_response_queue_.push(std::make_pair(session_id, response_data)); | ||
ecore_pipe_write(license_response_pipe_, nullptr, 0); | ||
} | ||
|
||
DrmLicenseRequestNative::~DrmLicenseRequestNative() { | ||
StopMessageQueue(); | ||
if (license_request_thread_) { | ||
ecore_thread_cancel(license_request_thread_); | ||
license_request_thread_ = nullptr; | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
packages/video_player_videohole/tizen/src/drm/drm_license_request_native.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2023 Samsung Electronics Co., Ltd. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
#ifndef FLUTTER_PLUGIN_DRM_LICENSE_REQUEST_NATIVE_H_ | ||
#define FLUTTER_PLUGIN_DRM_LICENSE_REQUEST_NATIVE_H_ | ||
|
||
#include <Ecore.h> | ||
|
||
#include <memory> | ||
#include <mutex> | ||
#include <queue> | ||
#include <utility> | ||
|
||
|
||
#include "drm_license_request.h" | ||
|
||
class DrmLicenseRequestNative : public DrmLicenseRequest { | ||
public: | ||
explicit DrmLicenseRequestNative( | ||
int drm_type, const std::string& license_server_url, | ||
OnLicenseRequestDone on_license_request_done_callback); | ||
virtual ~DrmLicenseRequestNative(); | ||
void RequestLicense(void* session_id, int message_type, void* message, | ||
int message_length) override; | ||
protected: | ||
void OnLicenseResponse(const std::string& session_id, std::vector<uint8_t>& response_data) override; | ||
private: | ||
void StopMessageQueue(); | ||
void ExecuteResponse(); | ||
static void RunLoop(void* data, Ecore_Thread* thread); | ||
Ecore_Thread* license_request_thread_ = nullptr; | ||
Eina_Thread_Queue* license_request_queue_ = nullptr; | ||
int drm_type_; | ||
std::string license_server_url_; | ||
std::mutex queue_mutex_; | ||
Ecore_Pipe *license_response_pipe_ = nullptr; | ||
std::queue<std::pair<std::string, std::vector<uint8_t>>> license_response_queue_; | ||
}; | ||
|
||
#endif |
Oops, something went wrong.