diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index 9f00c60f58..5080664464 100755 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -39,6 +39,7 @@ jobs: with: path: | build/Thunder + build/ThunderInterfaces build/ThunderTools install !install/etc/WPEFramework/plugins @@ -55,7 +56,7 @@ jobs: !install/usr/lib/pkgconfig/gtest.pc !install/usr/lib/pkgconfig/gtest_main.pc !install/usr/lib/wpeframework/plugins - key: ${{ runner.os }}-${{ env.THUNDER_REF }}-${{ env.INTERFACES_REF }}-4 + key: ${{ runner.os }}-${{ env.THUNDER_REF }}-${{ env.INTERFACES_REF }}-5 - name: Set up Python uses: actions/setup-python@v4 with: @@ -130,22 +131,24 @@ jobs: with: path: rdkservices + - name: Apply patch rdkservices + run: > + cd "${{github.workspace}}/rdkservices" + && + git apply "${{github.workspace}}/rdkservices/Tests/L1Tests/patches/0001-IAnalytics.h-changes-for-Thunder-R2.patch" + && + cd .. + - name: Checkout ThunderInterfaces + if: steps.cache.outputs.cache-hit != 'true' uses: actions/checkout@v3 with: repository: rdkcentral/ThunderInterfaces path: ThunderInterfaces ref: ${{env.INTERFACES_REF}} - - name: Apply patches ThunderInterfaces - run: > - cd "${{github.workspace}}/ThunderInterfaces" - && - git apply "${{github.workspace}}/rdkservices/Tests/L1Tests/patches/0001-Add-IAnalytics-interface-R2.patch" - && - cd .. - - name: Build ThunderInterfaces + if: steps.cache.outputs.cache-hit != 'true' run: > cmake -S "${{github.workspace}}/ThunderInterfaces" diff --git a/Analytics/Analytics.h b/Analytics/Analytics.h index 8b8b1434a3..83e8a8afa2 100644 --- a/Analytics/Analytics.h +++ b/Analytics/Analytics.h @@ -20,8 +20,7 @@ #pragma once #include "Module.h" - -#include +#include "IAnalytics.h" namespace WPEFramework { diff --git a/Analytics/Analytics.json b/Analytics/Analytics.json index 4afc8ea17b..e070ef4666 100644 --- a/Analytics/Analytics.json +++ b/Analytics/Analytics.json @@ -99,31 +99,6 @@ "result": { "$ref": "#/common/result" } - }, - "setSessionId" : { - "summary": "Set the session ID for the analytics events", - "params": { - "type":"object", - "properties": { - "sessionId":{ - "summary": "Session ID", - "type": "string", - "example": "1234567890" - } - }, - "required": [ - "sessionId" - ] - }, - "result": { - "$ref": "#/common/result" - } - }, - "setTimeReady" : { - "summary": "Let the analytics plugin know that the system time is ready and valid", - "result": { - "$ref": "#/common/result" - } } } } diff --git a/Analytics/AnalyticsJsonRpc.cpp b/Analytics/AnalyticsJsonRpc.cpp index f5139ec1e5..026cabcfcc 100644 --- a/Analytics/AnalyticsJsonRpc.cpp +++ b/Analytics/AnalyticsJsonRpc.cpp @@ -21,9 +21,6 @@ #include "UtilsJsonRpc.h" const string WPEFramework::Plugin::Analytics::ANALYTICS_METHOD_SEND_EVENT = "sendEvent"; -// TODO: To be removed once the Analytics is capable of handling it internally -const string WPEFramework::Plugin::Analytics::ANALYTICS_METHOD_SET_SESSION_ID = "setSessionId"; -const string WPEFramework::Plugin::Analytics::ANALYTICS_METHOD_SET_TIME_READY = "setTimeReady"; namespace WPEFramework { @@ -34,15 +31,11 @@ namespace Plugin { void Analytics::RegisterAll() { Register(_T(ANALYTICS_METHOD_SEND_EVENT), &Analytics::SendEventWrapper, this); - Register(_T(ANALYTICS_METHOD_SET_SESSION_ID), &Analytics::SetSessionIdWrapper, this); - Register(_T(ANALYTICS_METHOD_SET_TIME_READY), &Analytics::SetTimeReadyWrapper, this); } void Analytics::UnregisterAll() { Unregister(_T(ANALYTICS_METHOD_SEND_EVENT)); - Unregister(_T(ANALYTICS_METHOD_SET_SESSION_ID)); - Unregister(_T(ANALYTICS_METHOD_SET_TIME_READY)); } // API implementation @@ -92,45 +85,6 @@ namespace Plugin { cetListIterator->Release(); returnResponse(result == Core::ERROR_NONE); } - - // Method: setSessionId - Set the session ID - // Return codes: - // - ERROR_NONE: Success - // - ERROR_GENERAL: Failed to set the session ID - uint32_t Analytics::SetSessionIdWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFOMETHOD(); - - uint32_t result = Core::ERROR_NONE; - - returnIfStringParamNotFound(parameters, "sessionId"); - - string sessionId = parameters["sessionId"].String(); - - if (mAnalytics != nullptr) { - result = mAnalytics->SetSessionId(sessionId); - } - - returnResponse(result == Core::ERROR_NONE); - } - - // Method: setTimeReady - Set the time ready - // Return codes: - // - ERROR_NONE: Success - // - ERROR_GENERAL: Failed to set the time ready - uint32_t Analytics::SetTimeReadyWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFOMETHOD(); - - uint32_t result = Core::ERROR_NONE; - - if (mAnalytics != nullptr) { - result = mAnalytics->SetTimeReady(); - } - - returnResponse(result == Core::ERROR_NONE); - } - } } \ No newline at end of file diff --git a/Analytics/CHANGELOG.md b/Analytics/CHANGELOG.md index e23241b2ce..6d737fc111 100644 --- a/Analytics/CHANGELOG.md +++ b/Analytics/CHANGELOG.md @@ -14,6 +14,9 @@ All notable changes to this RDK Service will be documented in this file. For more details, refer to versioning section under Main README. +## [1.0.1] - 2024-10-16 +- Analytics improvements phase 2 + ## [1.0.0] - 2024-07-25 ### Added - New RDK Service Analytics to handle analytics events and send them to dedicated backends diff --git a/Analytics/CMakeLists.txt b/Analytics/CMakeLists.txt index 84ebc6a65c..1100d7ccc5 100644 --- a/Analytics/CMakeLists.txt +++ b/Analytics/CMakeLists.txt @@ -20,7 +20,7 @@ set(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME}) set(VERSION_MAJOR 1) set(VERSION_MINOR 0) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) add_compile_definitions(ANALYTICS_MAJOR_VERSION=${VERSION_MAJOR}) add_compile_definitions(ANALYTICS_MINOR_VERSION=${VERSION_MINOR}) @@ -30,7 +30,6 @@ set(MODULE_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) option(PLUGIN_ANALYTICS_SIFT_BACKEND "Enable Sift backend" OFF) - set(PLUGIN_ANALYTICS_STARTUPORDER "" CACHE STRING "To configure startup order of Analytics plugin") set(PLUGIN_ANALYTICS_AUTOSTART "false" CACHE STRING "Automatically start Analytics plugin") set(PLUGIN_ANALYTICS_DEVICE_OS_NAME "rdk" CACHE STRING "Device OS name") @@ -61,6 +60,98 @@ find_package(CompileSettingsDebug CONFIG REQUIRED) find_package(DS) find_package(IARMBus) +# -- Build IAnalytics interface -- + +find_package(WPEFramework REQUIRED) +find_package(${NAMESPACE}Core REQUIRED) +find_package(CompileSettingsDebug REQUIRED) +find_package(ProxyStubGenerator REQUIRED) +find_package(JsonGenerator REQUIRED) + +# Interfaces we want to build +set(INTERFACES_HEADERS + "${CMAKE_CURRENT_SOURCE_DIR}/IAnalytics.h" +) + +# Invoke the code generators +if(NOT GENERATOR_SEARCH_PATH) + set(GENERATOR_SEARCH_PATH ${CMAKE_SYSROOT}${CMAKE_INSTALL_PREFIX}/include/${NAMESPACE}) +endif() + +message("Using generator search path: ${GENERATOR_SEARCH_PATH}") + +ProxyStubGenerator( + INPUT ${INTERFACES_HEADERS} + OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated" + INCLUDE_PATH ${GENERATOR_SEARCH_PATH} +) + +JsonGenerator( + CODE + INPUT ${INTERFACES_HEADERS} + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/generated" + INCLUDE_PATH ${GENERATOR_SEARCH_PATH} +) + +# Find the generated sources +file(GLOB PROXY_STUB_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/generated/ProxyStubs*.cpp") +file(GLOB JSON_ENUM_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/generated/JsonEnum*.cpp") +file(GLOB JSON_HEADERS "${CMAKE_CURRENT_BINARY_DIR}/generated/J*.h") + +# Build the proxystub lib +add_library(AnalyticsProxyStubs SHARED + ${PROXY_STUB_SOURCES} + Module.cpp +) + +target_link_libraries(AnalyticsProxyStubs + PRIVATE + ${NAMESPACE}Core::${NAMESPACE}Core + CompileSettingsDebug::CompileSettingsDebug +) + +target_include_directories(AnalyticsProxyStubs + PRIVATE + $ +) + +# Build the definitions lib if applicable +if(JSON_ENUM_SOURCES) + add_library(AnalyticsDefinitions SHARED + ${JSON_ENUM_SOURCES} + ) + + target_link_libraries(AnalyticsDefinitions + PRIVATE + ${NAMESPACE}Core::${NAMESPACE}Core + CompileSettingsDebug::CompileSettingsDebug + ) +endif() + +# Install libs & headers +string(TOLOWER ${NAMESPACE} NAMESPACE_LIB) +install(TARGETS AnalyticsProxyStubs + EXPORT AnalyticsProxyStubsTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${NAMESPACE_LIB}/proxystubs COMPONENT ${NAMESPACE}_Runtime +) + +if(JSON_ENUM_SOURCES) + install(TARGETS AnalyticsDefinitions + EXPORT AnalyticsDefinitionsTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/ COMPONENT ${NAMESPACE}_Runtime + ) +endif() + +install(FILES ${INTERFACES_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/interfaces +) + +install(FILES ${JSON_HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${NAMESPACE}/interfaces/json +) + +# -- end of IAnalytics interface build -- + add_library(${MODULE_NAME} SHARED Analytics.cpp AnalyticsJsonRpc.cpp diff --git a/Analytics/IAnalytics.h b/Analytics/IAnalytics.h new file mode 100644 index 0000000000..c8ff032fed --- /dev/null +++ b/Analytics/IAnalytics.h @@ -0,0 +1,60 @@ +/** +* If not stated otherwise in this file or this component's LICENSE +* file the following copyright and licenses apply: +* +* Copyright 2020 RDK Management +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#pragma once + +#include "Module.h" + +// @stubgen:include + +#define ID_ANALYTICS_OFFSET 0x1000 + +namespace WPEFramework { +namespace Exchange { + // @json 1.0.0 + struct EXTERNAL IAnalytics : virtual public Core::IUnknown { + enum { ID = RPC::IDS::ID_EXTERNAL_INTERFACE_OFFSET + ID_ANALYTICS_OFFSET }; + + virtual ~IAnalytics() override = default; + + using IStringIterator = RPC::IIteratorType; + + /** + * @alt sendEvent + * @brief Send an event to the analytics server + * @param eventName Name of the event + * @param eventVersion Version of the event + * @param eventSource Source of the event + * @param eventSourceVersion Version of the event source + * @param cetList List of CETs + * @param epochTimestamp Epoch timestamp of the event + * @param uptimeTimestamp Uptime timestamp of the event + * @param eventPayload Payload of the event + */ + virtual Core::hresult SendEvent(const string& eventName /* @in */, + const string& eventVersion /* @in */, + const string& eventSource /* @in */, + const string& eventSourceVersion /* @in */, + IStringIterator* const& cetList /* @in */, + const uint64_t epochTimestamp /* @in */, + const uint64_t uptimeTimestamp /* @in */, + const string& eventPayload /* @in */ ) = 0; + }; +} +} \ No newline at end of file diff --git a/Analytics/Implementation/AnalyticsImplementation.cpp b/Analytics/Implementation/AnalyticsImplementation.cpp index db55dbda2c..2f4c03829f 100644 --- a/Analytics/Implementation/AnalyticsImplementation.cpp +++ b/Analytics/Implementation/AnalyticsImplementation.cpp @@ -54,13 +54,13 @@ namespace Plugin { mThread.join(); } - /* virtual */ uint32_t AnalyticsImplementation::SendEvent(const string& eventName, + /* virtual */ Core::hresult AnalyticsImplementation::SendEvent(const string& eventName, const string& eventVersion, const string& eventSource, const string& eventSourceVersion, - RPC::IStringIterator* const& cetList, - const uint64_t& epochTimestamp, - const uint64_t& uptimeTimestamp, + IStringIterator* const& cetList, + const uint64_t epochTimestamp, + const uint64_t uptimeTimestamp, const string& eventPayload) { std::shared_ptr event = std::make_shared(); @@ -100,16 +100,6 @@ namespace Plugin { return Core::ERROR_NONE; } - uint32_t AnalyticsImplementation::SetSessionId(const string& id) - { - return Core::ERROR_NONE; - } - - uint32_t AnalyticsImplementation::SetTimeReady() - { - return Core::ERROR_NONE; - } - uint32_t AnalyticsImplementation::Configure(PluginHost::IShell* shell) { LOGINFO("Configuring Analytics"); diff --git a/Analytics/Implementation/AnalyticsImplementation.h b/Analytics/Implementation/AnalyticsImplementation.h index bcedb69e19..2ed245b7c8 100644 --- a/Analytics/Implementation/AnalyticsImplementation.h +++ b/Analytics/Implementation/AnalyticsImplementation.h @@ -19,7 +19,7 @@ #pragma once #include "../Module.h" -#include +#include "../IAnalytics.h" #include #include "Backend/AnalyticsBackend.h" #include "SystemTime.h" @@ -77,17 +77,14 @@ namespace Plugin { // IAnalyticsImplementation interface - uint32_t SendEvent(const string& eventName, + Core::hresult SendEvent(const string& eventName, const string& eventVersion, const string& eventSource, const string& eventSourceVersion, - RPC::IStringIterator* const& cetList, - const uint64_t& epochTimestamp, - const uint64_t& uptimeTimestamp, + IStringIterator* const& cetList, + const uint64_t epochTimestamp, + const uint64_t uptimeTimestamp, const string& eventPayload) override; - uint32_t SetSessionId(const string& id) override; - uint32_t SetTimeReady() override; - // IConfiguration interface uint32_t Configure(PluginHost::IShell* shell); diff --git a/Tests/L1Tests/patches/0001-Add-IAnalytics-interface-R2.patch b/Tests/L1Tests/patches/0001-Add-IAnalytics-interface-R2.patch deleted file mode 100644 index 8045170a33..0000000000 --- a/Tests/L1Tests/patches/0001-Add-IAnalytics-interface-R2.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 9a2398b7bc356f341e25c414e45b6919df135d58 Mon Sep 17 00:00:00 2001 -From: Adrian Muzyka -Date: Thu, 19 Sep 2024 12:34:27 +0200 -Subject: [PATCH] Add IAnalytics interface R2 - ---- - interfaces/IAnalytics.h | 27 +++++++++++++++++++++++++++ - interfaces/Ids.h | 1 + - 2 files changed, 28 insertions(+) - create mode 100644 interfaces/IAnalytics.h - -diff --git a/interfaces/IAnalytics.h b/interfaces/IAnalytics.h -new file mode 100644 -index 0000000..19f5a3a ---- /dev/null -+++ b/interfaces/IAnalytics.h -@@ -0,0 +1,27 @@ -+#pragma once -+ -+#include "Module.h" -+ -+// @stubgen:include -+ -+namespace WPEFramework { -+namespace Exchange { -+ -+ struct EXTERNAL IAnalytics : virtual public Core::IUnknown { -+ enum { ID = ID_ANALYTICS }; -+ -+ virtual ~IAnalytics() override = default; -+ -+ virtual uint32_t SendEvent(const string& eventName /* @in */, -+ const string& eventVersion /* @in */, -+ const string& eventSource /* @in */, -+ const string& eventSourceVersion /* @in */, -+ RPC::IStringIterator* const& cetList /* @in */, -+ const uint64_t& epochTimestamp /* @in */, -+ const uint64_t& uptimeTimestamp /* @in */, -+ const string& eventPayload /* @in */ ) = 0; -+ virtual uint32_t SetSessionId(const string& id /* @in */) = 0; -+ virtual uint32_t SetTimeReady() = 0; -+ }; -+} -+} -diff --git a/interfaces/Ids.h b/interfaces/Ids.h -index 7ef9a42..fa5c1dd 100644 ---- a/interfaces/Ids.h -+++ b/interfaces/Ids.h -@@ -288,6 +288,7 @@ namespace Exchange { - ID_DTV_TRANSPORT, - ID_TEXT_TO_SPEECH, - ID_TEXT_TO_SPEECH_NOTIFICATION, -+ ID_ANALYTICS, - - }; - } --- -2.25.1 - diff --git a/Tests/L1Tests/patches/0001-IAnalytics.h-changes-for-Thunder-R2.patch b/Tests/L1Tests/patches/0001-IAnalytics.h-changes-for-Thunder-R2.patch new file mode 100644 index 0000000000..d2a195e1e2 --- /dev/null +++ b/Tests/L1Tests/patches/0001-IAnalytics.h-changes-for-Thunder-R2.patch @@ -0,0 +1,53 @@ +From ab0dd48a404f4e19d1d33aeb5af8aaf7239e5fef Mon Sep 17 00:00:00 2001 +From: Adrian Muzyka +Date: Wed, 16 Oct 2024 13:08:08 +0000 +Subject: [PATCH] IAnalytics.h changes for Thunder R2 + +--- + Analytics/IAnalytics.h | 20 ++++---------------- + 1 file changed, 4 insertions(+), 16 deletions(-) + +diff --git a/Analytics/IAnalytics.h b/Analytics/IAnalytics.h +index c8ff032fe..964726868 100644 +--- a/Analytics/IAnalytics.h ++++ b/Analytics/IAnalytics.h +@@ -21,33 +21,21 @@ + + #include "Module.h" + +-// @stubgen:include ++// @stubgen:include + + #define ID_ANALYTICS_OFFSET 0x1000 + + namespace WPEFramework { + namespace Exchange { +- // @json 1.0.0 ++ + struct EXTERNAL IAnalytics : virtual public Core::IUnknown { +- enum { ID = RPC::IDS::ID_EXTERNAL_INTERFACE_OFFSET + ID_ANALYTICS_OFFSET }; ++ enum { ID = ID_ANALYTICS_OFFSET }; + + virtual ~IAnalytics() override = default; + + using IStringIterator = RPC::IIteratorType; + +- /** +- * @alt sendEvent +- * @brief Send an event to the analytics server +- * @param eventName Name of the event +- * @param eventVersion Version of the event +- * @param eventSource Source of the event +- * @param eventSourceVersion Version of the event source +- * @param cetList List of CETs +- * @param epochTimestamp Epoch timestamp of the event +- * @param uptimeTimestamp Uptime timestamp of the event +- * @param eventPayload Payload of the event +- */ +- virtual Core::hresult SendEvent(const string& eventName /* @in */, ++ virtual uint32_t SendEvent(const string& eventName /* @in */, + const string& eventVersion /* @in */, + const string& eventSource /* @in */, + const string& eventSourceVersion /* @in */, +-- +2.43.0 diff --git a/Tests/L1Tests/tests/test_Analytics.cpp b/Tests/L1Tests/tests/test_Analytics.cpp index 92a96fbc34..68d6f5eb5a 100644 --- a/Tests/L1Tests/tests/test_Analytics.cpp +++ b/Tests/L1Tests/tests/test_Analytics.cpp @@ -23,8 +23,6 @@ class AnalyticsTest : public ::testing::Test { TEST_F(AnalyticsTest, RegisteredMethods) { EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("sendEvent"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setSessionId"))); - EXPECT_EQ(Core::ERROR_NONE, handler.Exists(_T("setTimeReady"))); } TEST_F(AnalyticsTest, sendEvent) @@ -33,17 +31,5 @@ TEST_F(AnalyticsTest, sendEvent) EXPECT_EQ(response, string("{\"success\":true}")); } -TEST_F(AnalyticsTest, setSessionId) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setSessionId"), _T("{\"sessionId\":\"123456789\"}"), response)); - EXPECT_EQ(response, string("{\"success\":true}")); -} - -TEST_F(AnalyticsTest, setTimeReady) -{ - EXPECT_EQ(Core::ERROR_NONE, handler.Invoke(connection, _T("setTimeReady"), _T("{}"), response)); - EXPECT_EQ(response, string("{\"success\":true}")); -} -