From c127487afb8ed75e5225cc29190cd53ec8b49214 Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Tue, 1 Dec 2020 11:30:10 +0200
Subject: [PATCH 01/16] [Bluetooth] Prevent "Wrong listener identifier" errors
for BLE scan
The following app code caused aforementioned errors:
var adapter = tizen.bluetooth.getLEAdapter();
adapter.startScan();
setTimeout(function() {
adapter.stopScan();
}, 10000);
Now, the error is not thrown.
[Validation] tct-bluetooth-tizen-tests: auto: 100% pass rate,
manual Bluetooth04_BLE_wearable suite: 100% pass rate
The code above runs in ChromeDevTools without errors
Change-Id: Id9ec278b4bb1c5ce38d0b3ffb1324498152ab645
Signed-off-by: Pawel Wasowski
---
src/bluetooth/bluetooth_api.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/bluetooth/bluetooth_api.js b/src/bluetooth/bluetooth_api.js
index 984fb77..1869e14 100755
--- a/src/bluetooth/bluetooth_api.js
+++ b/src/bluetooth/bluetooth_api.js
@@ -1514,12 +1514,12 @@ BluetoothLEAdapter.prototype.startScan = function() {
BluetoothLEAdapter.prototype.stopScan = function() {
privUtils_.log('Entered BluetoothLEAdapter.stopScan()');
- _bleScanListener.removeListener();
-
var result = native.callSync('BluetoothLEAdapter_stopScan', {});
if (native.isFailure(result)) {
throw native.getErrorObject(result);
}
+
+ _bleScanListener.removeListener();
};
var _BluetoothAdvertisePacketType = {
--
2.7.4
From b70a4532d7137e3566e1806558524fca343d2e01 Mon Sep 17 00:00:00 2001
From: "Piotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics"
Date: Mon, 4 Jan 2021 12:47:12 +0100
Subject: [PATCH 02/16] [version] 2.46
Change-Id: I1d625296e33677999739d473d445b2c09d1ec4e7
---
packaging/webapi-plugins.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec
index 7f4bc76..7e6ed1d 100644
--- a/packaging/webapi-plugins.spec
+++ b/packaging/webapi-plugins.spec
@@ -10,7 +10,7 @@
%define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions}
Name: webapi-plugins
-Version: 2.45
+Version: 2.46
Release: 0
License: Apache-2.0 and BSD-3-Clause and MIT
Group: Development/Libraries
--
2.7.4
From d5699286b81ab1d0f3d4f4322bc0ed8e797aa769 Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Tue, 29 Dec 2020 16:56:01 +0100
Subject: [PATCH 03/16] [ML][utils] Add native error to PlatformResult
converter
[Verification] The code builds fine
Change-Id: I88234f6474850f554dc617bb0ccc5343b6ed7e93
Signed-off-by: Pawel Wasowski
---
src/ml/ml_utils.cc | 29 +++++++++++++++++++++++++++++
src/ml/ml_utils.h | 11 ++++++++++-
2 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/src/ml/ml_utils.cc b/src/ml/ml_utils.cc
index 44987d8..7babe96 100644
--- a/src/ml/ml_utils.cc
+++ b/src/ml/ml_utils.cc
@@ -24,6 +24,35 @@ namespace extension {
namespace ml {
namespace util {
+PlatformResult ToPlatformResult(int ml_error_code, const std::string& error_message_beginning) {
+ ScopeLogger("ml_error_code: [%d] (%s)", ml_error_code, get_error_message(ml_error_code));
+
+ switch (ml_error_code) {
+ case ML_ERROR_NONE:
+ return PlatformResult{};
+ case ML_ERROR_INVALID_PARAMETER:
+ return PlatformResult{ErrorCode::INVALID_VALUES_ERR,
+ error_message_beginning + ": invalid parameter"};
+ case ML_ERROR_PERMISSION_DENIED:
+ return PlatformResult{ErrorCode::SECURITY_ERR,
+ error_message_beginning + ": permission denied"};
+ case ML_ERROR_TRY_AGAIN:
+ return PlatformResult{ErrorCode::INVALID_STATE_ERR,
+ error_message_beginning + ": invalid state"};
+ case ML_ERROR_TIMED_OUT:
+ return PlatformResult{ErrorCode::TIMEOUT_ERR, error_message_beginning + ": timeout"};
+ case ML_ERROR_NOT_SUPPORTED:
+ return PlatformResult{ErrorCode::NOT_SUPPORTED_ERR,
+ error_message_beginning + ": not supported"};
+ case ML_ERROR_STREAMS_PIPE:
+ case ML_ERROR_UNKNOWN:
+ case ML_ERROR_OUT_OF_MEMORY:
+ default:
+ return PlatformResult{ErrorCode::ABORT_ERR,
+ error_message_beginning + ": an unknown error occurred"};
+ }
+}
+
using namespace common;
} // util
diff --git a/src/ml/ml_utils.h b/src/ml/ml_utils.h
index 3424aad..725c7d9 100644
--- a/src/ml/ml_utils.h
+++ b/src/ml/ml_utils.h
@@ -17,12 +17,21 @@
#ifndef ML_ML_UTILS_H_
#define ML_ML_UTILS_H_
+#include
+
#include "common/picojson.h"
#include "common/platform_result.h"
+using common::PlatformResult;
+using common::ErrorCode;
+
namespace extension {
namespace ml {
-namespace util {} // util
+namespace util {
+
+PlatformResult ToPlatformResult(int ml_error_code, const std::string& error_message);
+
+} // util
} // ml
} // extension
--
2.7.4
From f55afdbe3cad75839a4374b70cca0d762556adbc Mon Sep 17 00:00:00 2001
From: Rafal Walczyna
Date: Tue, 5 Jan 2021 14:27:05 +0100
Subject: [PATCH 04/16] [Common] Moved helper functions to decode/encode
strings/binary to common
[Verification] Built successfully. Metadata and filesystem auto tct 100%.
Change-Id: I751e5cad95f8c7dc907214225f8f27cabbb3e5e7
Signed-off-by: Rafal Walczyna
---
src/common/converter.cc | 37 ++++++++++++++++++++++++++
src/common/converter.h | 3 +++
src/filesystem/filesystem_instance.cc | 50 +++++------------------------------
src/metadata/metadata_instance.cc | 25 +++---------------
4 files changed, 51 insertions(+), 64 deletions(-)
diff --git a/src/common/converter.cc b/src/common/converter.cc
index 48ccd60..ef59df0 100644
--- a/src/common/converter.cc
+++ b/src/common/converter.cc
@@ -43,4 +43,41 @@ long stol(const std::string& str, std::size_t* pos, int base) {
}
}
+/* Write to str buf bytes as if they were UTF-8 codepoints */
+void encode_binary_in_string(const std::vector& buf, std::string& str) {
+ ScopeLogger();
+ str.reserve(str.size() + buf.size());
+
+ for (std::uint8_t byte : buf) {
+ if (byte < 128) {
+ str += byte;
+ continue;
+ }
+ str += 0xC0 | (byte >> 6);
+ str += 0x80 | (byte & 0x3F);
+ }
+}
+
+/* Decode (max 2-byte) UTF-8 characters to buf, throws std::runtime_error */
+void decode_binary_from_string(const std::string& str, std::vector& buf) {
+ ScopeLogger();
+ buf.reserve(buf.size() + str.size());
+
+ const std::uint8_t* it = (std::uint8_t*)str.data();
+ const std::uint8_t* end = it + str.size();
+ while (it != end) {
+ if (*it < 128) {
+ buf.push_back(*it++);
+ continue;
+ }
+ auto b1 = *it++;
+ if (it == end) {
+ throw std::runtime_error("internal error (invalid UTF-8 sequence)");
+ }
+ auto b2 = *it++;
+ unsigned int x = ((b1 & 0x1F) << 6) | (b2 & 0x3F);
+ buf.push_back(x);
+ }
+}
+
} // webapi
diff --git a/src/common/converter.h b/src/common/converter.h
index 35b9e1f..5ba7a6b 100644
--- a/src/common/converter.h
+++ b/src/common/converter.h
@@ -59,6 +59,9 @@ const T &FromJson(const picojson::object &in, const char *name, Names... names)
return FromJson(v.get(), names...);
}
+void encode_binary_in_string(const std::vector& buf, std::string& str);
+void decode_binary_from_string(const std::string& str, std::vector& buf);
+
} // common
#endif // COMMON_CONVERTER_H_
diff --git a/src/filesystem/filesystem_instance.cc b/src/filesystem/filesystem_instance.cc
index da8b0ab..010a202 100644
--- a/src/filesystem/filesystem_instance.cc
+++ b/src/filesystem/filesystem_instance.cc
@@ -23,6 +23,7 @@
#include
#include
+#include "common/converter.h"
#include "common/logger.h"
#include "common/picojson.h"
#include "common/platform_exception.h"
@@ -235,48 +236,11 @@ void FilesystemInstance::FileRename(const picojson::value& args, picojson::objec
std::bind(&FilesystemManager::Rename, &fsm, oldPath, newPath, onSuccess, onError));
}
-/* Write to str buf bytes as if they were UTF-8 codepoints */
-static void encode_binary_in_string(const std::vector& buf, std::string& str) {
- ScopeLogger();
- str.reserve(str.size() + buf.size());
-
- for (std::uint8_t byte : buf) {
- if (byte < 128) {
- str += byte;
- continue;
- }
- str += 0xC0 | (byte >> 6);
- str += 0x80 | (byte & 0x3F);
- }
-}
-
-/* Decode (max 2-byte) UTF-8 characters to buf, throws std::runtime_error */
-static void decode_binary_from_string(const std::string& str, std::vector& buf) {
- ScopeLogger();
- buf.reserve(buf.size() + str.size());
-
- const std::uint8_t* it = (std::uint8_t*)str.data();
- const std::uint8_t* end = it + str.size();
- while (it != end) {
- if (*it < 128) {
- buf.push_back(*it++);
- continue;
- }
- auto b1 = *it++;
- if (it == end) {
- throw std::runtime_error("internal error (invalid UTF-8 sequence)");
- }
- auto b2 = *it++;
- unsigned int x = ((b1 & 0x1F) << 6) | (b2 & 0x3F);
- buf.push_back(x);
- }
-}
-
namespace latin1 {
-static auto to_utf8 = &encode_binary_in_string;
+static auto to_utf8 = &common::encode_binary_in_string;
/* It does not check if UTF-8 values are representable by ISO-8859-1. Make proper checks and
* substitute invalid characters in JavaScript before passing through crosswalk */
-static auto from_utf8 = &decode_binary_from_string;
+static auto from_utf8 = &common::decode_binary_from_string;
}
static constexpr std::size_t NPOS = (std::size_t)(-1);
@@ -727,7 +691,7 @@ void FilesystemInstance::FileReadBytes(const picojson::value& args, picojson::ob
std::vector out_data = read_file(location, offset, length);
out["result"] = picojson::value(picojson::string_type, true);
- encode_binary_in_string(out_data, out["result"].get());
+ common::encode_binary_in_string(out_data, out["result"].get());
ReportSuccess(out);
} catch (std::runtime_error& e) {
LoggerE("Cannot read file %s, cause: %s", location.c_str(), e.what());
@@ -796,7 +760,7 @@ void FilesystemInstance::FileWriteBytes(const picojson::value& args, picojson::o
try {
std::vector data;
- decode_binary_from_string(str, data);
+ common::decode_binary_from_string(str, data);
write_file(data.data(), data.size(), location, offset, mode);
} catch (std::runtime_error& e) {
LoggerE("Cannot write to %s, cause: %s", location.c_str(), e.what());
@@ -2142,7 +2106,7 @@ void FilesystemInstance::FileHandleReadData(const picojson::value& args, picojso
try {
std::vector data = read_file(handle->file_handle, size);
out["result"] = picojson::value(picojson::string_type, true);
- encode_binary_in_string(data, out["result"].get());
+ common::encode_binary_in_string(data, out["result"].get());
} catch (std::runtime_error& e) {
LoggerE("Cannot read, cause: %s", e.what());
LogAndReportError(IOException(e.what()), out);
@@ -2188,7 +2152,7 @@ void FilesystemInstance::FileHandleWriteData(const picojson::value& args, picojs
auto logic = [str, handle](decltype(out) out) {
try {
std::vector bytes;
- decode_binary_from_string(str, bytes);
+ common::decode_binary_from_string(str, bytes);
write_file(bytes.data(), bytes.size(), handle->file_handle);
} catch (std::runtime_error& e) {
LogAndReportError(IOException(e.what()), out);
diff --git a/src/metadata/metadata_instance.cc b/src/metadata/metadata_instance.cc
index eb8c02e..36d6fdf 100644
--- a/src/metadata/metadata_instance.cc
+++ b/src/metadata/metadata_instance.cc
@@ -16,6 +16,7 @@
#include "metadata/metadata_instance.h"
+#include "common/converter.h"
#include "common/logger.h"
#include "common/picojson.h"
#include "common/platform_exception.h"
@@ -114,24 +115,6 @@ void MetadataInstance::MetadataFileHandleGet(const picojson::value& args, picojs
ReportSuccess(picojson::value(value), out);
}
-// TODO copied from filesystem
-// move to common??
-/* Write to str buf bytes as if they were UTF-8 codepoints */
-static void encode_binary_in_string(const std::vector& buf, std::string& str) {
- ScopeLogger();
- str.reserve(str.size() + buf.size());
-
- for (std::uint8_t byte : buf) {
- if (byte < 128) {
- str += byte;
- continue;
- }
- str += 0xC0 | (byte >> 6);
- str += 0x80 | (byte & 0x3F);
- }
-}
-///////////////////////////////////
-
void MetadataInstance::MetadataFileHandleGetArtwork(const picojson::value& args,
picojson::object& out) {
ScopeLogger();
@@ -165,7 +148,7 @@ void MetadataInstance::MetadataFileHandleGetArtwork(const picojson::value& args,
picojson::object& result_artwork_obj = result_artwork.get();
result_artwork_obj["encodedData"] = picojson::value(picojson::string_type, true);
- encode_binary_in_string(data, result_artwork_obj["encodedData"].get());
+ common::encode_binary_in_string(data, result_artwork_obj["encodedData"].get());
result_artwork_obj["mimeType"] = picojson::value(mime_type);
ReportSuccess(result_artwork, out);
@@ -201,7 +184,7 @@ void MetadataInstance::MetadataFileHandleGetThumbnailFrame(const picojson::value
}
std::string result_artwork;
- encode_binary_in_string(data, result_artwork);
+ common::encode_binary_in_string(data, result_artwork);
ReportSuccess(picojson::value(result_artwork), out);
}
@@ -238,7 +221,7 @@ void MetadataInstance::MetadataFileHandleGetFrameAtTime(const picojson::value& a
}
std::string result_frame;
- encode_binary_in_string(data, result_frame);
+ common::encode_binary_in_string(data, result_frame);
ReportSuccess(picojson::value(result_frame), out);
}
--
2.7.4
From d0bf72305dab751448a61b8179fa1aa7e6cacb4a Mon Sep 17 00:00:00 2001
From: Arkadiusz Pietraszek
Date: Thu, 7 Jan 2021 20:32:28 +0100
Subject: [PATCH 05/16] [Download][TDAF-1353] Exception fix for 'start'
function
`start` function was returning unknown error exception instead of
unsupported error in case when networkType in DownloadRequest wasn't
supported by the device.
Additionally fix enables null values to be used (in accordance with the documentation).
[Verification] Code builds without errors. TCT suites deprecated, download and systeminfo pass rate: 100%.
Tested in developer console on devices with telephony set to true and false.
Below code was used with all network types, as well as invalid values.
```
var downloadRequest = new tizen.DownloadRequest(
"http://download.tizen.org/tct/2_1/webapi-tizen-download-test-image-lq.png",
null, null, "CELLULAR", null);
tizen.download.start(downloadRequest);
```
Change-Id: I4f2866a07019f129c852024970783b110ef11abc
Signed-off-by: Arkadiusz Pietraszek
---
src/download/download_api.js | 23 ++++++++++++++++++++---
src/download/download_instance.cc | 11 ++++++-----
2 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/src/download/download_api.js b/src/download/download_api.js
index 5ea0cf7..826ab87 100755
--- a/src/download/download_api.js
+++ b/src/download/download_api.js
@@ -90,12 +90,29 @@ tizen.DownloadRequest = function(url, destination, fileName, networkType, httpHe
validator_.isConstructorCall(this, tizen.DownloadRequest);
var url_ = converter_.toString(url);
- var destination_ = destination === undefined ? '' : converter_.toString(destination);
- var fileName_ = fileName === undefined ? '' : converter_.toString(fileName);
+ var destination_;
+
+ if (undefined === destination || null === destination) {
+ destination_ = '';
+ } else {
+ destination_ = converter_.toString(destination);
+ }
+
+ var fileName_;
+
+ if (undefined === fileName || null === fileName) {
+ fileName_ = '';
+ } else {
+ fileName_ = converter_.toString(fileName);
+ }
var networkType_;
- if (networkType === undefined || !(networkType in DownloadNetworkType)) {
+ if (
+ undefined === networkType ||
+ null === networkType ||
+ !(networkType in DownloadNetworkType)
+ ) {
networkType_ = 'ALL';
} else {
networkType_ = networkType;
diff --git a/src/download/download_instance.cc b/src/download/download_instance.cc
index 49905f5..3a3b6c3 100644
--- a/src/download/download_instance.cc
+++ b/src/download/download_instance.cc
@@ -492,6 +492,8 @@ common::PlatformResult DownloadInstance::CheckNetworkConnection(const std::strin
bool& network_support,
bool& network_available,
DownloadInfoPtr di_ptr) {
+ ScopeLogger("network_type: %s", network_type.c_str());
+
connection_h connection = nullptr;
int ret = connection_create(&connection);
CHECK_CONNECTION_ERROR(ret)
@@ -503,11 +505,6 @@ common::PlatformResult DownloadInstance::CheckNetworkConnection(const std::strin
ret = connection_get_type(connection, &connection_type);
CHECK_CONNECTION_ERROR(ret)
- if (CONNECTION_TYPE_DISCONNECTED == connection_type) {
- return LogAndCreateResult(common::ErrorCode::UNKNOWN_ERR, "Connection problem occurred",
- ("Connection type is disconnected"));
- }
-
if ("CELLULAR" == network_type) {
// check if connection type is supported
bool cell_support = false;
@@ -549,6 +546,10 @@ common::PlatformResult DownloadInstance::CheckNetworkConnection(const std::strin
"The input parameter contains an invalid network type.",
("The input parameter contains an invalid network type: %s", network_type.c_str()));
}
+ if (CONNECTION_TYPE_DISCONNECTED == connection_type) {
+ return LogAndCreateResult(common::ErrorCode::UNKNOWN_ERR, "Connection problem occurred",
+ ("Connection type is disconnected"));
+ }
return common::PlatformResult(common::ErrorCode::NO_ERROR);
}
#undef CHECK_CONNECTION_ERROR
--
2.7.4
From 30e2dbdb931f462485663079e656c3e0eb8517f6 Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Fri, 8 Jan 2021 12:06:03 +0100
Subject: [PATCH 06/16] [ML][pipeline] Add placeholders for implementation
ACR: TWDAPI-274
This commit adds placeholders for implementation of PipelineManager and
Pipeline to avoid merge conflicts of changes done by different
committers.
[Verification] Code compiles
Change-Id: Id4a2b33943e390526929bb5c2dba42cd55d7ad12
Signed-off-by: Pawel Wasowski
---
src/ml/js/ml_pipeline.js | 76 ++++++++++++++++++++++++++++++++++++++
src/ml/ml_instance.cc | 74 +++++++++++++++++++++++++++++++++++++
src/ml/ml_instance.h | 76 ++++++++++++++++++++++++++++++++++++++
src/ml/ml_pipeline.cc | 77 +++++++++++++++++++++++++++++++++++++-
src/ml/ml_pipeline.h | 86 +++++++++++++++++++++++++++++++++++++++++--
src/ml/ml_pipeline_manager.cc | 78 ++++++++++++++++++++++++++++++++++++++-
src/ml/ml_pipeline_manager.h | 86 +++++++++++++++++++++++++++++++++++++++++--
7 files changed, 545 insertions(+), 8 deletions(-)
diff --git a/src/ml/js/ml_pipeline.js b/src/ml/js/ml_pipeline.js
index 1aa4728..fdd1a2d 100755
--- a/src/ml/js/ml_pipeline.js
+++ b/src/ml/js/ml_pipeline.js
@@ -14,6 +14,82 @@
* limitations under the License.
*/
+//PipelineManager::createPipeline() begin
+
+//PipelineManager::createPipeline() end
+
+//Pipeline::state begin
+
+//Pipeline::state end
+
+//Pipeline::start() begin
+
+//Pipeline::start() end
+
+//Pipeline::stop() begin
+
+//Pipeline::stop() end
+
+//Pipeline::dispose() begin
+
+//Pipeline::dispose() end
+
+//Pipeline::getNodeInfo() begin
+
+//Pipeline::getNodeInfo() end
+
+//Pipeline::getSource() begin
+
+//Pipeline::getSource() end
+
+//Pipeline::getSwitch() begin
+
+//Pipeline::getSwitch() end
+
+//Pipeline::getValve() begin
+
+//Pipeline::getValve() end
+
+//Pipeline::registerSinkCallback() begin
+
+//Pipeline::registerSinkCallback() end
+
+//Pipeline::unregisterSinkCallback() begin
+
+//Pipeline::unregisterSinkCallback() end
+
+//Pipeline::registerCustomFilter() begin
+
+//Pipeline::registerCustomFilter() end
+
+//Pipeline::unregisterCustomFilter() begin
+
+//Pipeline::unregisterCustomFilter() end
+
+//NodeInfo::getProperty() begin
+
+//NodeInfo::getProperty() end
+
+//NodeInfo::setProperty() begin
+
+//NodeInfo::setProperty() end
+
+//Source::inputTensorsInfo begin
+
+//Source::inputTensorsInfo end
+
+//Source::inputData() begin
+
+//Source::inputData() end
+
+//Switch::getPadList() begin
+
+//Switch::getPadList() end
+
+//Valve::setOpen() begin
+
+//Valve::setOpen() end
+
var MachineLearningPipeline = function() {};
// ML Pipeline API
diff --git a/src/ml/ml_instance.cc b/src/ml/ml_instance.cc
index ec1e267..5706267 100644
--- a/src/ml/ml_instance.cc
+++ b/src/ml/ml_instance.cc
@@ -58,7 +58,81 @@ MlInstance::~MlInstance() {
// Single API end
// Pipeline API begin
+// PipelineManager::createPipeline() begin
+// PipelineManager::createPipeline() end
+
+// Pipeline::state begin
+
+// Pipeline::state end
+
+// Pipeline::start() begin
+
+// Pipeline::start() end
+
+// Pipeline::stop() begin
+
+// Pipeline::stop() end
+
+// Pipeline::dispose() begin
+
+// Pipeline::dispose() end
+
+// Pipeline::getNodeInfo() begin
+
+// Pipeline::getNodeInfo() end
+
+// Pipeline::getSource() begin
+
+// Pipeline::getSource() end
+
+// Pipeline::getSwitch() begin
+
+// Pipeline::getSwitch() end
+
+// Pipeline::getValve() begin
+
+// Pipeline::getValve() end
+
+// Pipeline::registerSinkCallback() begin
+
+// Pipeline::registerSinkCallback() end
+
+// Pipeline::unregisterSinkCallback() begin
+
+// Pipeline::unregisterSinkCallback() end
+
+// Pipeline::registerCustomFilter() begin
+
+// Pipeline::registerCustomFilter() end
+
+// Pipeline::unregisterCustomFilter() begin
+
+// Pipeline::unregisterCustomFilter() end
+
+// NodeInfo::getProperty() begin
+
+// NodeInfo::getProperty() end
+
+// NodeInfo::setProperty() begin
+
+// NodeInfo::setProperty() end
+
+// Source::inputTensorsInfo begin
+
+// Source::inputTensorsInfo end
+
+// Source::inputData() begin
+
+// Source::inputData() end
+
+// Switch::getPadList() begin
+
+// Switch::getPadList() end
+
+// Valve::setOpen() begin
+
+// Valve::setOpen() end
// Pipeline API end
} // namespace ml
diff --git a/src/ml/ml_instance.h b/src/ml/ml_instance.h
index fc179d2..e7a1998 100644
--- a/src/ml/ml_instance.h
+++ b/src/ml/ml_instance.h
@@ -41,6 +41,82 @@ class MlInstance : public common::ParsedInstance {
// Pipeline API begin
+ // PipelineManager::createPipeline() begin
+
+ // PipelineManager::createPipeline() end
+
+ // Pipeline::state begin
+
+ // Pipeline::state end
+
+ // Pipeline::start() begin
+
+ // Pipeline::start() end
+
+ // Pipeline::stop() begin
+
+ // Pipeline::stop() end
+
+ // Pipeline::dispose() begin
+
+ // Pipeline::dispose() end
+
+ // Pipeline::getNodeInfo() begin
+
+ // Pipeline::getNodeInfo() end
+
+ // Pipeline::getSource() begin
+
+ // Pipeline::getSource() end
+
+ // Pipeline::getSwitch() begin
+
+ // Pipeline::getSwitch() end
+
+ // Pipeline::getValve() begin
+
+ // Pipeline::getValve() end
+
+ // Pipeline::registerSinkCallback() begin
+
+ // Pipeline::registerSinkCallback() end
+
+ // Pipeline::unregisterSinkCallback() begin
+
+ // Pipeline::unregisterSinkCallback() end
+
+ // Pipeline::registerCustomFilter() begin
+
+ // Pipeline::registerCustomFilter() end
+
+ // Pipeline::unregisterCustomFilter() begin
+
+ // Pipeline::unregisterCustomFilter() end
+
+ // NodeInfo::getProperty() begin
+
+ // NodeInfo::getProperty() end
+
+ // NodeInfo::setProperty() begin
+
+ // NodeInfo::setProperty() end
+
+ // Source::inputTensorsInfo begin
+
+ // Source::inputTensorsInfo end
+
+ // Source::inputData() begin
+
+ // Source::inputData() end
+
+ // Switch::getPadList() begin
+
+ // Switch::getPadList() end
+
+ // Valve::setOpen() begin
+
+ // Valve::setOpen() end
+
// Pipeline API end
};
diff --git a/src/ml/ml_pipeline.cc b/src/ml/ml_pipeline.cc
index f931b81..60a0108 100644
--- a/src/ml/ml_pipeline.cc
+++ b/src/ml/ml_pipeline.cc
@@ -13,5 +13,80 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "ml_pipeline.h"
-#include "ml_pipeline.h"
\ No newline at end of file
+// PipelineManager::createPipeline() begin
+
+// PipelineManager::createPipeline() end
+
+// Pipeline::state begin
+
+// Pipeline::state end
+
+// Pipeline::start() begin
+
+// Pipeline::start() end
+
+// Pipeline::stop() begin
+
+// Pipeline::stop() end
+
+// Pipeline::dispose() begin
+
+// Pipeline::dispose() end
+
+// Pipeline::getNodeInfo() begin
+
+// Pipeline::getNodeInfo() end
+
+// Pipeline::getSource() begin
+
+// Pipeline::getSource() end
+
+// Pipeline::getSwitch() begin
+
+// Pipeline::getSwitch() end
+
+// Pipeline::getValve() begin
+
+// Pipeline::getValve() end
+
+// Pipeline::registerSinkCallback() begin
+
+// Pipeline::registerSinkCallback() end
+
+// Pipeline::unregisterSinkCallback() begin
+
+// Pipeline::unregisterSinkCallback() end
+
+// Pipeline::registerCustomFilter() begin
+
+// Pipeline::registerCustomFilter() end
+
+// Pipeline::unregisterCustomFilter() begin
+
+// Pipeline::unregisterCustomFilter() end
+
+// NodeInfo::getProperty() begin
+
+// NodeInfo::getProperty() end
+
+// NodeInfo::setProperty() begin
+
+// NodeInfo::setProperty() end
+
+// Source::inputTensorsInfo begin
+
+// Source::inputTensorsInfo end
+
+// Source::inputData() begin
+
+// Source::inputData() end
+
+// Switch::getPadList() begin
+
+// Switch::getPadList() end
+
+// Valve::setOpen() begin
+
+// Valve::setOpen() end
\ No newline at end of file
diff --git a/src/ml/ml_pipeline.h b/src/ml/ml_pipeline.h
index e277044..029269e 100644
--- a/src/ml/ml_pipeline.h
+++ b/src/ml/ml_pipeline.h
@@ -23,7 +23,87 @@
namespace extension {
namespace ml {
-} // namespace ml
-} // namespace extension
+class Pipeline {
+ public:
+ // PipelineManager::createPipeline() begin
-#endif // ML_ML_PIPELINE_H_
\ No newline at end of file
+ // PipelineManager::createPipeline() end
+
+ // Pipeline::state begin
+
+ // Pipeline::state end
+
+ // Pipeline::start() begin
+
+ // Pipeline::start() end
+
+ // Pipeline::stop() begin
+
+ // Pipeline::stop() end
+
+ // Pipeline::dispose() begin
+
+ // Pipeline::dispose() end
+
+ // Pipeline::getNodeInfo() begin
+
+ // Pipeline::getNodeInfo() end
+
+ // Pipeline::getSource() begin
+
+ // Pipeline::getSource() end
+
+ // Pipeline::getSwitch() begin
+
+ // Pipeline::getSwitch() end
+
+ // Pipeline::getValve() begin
+
+ // Pipeline::getValve() end
+
+ // Pipeline::registerSinkCallback() begin
+
+ // Pipeline::registerSinkCallback() end
+
+ // Pipeline::unregisterSinkCallback() begin
+
+ // Pipeline::unregisterSinkCallback() end
+
+ // Pipeline::registerCustomFilter() begin
+
+ // Pipeline::registerCustomFilter() end
+
+ // Pipeline::unregisterCustomFilter() begin
+
+ // Pipeline::unregisterCustomFilter() end
+
+ // NodeInfo::getProperty() begin
+
+ // NodeInfo::getProperty() end
+
+ // NodeInfo::setProperty() begin
+
+ // NodeInfo::setProperty() end
+
+ // Source::inputTensorsInfo begin
+
+ // Source::inputTensorsInfo end
+
+ // Source::inputData() begin
+
+ // Source::inputData() end
+
+ // Switch::getPadList() begin
+
+ // Switch::getPadList() end
+
+ // Valve::setOpen() begin
+
+ // Valve::setOpen() end
+ private:
+};
+
+} // namespace ml
+} // namespace extension
+
+#endif // ML_ML_PIPELINE_H_
\ No newline at end of file
diff --git a/src/ml/ml_pipeline_manager.cc b/src/ml/ml_pipeline_manager.cc
index dcba44c..b33a771 100644
--- a/src/ml/ml_pipeline_manager.cc
+++ b/src/ml/ml_pipeline_manager.cc
@@ -14,4 +14,80 @@
* limitations under the License.
*/
-#include "ml_pipeline_manager.h"
\ No newline at end of file
+#include "ml_pipeline_manager.h"
+
+// PipelineManager::createPipeline() begin
+
+// PipelineManager::createPipeline() end
+
+// Pipeline::state begin
+
+// Pipeline::state end
+
+// Pipeline::start() begin
+
+// Pipeline::start() end
+
+// Pipeline::stop() begin
+
+// Pipeline::stop() end
+
+// Pipeline::dispose() begin
+
+// Pipeline::dispose() end
+
+// Pipeline::getNodeInfo() begin
+
+// Pipeline::getNodeInfo() end
+
+// Pipeline::getSource() begin
+
+// Pipeline::getSource() end
+
+// Pipeline::getSwitch() begin
+
+// Pipeline::getSwitch() end
+
+// Pipeline::getValve() begin
+
+// Pipeline::getValve() end
+
+// Pipeline::registerSinkCallback() begin
+
+// Pipeline::registerSinkCallback() end
+
+// Pipeline::unregisterSinkCallback() begin
+
+// Pipeline::unregisterSinkCallback() end
+
+// Pipeline::registerCustomFilter() begin
+
+// Pipeline::registerCustomFilter() end
+
+// Pipeline::unregisterCustomFilter() begin
+
+// Pipeline::unregisterCustomFilter() end
+
+// NodeInfo::getProperty() begin
+
+// NodeInfo::getProperty() end
+
+// NodeInfo::setProperty() begin
+
+// NodeInfo::setProperty() end
+
+// Source::inputTensorsInfo begin
+
+// Source::inputTensorsInfo end
+
+// Source::inputData() begin
+
+// Source::inputData() end
+
+// Switch::getPadList() begin
+
+// Switch::getPadList() end
+
+// Valve::setOpen() begin
+
+// Valve::setOpen() end
\ No newline at end of file
diff --git a/src/ml/ml_pipeline_manager.h b/src/ml/ml_pipeline_manager.h
index c068daf..68891e3 100644
--- a/src/ml/ml_pipeline_manager.h
+++ b/src/ml/ml_pipeline_manager.h
@@ -23,7 +23,87 @@
namespace extension {
namespace ml {
-} // namespace ml
-} // namespace extension
+class PipelineManager {
+ public:
+ // PipelineManager::createPipeline() begin
-#endif // ML_ML_PIPELINE_MANAGER_H_
\ No newline at end of file
+ // PipelineManager::createPipeline() end
+
+ // Pipeline::state begin
+
+ // Pipeline::state end
+
+ // Pipeline::start() begin
+
+ // Pipeline::start() end
+
+ // Pipeline::stop() begin
+
+ // Pipeline::stop() end
+
+ // Pipeline::dispose() begin
+
+ // Pipeline::dispose() end
+
+ // Pipeline::getNodeInfo() begin
+
+ // Pipeline::getNodeInfo() end
+
+ // Pipeline::getSource() begin
+
+ // Pipeline::getSource() end
+
+ // Pipeline::getSwitch() begin
+
+ // Pipeline::getSwitch() end
+
+ // Pipeline::getValve() begin
+
+ // Pipeline::getValve() end
+
+ // Pipeline::registerSinkCallback() begin
+
+ // Pipeline::registerSinkCallback() end
+
+ // Pipeline::unregisterSinkCallback() begin
+
+ // Pipeline::unregisterSinkCallback() end
+
+ // Pipeline::registerCustomFilter() begin
+
+ // Pipeline::registerCustomFilter() end
+
+ // Pipeline::unregisterCustomFilter() begin
+
+ // Pipeline::unregisterCustomFilter() end
+
+ // NodeInfo::getProperty() begin
+
+ // NodeInfo::getProperty() end
+
+ // NodeInfo::setProperty() begin
+
+ // NodeInfo::setProperty() end
+
+ // Source::inputTensorsInfo begin
+
+ // Source::inputTensorsInfo end
+
+ // Source::inputData() begin
+
+ // Source::inputData() end
+
+ // Switch::getPadList() begin
+
+ // Switch::getPadList() end
+
+ // Valve::setOpen() begin
+
+ // Valve::setOpen() end
+ private:
+};
+
+} // namespace ml
+} // namespace extension
+
+#endif // ML_ML_PIPELINE_MANAGER_H_
\ No newline at end of file
--
2.7.4
From cc19a7e5900e145c01e9b7ba21c2f2bb76ec42f6 Mon Sep 17 00:00:00 2001
From: Pawel Wasowski
Date: Thu, 24 Dec 2020 11:36:26 +0100
Subject: [PATCH 07/16] [ML][Pipeline] Add Pipeline and PipelineManager
ACR: TWDAPI-274
[Verification] createPipeline() tested in Chrome
DevTools with the snippet below works fine
var pipeline = tizen.ml.pipeline.createPipeline(
'videoteststrc ! tizenwlsink',
function(state) {
console.log(state);
})
//a moment later:
// READY
// PAUSED
tizen.ml.createPipeline()
// WebAPIException: InvalidValuesError
Change-Id: I68beaebf7e248b61bba9dc06ce6124c187c45fae
Signed-off-by: Pawel Wasowski
---
src/ml/js/ml_common.js | 3 ++
src/ml/js/ml_pipeline.js | 96 +++++++++++++++++++++++++++++++--
src/ml/ml_instance.cc | 63 +++++++++++++++++++---
src/ml/ml_instance.h | 5 +-
src/ml/ml_pipeline.cc | 120 +++++++++++++++++++++++++++++++++++++++++-
src/ml/ml_pipeline.h | 32 ++++++++++-
src/ml/ml_pipeline_manager.cc | 44 +++++++++++++++-
src/ml/ml_pipeline_manager.h | 18 ++++++-
8 files changed, 364 insertions(+), 17 deletions(-)
diff --git a/src/ml/js/ml_common.js b/src/ml/js/ml_common.js
index 21819da..c8bc981 100755
--- a/src/ml/js/ml_common.js
+++ b/src/ml/js/ml_common.js
@@ -17,6 +17,9 @@
var privUtils_ = xwalk.utils;
var validator_ = privUtils_.validator;
var types_ = validator_.Types;
+var native_ = new xwalk.utils.NativeManager(extension);
+
+var AbortError = new WebAPIException('AbortError', 'An unknown error occurred');
// TensorRawData
diff --git a/src/ml/js/ml_pipeline.js b/src/ml/js/ml_pipeline.js
index fdd1a2d..f50b97a 100755
--- a/src/ml/js/ml_pipeline.js
+++ b/src/ml/js/ml_pipeline.js
@@ -14,12 +14,101 @@
* limitations under the License.
*/
-//PipelineManager::createPipeline() begin
+var kPipelineStateChangeListenerNamePrefix = 'MLPipelineStateChangeListener';
+//PipelineManager::createPipeline() begin
+var nextPipelineId = 1;
+function NextPipelineId() {
+ return nextPipelineId++;
+}
+
+var ValidPipelineManagerCreatePipelineExceptions = [
+ 'InvalidValuesError',
+ 'TypeMismatchError',
+ 'NotSupportedError',
+ 'SecurityError',
+ 'AbortError'
+];
+
+var CreatePipeline = function() {
+ privUtils_.log('Entered PipelineManager.createPipeline()');
+ var args = validator_.validateArgs(arguments, [
+ {
+ name: 'definition',
+ type: validator_.Types.STRING
+ },
+ {
+ name: 'listener',
+ type: validator_.Types.FUNCTION,
+ optional: true,
+ nullable: true
+ }
+ ]);
+
+ if (!args.has.definition) {
+ throw new WebAPIException(
+ WebAPIException.INVALID_VALUES_ERR,
+ 'Invalid parameter: pipeline definition is mandatory'
+ );
+ }
+
+ var pipeline = new Pipeline(NextPipelineId());
+ var nativeArgs = {
+ id: pipeline._id,
+ definition: args.definition
+ };
+
+ if (args.listener) {
+ nativeArgs.listenerName = kPipelineStateChangeListenerNamePrefix + pipeline._id;
+ var stateChangeListener = function(stateObject) {
+ args.listener(stateObject.state);
+ };
+ native_.addListener(nativeArgs.listenerName, stateChangeListener);
+ }
+
+ var result = native_.callSync('MLPipelineManagerCreatePipeline', nativeArgs);
+
+ if (native_.isFailure(result)) {
+ if (nativeArgs.listenerName) {
+ native_.removeListener(nativeArgs.listenerName);
+ }
+ throw native_.getErrorObjectAndValidate(
+ result,
+ ValidPipelineManagerCreatePipelineExceptions,
+ AbortError
+ );
+ }
+
+ return pipeline;
+};
//PipelineManager::createPipeline() end
//Pipeline::state begin
-
+var ValidPipelineStateExceptions = ['NotSupportedError', 'AbortError'];
+var Pipeline = function(id) {
+ Object.defineProperties(this, {
+ state: {
+ enumerable: true,
+ get: function() {
+ var result = native_.callSync('MLPipelineGetState', {
+ id: id
+ });
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObjectAndValidate(
+ result,
+ ValidPipelineStateExceptions,
+ AbortError
+ );
+ }
+
+ return result.state;
+ }
+ },
+ _id: {
+ value: id
+ }
+ });
+};
//Pipeline::state end
//Pipeline::start() begin
@@ -89,7 +178,8 @@
//Valve::setOpen() begin
//Valve::setOpen() end
-
var MachineLearningPipeline = function() {};
+MachineLearningPipeline.prototype.createPipeline = CreatePipeline;
+
// ML Pipeline API
diff --git a/src/ml/ml_instance.cc b/src/ml/ml_instance.cc
index 5706267..5d2f242 100644
--- a/src/ml/ml_instance.cc
+++ b/src/ml/ml_instance.cc
@@ -24,21 +24,22 @@ namespace ml {
using namespace common;
-MlInstance::MlInstance() {
+MlInstance::MlInstance() : pipeline_manager_{this} {
ScopeLogger();
using namespace std::placeholders;
#define REGISTER_METHOD(M) RegisterSyncHandler(#M, std::bind(&MlInstance::M, this, _1, _2))
-// Common ML API begin
+ // Common ML API begin
-// Common ML API end
+ // Common ML API end
-// Single API begin
+ // Single API begin
-// Single API end
+ // Single API end
-// Pipeline API begin
+ // Pipeline API begin
+ REGISTER_METHOD(MLPipelineManagerCreatePipeline);
// Pipeline API end
@@ -58,8 +59,57 @@ MlInstance::~MlInstance() {
// Single API end
// Pipeline API begin
+
+namespace {
+
+const std::string kId = "id";
+const std::string kDefinition = "definition";
+const std::string kPipelineStateChangeListenerName = "listenerName";
+
+} // namespace
+
// PipelineManager::createPipeline() begin
+namespace {
+
+bool CreatePipelineArgumentsAreInvalid(const picojson::value& args) {
+ ScopeLogger();
+ auto arguments_valid = args.get(kId).is();
+ arguments_valid &= args.get(kDefinition).is();
+ arguments_valid &= (args.get(kPipelineStateChangeListenerName).is() ||
+ args.get(kPipelineStateChangeListenerName).is());
+ LoggerD("CreatePipeline arguments are %s", arguments_valid ? "valid" : "invalid");
+
+ return !arguments_valid;
+}
+
+}; // namespace
+
+void MlInstance::MLPipelineManagerCreatePipeline(const picojson::value& args,
+ picojson::object& out) {
+ ScopeLogger("args: %s", args.serialize().c_str());
+
+ if (CreatePipelineArgumentsAreInvalid(args)) {
+ ReportError(PlatformResult{ErrorCode::ABORT_ERR, "Could not create pipeline"}, &out);
+ return;
+ }
+
+ auto id = static_cast(args.get(kId).get());
+ auto definition = args.get(kDefinition).get();
+ auto state_change_listener_name =
+ args.get(kPipelineStateChangeListenerName).is()
+ ? args.get(kPipelineStateChangeListenerName).get()
+ : "";
+
+ auto ret = pipeline_manager_.CreatePipeline(id, definition, state_change_listener_name);
+
+ if (!ret) {
+ ReportError(ret, &out);
+ return;
+ }
+
+ ReportSuccess(out);
+}
// PipelineManager::createPipeline() end
// Pipeline::state begin
@@ -133,6 +183,7 @@ MlInstance::~MlInstance() {
// Valve::setOpen() begin
// Valve::setOpen() end
+
// Pipeline API end
} // namespace ml
diff --git a/src/ml/ml_instance.h b/src/ml/ml_instance.h
index e7a1998..622bcc8 100644
--- a/src/ml/ml_instance.h
+++ b/src/ml/ml_instance.h
@@ -19,6 +19,7 @@
#include "common/extension.h"
+#include "ml/ml_pipeline_manager.h"
#include "nnstreamer/nnstreamer-single.h"
#include "nnstreamer/nnstreamer.h"
@@ -40,9 +41,10 @@ class MlInstance : public common::ParsedInstance {
// Single API end
// Pipeline API begin
+ PipelineManager pipeline_manager_;
// PipelineManager::createPipeline() begin
-
+ void MLPipelineManagerCreatePipeline(const picojson::value& args, picojson::object& out);
// PipelineManager::createPipeline() end
// Pipeline::state begin
@@ -116,7 +118,6 @@ class MlInstance : public common::ParsedInstance {
// Valve::setOpen() begin
// Valve::setOpen() end
-
// Pipeline API end
};
diff --git a/src/ml/ml_pipeline.cc b/src/ml/ml_pipeline.cc
index 60a0108..caa63a5 100644
--- a/src/ml/ml_pipeline.cc
+++ b/src/ml/ml_pipeline.cc
@@ -13,12 +13,125 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include
+
+#include "common/logger.h"
+#include "common/picojson.h"
#include "ml_pipeline.h"
+#include "ml_utils.h"
+
+using common::PlatformResult;
+using common::ErrorCode;
+
+namespace {
+
+const std::string kListenerId = "listenerId";
+const std::string kState = "state";
+
+std::string StateToString(ml_pipeline_state_e state) {
+ ScopeLogger("state: [%d]", state);
+
+ std::string state_str;
+ switch (state) {
+ case ML_PIPELINE_STATE_UNKNOWN:
+ state_str = "UNKNOWN";
+ break;
+ case ML_PIPELINE_STATE_NULL:
+ state_str = "NULL";
+ break;
+ case ML_PIPELINE_STATE_READY:
+ state_str = "READY";
+ break;
+ case ML_PIPELINE_STATE_PAUSED:
+ state_str = "PAUSED";
+ break;
+ case ML_PIPELINE_STATE_PLAYING:
+ state_str = "PLAYING";
+ break;
+ default:
+ LoggerE("Illegal ml_pipeline_state_e value: [%d]", state);
+ state_str = "UNKNOWN";
+ }
+
+ LoggerD("state_str: [%s]", state_str.c_str());
+ return state_str;
+}
+
+} // namespace
+
+namespace extension {
+namespace ml {
+
+Pipeline::Pipeline(int id, const std::string& state_change_listener_name,
+ common::Instance* instance_ptr)
+ : id_{id},
+ pipeline_{nullptr}, // this will be set to a proper pointer in CreatePipeline()
+ state_change_listener_name_{state_change_listener_name},
+ instance_ptr_{instance_ptr} {
+ ScopeLogger("id: [%d], state_change_listener_name: [%s]", id, state_change_listener_name.c_str());
+}
// PipelineManager::createPipeline() begin
-
+PlatformResult Pipeline::CreatePipeline(int id, const std::string& definition,
+ const std::string& state_change_listener_name,
+ common::Instance* instance_ptr,
+ std::unique_ptr* out) {
+ ScopeLogger("id: [%d], definition: [%s], state_change_listener_name: [%s]", id,
+ definition.c_str(), state_change_listener_name.c_str());
+
+ /* We need to create the Pipeline object before setting its pipeline_ member,
+ * because Pipeline is the user data for the listener registered by
+ * ml_pipeline_construct().
+ */
+ std::unique_ptr pipeline_ptr{
+ new (std::nothrow) Pipeline{id, state_change_listener_name, instance_ptr}};
+ if (!pipeline_ptr) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "An unknown occurred.",
+ ("Could not allocate memory for Pipeline"));
+ }
+
+ int ret = ML_ERROR_UNKNOWN;
+ if (state_change_listener_name == "") {
+ ret = ml_pipeline_construct(definition.c_str(), nullptr, nullptr, &pipeline_ptr->pipeline_);
+ } else {
+ ret = ml_pipeline_construct(definition.c_str(), PipelineStateChangeListener,
+ static_cast(pipeline_ptr.get()), &pipeline_ptr->pipeline_);
+ }
+
+ if (ML_ERROR_NONE != ret) {
+ LoggerE("ml_pipeline_construct() failed: [%d] (%s)", ret, get_error_message(ret));
+ return util::ToPlatformResult(ret, "Could not create a pipeline");
+ }
+ LoggerD("ml_pipeline_construct() succeeded");
+
+ *out = std::move(pipeline_ptr);
+ return PlatformResult{};
+}
// PipelineManager::createPipeline() end
+Pipeline::~Pipeline() {
+ ScopeLogger("Destroying pipeline: [%d]", id_);
+
+ auto ret = ml_pipeline_destroy(pipeline_);
+ if (ML_ERROR_NONE != ret) {
+ LoggerE("ml_pipeline_destroy() failed: [%d] (%s)", ret, get_error_message(ret));
+ }
+ LoggerD("ml_pipeline_destroy() succeeded");
+}
+
+void Pipeline::PipelineStateChangeListener(ml_pipeline_state_e state, void* user_data) {
+ ScopeLogger("state: [%s]", StateToString(state).c_str());
+
+ Pipeline* pipeline = static_cast(user_data);
+
+ picojson::value response{picojson::object{}};
+ response.get()[kListenerId] =
+ picojson::value{pipeline->state_change_listener_name_};
+ response.get()[kState] = picojson::value{StateToString(state)};
+
+ common::Instance::PostMessage(pipeline->instance_ptr_, response);
+}
+
// Pipeline::state begin
// Pipeline::state end
@@ -89,4 +202,7 @@
// Valve::setOpen() begin
-// Valve::setOpen() end
\ No newline at end of file
+// Valve::setOpen() end
+
+} // namespace extension
+} // namespace ml
diff --git a/src/ml/ml_pipeline.h b/src/ml/ml_pipeline.h
index 029269e..b5834f4 100644
--- a/src/ml/ml_pipeline.h
+++ b/src/ml/ml_pipeline.h
@@ -17,18 +17,40 @@
#ifndef ML_ML_PIPELINE_H_
#define ML_ML_PIPELINE_H_
+#include