diff --git a/.github/workflows/L2-tests-R4-4-1.yml b/.github/workflows/L2-tests-R4-4-1.yml new file mode 100755 index 0000000000..79b6d74871 --- /dev/null +++ b/.github/workflows/L2-tests-R4-4-1.yml @@ -0,0 +1,404 @@ +name: L2-tests-R4-4-1 + +on: + push: + branches: [ main, 'sprint/**', 'release/**' ] + pull_request: + branches: [ main, 'sprint/**', 'release/**' ] + +env: + BUILD_TYPE: Debug + THUNDER_REF: "R4.4.1" + INTERFACES_REF: "R4.4.1" + +jobs: + L2-tests-R4-4-1: + name: Run L2 with Thunder R4.4.1 + runs-on: ubuntu-latest + strategy: + matrix: + compiler: [ gcc, clang ] + coverage: [ with-coverage, without-coverage ] + exclude: + - compiler: clang + coverage: with-coverage + - compiler: clang + coverage: without-coverage + - compiler: gcc + coverage: without-coverage + + steps: + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + - run: pip install jsonref + + - name: Set up CMake + uses: jwlawson/actions-setup-cmake@v1.13 + with: + cmake-version: '3.16.x' + + - name: Install packages + run: > + sudo apt update + && + sudo apt install -y libsqlite3-dev libcurl4-openssl-dev valgrind lcov clang libsystemd-dev libboost-all-dev libwebsocketpp-dev meson libcunit1 libcunit1-dev + + - name: Install GStreamer + run: | + sudo apt update + sudo apt install -y libunwind-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev + + - name: Build trevor-base64 + run: | + if [ ! -d "trower-base64" ]; then + git clone https://github.com/xmidt-org/trower-base64.git + fi + cd trower-base64 + meson setup --warnlevel 3 --werror build + ninja -C build + sudo ninja -C build install + + - name: Checkout Thunder + uses: actions/checkout@v3 + with: + repository: rdkcentral/Thunder + path: Thunder + ref: ${{env.THUNDER_REF}} + + - name: Checkout ThunderTools + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/checkout@v3 + with: + repository: rdkcentral/ThunderTools + path: ThunderTools + ref: ${{env.THUNDER_REF}} + + - name: Build ThunderTools + if: steps.cache.outputs.cache-hit != 'true' + run: > + cmake + -S "${{github.workspace}}/ThunderTools" + -B build/ThunderTools + -DEXCEPTIONS_ENABLE=ON + -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/install/usr" + -DCMAKE_MODULE_PATH="${{github.workspace}}/install/tools/cmake" + && + cmake --build build/ThunderTools -j8 + && + cmake --install build/ThunderTools + + - name: Build Thunder + if: steps.cache.outputs.cache-hit != 'true' + run: > + cmake + -S "${{github.workspace}}/Thunder" + -B build/Thunder + -DMESSAGING=ON + -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/install/usr" + -DCMAKE_MODULE_PATH="${{github.workspace}}/install/tools/cmake" + -DBUILD_TYPE=${{env.BUILD_TYPE}} + -DBINDING=127.0.0.1 + -DPORT=9998 + -DEXCEPTIONS_ENABLE=ON + && + cmake --build build/Thunder -j8 + && + cmake --install build/Thunder + + - name: Checkout rdkservices + uses: actions/checkout@v3 + with: + path: rdkservices + + - name: Apply patch Rdkservices + run: | + cd ${{github.workspace}}/rdkservices + patch -p1 < files/0003-R4.4.1-LocationSync-compilation-error.patch + patch -p1 < files/0003-R4.4.1-SystemAudioPlayer-compilation-error.patch + cd - + + - name: Checkout ThunderInterfaces + uses: actions/checkout@v3 + with: + repository: rdkcentral/ThunderInterfaces + path: ThunderInterfaces + ref: ${{env.INTERFACES_REF}} + run: rm -rf ${{github.workspace}}/ThunderInterfaces/jsonrpc/DTV.json + + - name: Apply patch ThunderInterfaces + run: | + echo "Present working directory is: $(pwd)" + echo "Listing directory is:" + ls -la + cd ThunderInterfaces + echo "Current branch is: $(git branch --show-current)" + git apply "${{github.workspace}}/rdkservices/files/SplitDeviceCapablities.patch" + git apply "${{github.workspace}}/rdkservices/files/0007-RDK-IDeviceInfo-Changes.patch" + git apply "${{github.workspace}}/rdkservices/files/0001-Add-TextToSpeech-Interface.patch" + cd .. + + - name: Build ThunderInterfaces + run: > + cmake + -S "${{github.workspace}}/ThunderInterfaces" + -B build/ThunderInterfaces + -DEXCEPTIONS_ENABLE=ON + -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/install/usr" + -DCMAKE_MODULE_PATH="${{github.workspace}}/install/tools/cmake" + && + cmake --build build/ThunderInterfaces -j8 + && + cmake --install build/ThunderInterfaces + + - name: Generate external headers + # Empty headers to mute errors + run: > + cd "${{github.workspace}}/rdkservices/Tests/" + && + mkdir -p + headers + headers/rdk/ds + headers/rdk/iarmbus + headers/rdk/iarmmgrs-hal + headers/systemservices + headers/systemservices/proc + && + cd headers + && + touch + rdk/ds/host.hpp + rdk/ds/videoOutputPort.hpp + rdk/ds/audioOutputPort.hpp + rdk/ds/sleepMode.hpp + rdk/iarmbus/libIARM.h + rdk/iarmbus/libIBus.h + rdk/iarmbus/libIBusDaemon.h + rdk/iarmmgrs-hal/mfrMgr.h + rdk/iarmmgrs-hal/pwrMgr.h + rdk/iarmmgrs-hal/sysMgr.h + rfcapi.h + rbus.h + libudev.h + systemservices/proc/readproc.h + systemservices/secure_wrapper.h + maintenanceMGR.h + pkg.h + && + cp -r /usr/include/gstreamer-1.0/gst /usr/include/glib-2.0/* /usr/lib/x86_64-linux-gnu/glib-2.0/include/* /usr/local/include/trower-base64/base64.h . + + - name: Set clang toolchain + if: ${{ matrix.compiler == 'clang' }} + run: echo "TOOLCHAIN_FILE=${{github.workspace}}/rdkservices/Tests/clang.cmake" >> $GITHUB_ENV + + - name: Set gcc/with-coverage toolchain + if: ${{ matrix.compiler == 'gcc' && matrix.coverage == 'with-coverage' && !env.ACT }} + run: echo "TOOLCHAIN_FILE=${{github.workspace}}/rdkservices/Tests/gcc-with-coverage.cmake" >> $GITHUB_ENV + + - name: Build mocks + run: > + cmake + -S "${{github.workspace}}/rdkservices/Tests/mocks" + -B build/mocks + -DCMAKE_TOOLCHAIN_FILE="${{ env.TOOLCHAIN_FILE }}" + -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/install/usr" + -DCMAKE_MODULE_PATH="${{github.workspace}}/install/tools/cmake" + -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + -DCMAKE_CXX_FLAGS="-fPIC" + && + cmake --build build/mocks -j8 + && + cmake --install build/mocks + + - name: Build rdkservices + run: > + cmake + -S "${{github.workspace}}/rdkservices" + -B build/rdkservices + -DCMAKE_TOOLCHAIN_FILE="${{ env.TOOLCHAIN_FILE }}" + -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/install/usr" + -DCMAKE_MODULE_PATH="${{github.workspace}}/install/tools/cmake" + -DCMAKE_CXX_FLAGS=" + -DEXCEPTIONS_ENABLE=ON + -fprofile-arcs + -ftest-coverage + -DUSE_THUNDER_R4=ON + -DTHUNDER_VERSION=4 + -DTHUNDER_VERSION_MAJOR=4 + -DTHUNDER_VERSION_MINOR=4 + -I ${{github.workspace}}/rdkservices/Tests/headers + -I ${{github.workspace}}/rdkservices/Tests/headers/rdk/ds + -I ${{github.workspace}}/rdkservices/Tests/headers/rdk/iarmbus + -I ${{github.workspace}}/rdkservices/Tests/headers/rdk/iarmmgrs-hal + -I ${{github.workspace}}/rdkservices/Tests/headers/systemservices + -I ${{github.workspace}}/rdkservices/Tests/headers/sampleplugin + -I ${{github.workspace}}/rdkservices/Tests/headers/systemservices/proc + -include ${{github.workspace}}/rdkservices/Tests/mocks/devicesettings.h + -include ${{github.workspace}}/rdkservices/Tests/mocks/Iarm.h + -include ${{github.workspace}}/rdkservices/Tests/mocks/Rfc.h + -include ${{github.workspace}}/rdkservices/Tests/mocks/RBus.h + -include ${{github.workspace}}/rdkservices/Tests/mocks/Udev.h + -include ${{github.workspace}}/rdkservices/Tests/mocks/Wraps.h + -include ${{github.workspace}}/rdkservices/Tests/mocks/maintenanceMGR.h + -include ${{github.workspace}}/rdkservices/Tests/mocks/pkg.h + -Wall -Wno-unused-result -Wno-deprecated-declarations -Wno-error=format= + -DUSE_IARMBUS + -DENABLE_THERMAL_PROTECTION" + -DCOMCAST_CONFIG=OFF + -DCMAKE_DISABLE_FIND_PACKAGE_DS=ON + -DCMAKE_DISABLE_FIND_PACKAGE_IARMBus=ON + -DCMAKE_DISABLE_FIND_PACKAGE_Udev=ON + -DCMAKE_DISABLE_FIND_PACKAGE_RFC=ON + -DCMAKE_DISABLE_FIND_PACKAGE_RBus=ON + -DPLUGIN_WAREHOUSE=ON + -DPLUGIN_SYSTEMSERVICES=ON + -DPLUGIN_TELEMETRY=ON + -DPLUGIN_HDCPPROFILE=OFF + -DPLUGIN_NETWORK=OFF + -DPLUGIN_TEXTTOSPEECH=OFF + -DPLUGIN_USBACCESS=ON + -DUSE_THUNDER_R4=ON + -DPLUGIN_L2Tests=ON + -DRDK_SERVICE_L2_TEST=ON + -DDS_FOUND=ON + -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + && + cmake --build build/rdkservices -j8 + && + cmake --install build/rdkservices + + - name: Set up files + run: > + sudo mkdir -p -m 777 + /opt/persistent + /opt/secure + /opt/secure/reboot + /opt/secure/persistent + /opt/secure/persistent/System + /opt/logs + /lib/rdk + /run/media/sda1/logs/PreviousLogs + /run/media/sda2/logs/PreviousLogs + /run/sda1/UsbTestFWUpdate + /run/sda1/UsbProdFWUpdate + /run/media/sda1/Logs + /run/sda2 + && + sudo touch + /opt/standbyReason.txt + /opt/tmtryoptout + /opt/fwdnldstatus.txt + /opt/dcm.properties + /etc/device.properties + /etc/dcm.properties + /etc/authService.conf + /version.txt + /run/media/sda1/logs/PreviousLogs/logFile.txt + /run/media/sda1/logs/test.txt + /run/media/sda1/logs/test.png + /run/media/sda1/logs/test.docx + /run/media/sda2/logs/test.txt + /run/media/sda2/logs/test.png + /run/media/sda1/Logs/5C3400F15492_Logs_12-05-22-10-41PM.tgz + /run/sda1/HSTP11MWR_5.11p5s1_VBN_sdy.bin + /run/sda1/UsbTestFWUpdate/HSTP11MWR_3.11p5s1_VBN_sdy.bin + /run/sda1/UsbProdFWUpdate/HSTP11MWR_4.11p5s1_VBN_sdy.bin + /lib/rdk/getMaintenanceStartTime.sh + /tmp/opkg.conf + /tmp/system_service_temp.conf + && + sudo chmod 777 + /opt/standbyReason.txt + /opt/tmtryoptout + /opt/fwdnldstatus.txt + /opt/dcm.properties + /etc/device.properties + /etc/dcm.properties + /etc/authService.conf + /version.txt + /lib/rdk/getMaintenanceStartTime.sh + /tmp/opkg.conf + /tmp/system_service_temp.conf + + - name: Download pact_verifier_cli + run: > + echo "Copying pact plugins" && + sudo mkdir -p ~/.pact/plugins/websockets-0.4.1 && + sudo cp "${{github.workspace}}/rdkservices/Tests/L2Tests/pact/pact-plugin-websockets" ~/.pact/plugins/websockets-0.4.1/ && + sudo cp "${{github.workspace}}/rdkservices/Tests/L2Tests/pact/pact-plugin.json" ~/.pact/plugins/websockets-0.4.1/ && + sudo chmod +x ~/.pact/plugins/websockets-0.4.1/pact-plugin-websockets && + PATH=${{github.workspace}}/install/usr/bin:${PATH} + ${{github.workspace}}/rdkservices/Tests/L2Tests/pact/install-verifier-cli.sh + + - name: Run unit tests without valgrind + run: > + PATH=${{github.workspace}}/install/usr/bin:${PATH} + LD_LIBRARY_PATH=${{github.workspace}}/install/usr/lib:${{github.workspace}}/install/usr/lib/wpeframework/plugins:${LD_LIBRARY_PATH} + RdkServicesL2Test + + - name: Run unit tests with valgrind + run: > + PATH=${{github.workspace}}/install/usr/bin:${PATH} + LD_LIBRARY_PATH=${{github.workspace}}/install/usr/lib:${{github.workspace}}/install/usr/lib/wpeframework/plugins:${LD_LIBRARY_PATH} + valgrind + --tool=memcheck + --log-file=valgrind_log + --leak-check=yes + --show-reachable=yes + --track-fds=yes + --fair-sched=try + RdkServicesL2Test + + - name: Generate coverage + if: ${{ matrix.coverage == 'with-coverage' && !env.ACT }} + run: > + cp ${{github.workspace}}/rdkservices/Tests/L2Tests/.lcovrc_l2 ~/.lcovrc + && + lcov -c + -o coverage.info + -d build/rdkservices + && + lcov + -r coverage.info + '/usr/include/*' + '*/build/rdkservices/_deps/*' + '*/install/usr/include/*' + '*/Tests/headers/*' + '*/Tests/mocks/*' + '*/Tests/L2Tests/*' + -o filtered_coverage.info + && + genhtml + -o coverage + -t "rdkservices coverage" + filtered_coverage.info + + - name: Upload artifacts + if: ${{ !env.ACT }} + uses: actions/upload-artifact@v3 + with: + name: artifacts + path: | + coverage/ + valgrind_log + if-no-files-found: warn + + - name: Run contract tests + if: ${{ !env.ACT }} + env: + PACTFLOW_TOKEN: ${{ secrets.PACTFLOW_TOKEN }} + run: > + PATH=$GITHUB_WORKSPACE/install/usr/bin:${PATH} + LD_LIBRARY_PATH=$GITHUB_WORKSPACE/install/usr/lib:$GITHUB_WORKSPACE/install/usr/lib/wpeframework/plugins:${LD_LIBRARY_PATH} + RdkServicesL2Test CTVerifierMain + + - name: Upload contract test results + if: ${{ !env.ACT }} + uses: actions/upload-artifact@v3 + with: + name: Contract test results + path: | + contract-test-results.json + contract-test-statistics.txt + if-no-files-found: warn diff --git a/.github/workflows/L2-tests.yml b/.github/workflows/L2-tests.yml index 2692c5c702..56dac8977c 100755 --- a/.github/workflows/L2-tests.yml +++ b/.github/workflows/L2-tests.yml @@ -13,7 +13,7 @@ env: jobs: l2-tests: - name: Build and run L2 tests + name: Run L2 with Thunder R2 runs-on: ubuntu-latest strategy: matrix: diff --git a/DisplayInfo/CMakeLists.txt b/DisplayInfo/CMakeLists.txt index 346c0987b1..fb5e45f7c7 100644 --- a/DisplayInfo/CMakeLists.txt +++ b/DisplayInfo/CMakeLists.txt @@ -93,6 +93,11 @@ if (USE_DEVICESETTINGS) PRIVATE DeviceSettings/Amlogic/SoC_abstraction.cpp DeviceSettings/Amlogic/kms.c) + elseif (BUILD_RASPBERRYPI) + target_sources(${MODULE_NAME} + PRIVATE + DeviceSettings/RPI/SoC_abstraction.cpp + DeviceSettings/RPI/kms.c) endif() elseif (NXCLIENT_FOUND AND NEXUS_FOUND) diff --git a/DisplayInfo/DeviceSettings/RPI/SoC_abstraction.cpp b/DisplayInfo/DeviceSettings/RPI/SoC_abstraction.cpp new file mode 100644 index 0000000000..058233484c --- /dev/null +++ b/DisplayInfo/DeviceSettings/RPI/SoC_abstraction.cpp @@ -0,0 +1,184 @@ +/* + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kms.h" + +#define MEM_PROCFS "/proc/meminfo" +#define TOTAL_MEM_PARAM_STR "MemTotal:" +#define FREE_MEM_PARAM_STR "MemFree:" +#define DEFAULT_DEVICE "/dev/dri/card1" + +using namespace std; + +static uint64_t parseLine(const char * line); +static uint64_t getMemInfo(const char * param); +static void getPrimaryPlane(int drm_fd, kms_ctx *kms, drmModePlane **plane); +static void getGraphicSize(uint32_t &w, uint32_t &h); + +static uint64_t parseLine(const char * line) +{ + string str(line); + uint64_t val = 0; + size_t begin = str.find_first_of("0123456789"); + size_t end = string::npos; + + if (string::npos != begin) + end = str.find_first_not_of("0123456789", begin); + + if (string::npos != begin && string::npos != end) + { + + str = str.substr(begin, end); + val = strtoul(str.c_str(), NULL, 10); + + } + else + { + cout << "Failed to parse: " << line << endl; + } + + return val; +} + +static uint64_t getMemInfo(const char * param) +{ + FILE *meminfoFile = fopen(MEM_PROCFS, "r"); + uint64_t memVal = 0; + if (NULL == meminfoFile) + { + cout << "Failed to open " << MEM_PROCFS << ", error: " << strerror(errno) << endl; + } + else + { + vector buf; + buf.resize(1024); + + while (fgets(buf.data(), buf.size(), meminfoFile)) + { + if ( strstr(buf.data(), param ) == buf.data()) + { + memVal = parseLine(buf.data()) * 1000; + break; + } + } + + fclose(meminfoFile); + } + return memVal; +} + +static void getPrimaryPlane(int drm_fd, kms_ctx *kms, drmModePlane **plane) +{ + kms_get_plane(drm_fd, kms); + cout << "Primary Plane ID : "<< kms->primary_plane_id << endl; + *plane = drmModeGetPlane(drm_fd, kms->primary_plane_id ); + if(*plane) + printf("fb id : %d\n", (*plane)->fb_id); +} + +static void getGraphicSize(uint32_t &w, uint32_t &h) +{ + int drm_fd; + kms_ctx *kms = NULL; + drmModePlane *plane = NULL; + int trytimes = 0; + + do { + /* Setup buffer information */ + drm_fd = open( DEFAULT_DEVICE, O_RDWR | O_CLOEXEC); + + /* Setup KMS */ + kms = kms_setup(drm_fd); + if(!kms || !kms->crtc ) { + cout << "[RPI] kms_setup fail" << endl; + break; + } + + /* Get primary buffer */ + getPrimaryPlane(drm_fd, kms, &plane); + if( !plane) { + cout << "[RPI] fail to getPrimaryPlane" << endl; + break; + } + + /* get fb */ + drmModeFB *fb = drmModeGetFB(drm_fd, plane->fb_id); + while(!fb) { + getPrimaryPlane(drm_fd, kms, &plane); + fb = drmModeGetFB(drm_fd, plane->fb_id); + if (trytimes++ > 100) { + cout << "[RPI] fail to getPrimaryPlane" << endl; + break; + } + } + + /* Get the width and height */ + if(fb) { + w = fb->width; + h = fb->height; + drmModeFreeFB(fb); + } + } while(0); + + /* release */ + /* Cleanup buffer info */ + if(kms) { + kms_cleanup_context(kms); + free(kms); + } + + cout << "[getGraphicSize] width : " << w << endl; + cout << "[getGraphicSize] height : " << h << endl; + if(drm_fd >= 0){ + close(drm_fd); + } +} + + +uint64_t SoC_GetTotalGpuRam() +{ + return getMemInfo(TOTAL_MEM_PARAM_STR); +} + +uint64_t SoC_GetFreeGpuRam() +{ + return getMemInfo(FREE_MEM_PARAM_STR); +} + +uint32_t SoC_GetGraphicsWidth() +{ + uint32_t w, h; + getGraphicSize(w, h); + return w; +} + +uint32_t SoC_GetGraphicsHeight() +{ + uint32_t w, h; + getGraphicSize(w, h); + return h; +} diff --git a/DisplayInfo/DeviceSettings/RPI/kms.c b/DisplayInfo/DeviceSettings/RPI/kms.c new file mode 100644 index 0000000000..cde7d05d7f --- /dev/null +++ b/DisplayInfo/DeviceSettings/RPI/kms.c @@ -0,0 +1,212 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include "kms.h" + +void kms_setup_encoder( int fd, kms_ctx *kms ) +{ + for( int i = 0; i < kms->res->count_encoders; i++ ) { + + kms->encoder = drmModeGetEncoder(fd,kms->res->encoders[i]); + + if(!kms->encoder){ + return; + } + + if ( kms->encoder->encoder_id == kms->connector->encoder_id ) { + + kms->encoder_id = kms->encoder->encoder_id; + return; + } + + + for( int j = 0; j < kms->res->count_crtcs; j++ ) { + + if( kms->encoder->possible_crtcs & ( 1 << j ) ) { + + drmModeFreeEncoder( kms->encoder ); + kms->encoder = drmModeGetEncoder(fd, kms->res->encoders[j]); + + kms->encoder->crtc_id = kms->crtc_id = j; + goto exit; + } + } + } + +exit: + return; +} + + + + +void kms_setup_connector( int fd, kms_ctx *kms ) +{ + int i = 0; + drmModeConnector *connector = NULL; + + for( i = 0; i < kms->res->count_connectors; i++ ) { + + connector = drmModeGetConnector(fd, kms->res->connectors[i]); + if( connector ) { + + if( connector->count_modes && ( connector->connection == DRM_MODE_CONNECTED ) ) { + break; + } + } + } + + if ( connector ) { + + kms->connector = connector; + kms->connector_id = connector->connector_id; + } + + return; +} + + +void kms_setup_crtc( int fd, kms_ctx *kms ) +{ + if( kms->encoder ) { + + kms->crtc = drmModeGetCrtc(fd, kms->encoder->crtc_id); + + if( kms->crtc && kms->crtc->mode_valid ) { + + kms->current_info = kms->crtc->mode; + kms->crtc_id = kms->encoder->crtc_id; + } + } + + return; +} + + +kms_ctx* kms_setup( int fd ) +{ + kms_ctx *kms = NULL; + kms = (kms_ctx*)calloc(1,sizeof(*kms)); + if( !kms ) + assert(0); + + kms->res = drmModeGetResources(fd); + + kms_setup_connector(fd, kms); + kms_setup_encoder(fd, kms); + kms_setup_crtc(fd, kms); + return kms; +} + + +void kms_cleanup_context( kms_ctx *kms ) +{ + if( kms->connector ) + drmModeFreeConnector(kms->connector); + + if( kms->encoder ) + drmModeFreeEncoder(kms->encoder); + + if( kms->crtc ) + drmModeFreeCrtc(kms->crtc); + + if( kms->res ) + drmModeFreeResources(kms->res); +} + + +uint32_t kms_get_properties(int fd, drmModeObjectProperties *props, const char *name) +{ + drmModePropertyPtr property; + uint32_t i, id = 0; + + for (i = 0; i < props->count_props; i++) { + + property = drmModeGetProperty(fd, props->props[i]); + if (!strcmp(property->name, name)) + id = property->prop_id; + + drmModeFreeProperty(property); + + if ( id ) + return id; + } + return id; +} + + + +void kms_get_plane( int fd, kms_ctx *kms ) +{ + int n = 0, j = 0; + + drmModePlane *plane = NULL; + drmModePlaneRes *planeRes = NULL; + drmModePropertyRes *prop = NULL; + drmModeObjectProperties *props = NULL; + + drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + + kms->primary_plane_id = kms->overlay_plane_id = -1; + + planeRes = drmModeGetPlaneResources( fd ); + if ( planeRes ) { + + for( n= 0; n < planeRes->count_planes; ++n ) { + + plane = drmModeGetPlane( fd, planeRes->planes[n] ); + + if ( plane ) { + + props = drmModeObjectGetProperties( fd, planeRes->planes[n], DRM_MODE_OBJECT_PLANE ); + if ( props ) { + + for( j= 0; j < props->count_props; ++j ) { + + prop = drmModeGetProperty( fd, props->props[j] ); + if ( prop ) { + + if ( !strcmp( prop->name, "type") ) { + + if ( ( props->prop_values[j] == DRM_PLANE_TYPE_PRIMARY ) && ( kms->primary_plane_id == -1 ) ) + kms->primary_plane_id = planeRes->planes[n]; + + else if ( ( props->prop_values[j] == DRM_PLANE_TYPE_OVERLAY ) && ( kms->overlay_plane_id == -1 ) ) + kms->overlay_plane_id = planeRes->planes[n]; + } + } + + drmModeFreeProperty( prop ); + } + } + + drmModeFreeObjectProperties( props ); + } + + drmModeFreePlane( plane ); + } + + } + + drmModeFreePlaneResources( planeRes ); +} diff --git a/DisplayInfo/DeviceSettings/RPI/kms.h b/DisplayInfo/DeviceSettings/RPI/kms.h new file mode 100644 index 0000000000..454a59bc5d --- /dev/null +++ b/DisplayInfo/DeviceSettings/RPI/kms.h @@ -0,0 +1,139 @@ +/* + * 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. + */ + +#ifndef __DRM_KMS_H__ +#define __DRM_KMS_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _kms_ctx { + + drmModeRes *res; + drmModeConnector *connector; + drmModeEncoder *encoder; + drmModeCrtc *crtc; + + drmModeCrtc *previous_crtc; + drmModeModeInfo current_info; + + uint32_t connector_id; /**< Connector id which will be use in program */ + uint32_t crtc_id; + uint32_t encoder_id; + uint32_t primary_plane_id; + uint32_t overlay_plane_id; + + /* atomic properties */ + uint32_t active_property; + uint32_t mode_id_property; + uint32_t crtc_id_property; + uint32_t blob_id; + + uint32_t fb_id_property; + uint32_t crtc_x_property; + uint32_t crtc_y_property; + uint32_t crtc_h_property; + uint32_t crtc_w_property; + uint32_t src_x_property; + uint32_t src_y_property; + uint32_t src_w_property; + uint32_t src_h_property; + + drmModeAtomicReq *req; + +} kms_ctx; + +/** + * @brief Create kms context + * + * @param[in] fd drm file descriptor + * + * + * @retval kms context + */ +kms_ctx* kms_setup(int fd); + + + +/** + * @brief Cleanup kms context + * + * @param[in] kms kms context + * + */ +void kms_cleanup_context(kms_ctx *kms); + +/** + * @brief Set and get possible encoder id + * + * @param[in] fd drm file descriptor + * @param[in] kms kms context + * + */ +void kms_setup_encoder(int fd, kms_ctx *kms); + + +/** + * @brief Set and get possible connector id + * + * @param[in] fd drm file descriptor + * @para,[in] kms kms context + * + */ +void kms_setup_connector(int fd, kms_ctx *kms); + +/** + * @brief Set and get possible crtc id + * + * @param[in] fd drm file descriptor + * @param[in] kms kms context + * + */ +void kms_setup_crtc(int fd, kms_ctx *kms); + +/** + * @brief Get the specific object properties + * + * @param[in] fd drm file descriptor + * @param[in] props all object properties + * @param[in] name the property name which want to be queried + * + */ +uint32_t kms_get_properties(int fd, drmModeObjectProperties *props, const char *name); + + +/** + * @brief Get primary and overlay plane. + * The plane id will set to -1 if cannot get. + * + * @param[in] fd drm file descriptor + * @param[in] kms kms context + * + */ +void kms_get_plane( int fd, kms_ctx *kms); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Monitor/CHANGELOG.md b/Monitor/CHANGELOG.md index 30f3614efb..34355dffaa 100644 --- a/Monitor/CHANGELOG.md +++ b/Monitor/CHANGELOG.md @@ -15,6 +15,10 @@ All notable changes to this RDK Service will be documented in this file. * Changes in CHANGELOG should be updated when commits are added to the main or release branches. There should be one CHANGELOG entry per JIRA Ticket. This is not enforced on sprint branches since there could be multiple changes for the same JIRA ticket during development. * For more details, refer to [versioning](https://github.com/rdkcentral/rdkservices#versioning) section under Main README. +## [1.0.7] - 2024-06-20 +### Added +- Added Delay in Thread Restart Logic + ## [1.0.6] - 2024-03-29 ### Security - Resolved security vulnerabilities diff --git a/Monitor/Monitor.cpp b/Monitor/Monitor.cpp index 4a5869c78f..8d9a23aaa3 100644 --- a/Monitor/Monitor.cpp +++ b/Monitor/Monitor.cpp @@ -21,7 +21,7 @@ #define API_VERSION_NUMBER_MAJOR 1 #define API_VERSION_NUMBER_MINOR 0 -#define API_VERSION_NUMBER_PATCH 6 +#define API_VERSION_NUMBER_PATCH 7 namespace WPEFramework { diff --git a/Monitor/Monitor.h b/Monitor/Monitor.h index 0f2c570ff3..148e331f07 100644 --- a/Monitor/Monitor.h +++ b/Monitor/Monitor.h @@ -811,7 +811,7 @@ namespace Plugin { _service->Notify(message); _parent.event_action(callsign, "Activate", "Automatic"); TRACE(Trace::Error, (_T("Restarting %s again because we detected it misbehaved."), callsign.c_str())); - Core::IWorkerPool::Instance().Schedule(Core::Time::Now(), PluginHost::IShell::Job::Create(service, PluginHost::IShell::ACTIVATED, PluginHost::IShell::AUTOMATIC)); + Core::IWorkerPool::Instance().Schedule(Core::Time::Now().Add(5000), PluginHost::IShell::Job::Create(service, PluginHost::IShell::ACTIVATED, PluginHost::IShell::AUTOMATIC)); } } } diff --git a/PersistentStore/PersistentStore.cpp b/PersistentStore/PersistentStore.cpp index db2503746e..e3a9f99d7f 100644 --- a/PersistentStore/PersistentStore.cpp +++ b/PersistentStore/PersistentStore.cpp @@ -112,6 +112,9 @@ namespace Plugin { _store = _service->Root(_connectionId, RPC::CommunicationTimeOut, _T("PersistentStoreImplementation")); if (_store != nullptr) { _store2 = _store->QueryInterface(); + if (_store2 != nullptr) { + _store2->Register(&_store2Sink); + } _storeCache = _store->QueryInterface(); _storeInspector = _store->QueryInterface(); _storeLimit = _store->QueryInterface(); @@ -137,6 +140,7 @@ namespace Plugin { if (_store != nullptr) { if (_store2 != nullptr) { + _store2->Unregister(&_store2Sink); _store2->Release(); _store2 = nullptr; } diff --git a/PersistentStore/PersistentStore.h b/PersistentStore/PersistentStore.h index 7af934b241..91c50655d2 100644 --- a/PersistentStore/PersistentStore.h +++ b/PersistentStore/PersistentStore.h @@ -61,6 +61,38 @@ namespace Plugin { Core::JSON::DecUInt64 Limit; }; + class Store2Notification : public Exchange::IStore2::INotification { + private: + Store2Notification(const Store2Notification&) = delete; + Store2Notification& operator=(const Store2Notification&) = delete; + + public: + explicit Store2Notification(PersistentStore& parent) + : _parent(parent) + { + } + ~Store2Notification() override = default; + + public: + void ValueChanged(const Exchange::IStore2::ScopeType scope, const string& ns, const string& key, const string& value) override + { + JsonData::PersistentStore::SetValueParamsData params; + params.Scope = JsonData::PersistentStore::ScopeType(scope); + params.Namespace = ns; + params.Key = key; + params.Value = value; + + _parent.event_onValueChanged(params); + } + + BEGIN_INTERFACE_MAP(Store2Notification) + INTERFACE_ENTRY(Exchange::IStore2::INotification) + END_INTERFACE_MAP + + private: + PersistentStore& _parent; + }; + class RemoteConnectionNotification : public RPC::IRemoteConnection::INotification { private: RemoteConnectionNotification() = delete; @@ -110,6 +142,7 @@ namespace Plugin { , _storeCache(nullptr) , _storeInspector(nullptr) , _storeLimit(nullptr) + , _store2Sink(*this) , _notification(*this) { RegisterAll(); @@ -164,6 +197,7 @@ namespace Plugin { Exchange::IStoreCache* _storeCache; Exchange::IStoreInspector* _storeInspector; Exchange::IStoreLimit* _storeLimit; + Core::Sink _store2Sink; Core::Sink _notification; }; diff --git a/PersistentStore/PersistentStoreJsonRpc.cpp b/PersistentStore/PersistentStoreJsonRpc.cpp index 023e818e57..a3b2858f8b 100644 --- a/PersistentStore/PersistentStoreJsonRpc.cpp +++ b/PersistentStore/PersistentStoreJsonRpc.cpp @@ -64,8 +64,6 @@ namespace Plugin { params.Ttl.Value()); if (result == Core::ERROR_NONE) { response.Success = true; - - event_onValueChanged(params); } return result; diff --git a/Tests/L2Tests/CMakeLists.txt b/Tests/L2Tests/CMakeLists.txt index 7ae983eaaa..e47cfae0b3 100755 --- a/Tests/L2Tests/CMakeLists.txt +++ b/Tests/L2Tests/CMakeLists.txt @@ -45,11 +45,18 @@ set_source_files_properties( target_link_libraries(${PROJECT_NAME} gmock_main ${CMAKE_INSTALL_PREFIX}/lib/libWPEFrameworkCore.so - ${CMAKE_INSTALL_PREFIX}/lib/libWPEFrameworkProtocols.so - ${CMAKE_INSTALL_PREFIX}/lib/libWPEFrameworkTracing.so ${CMAKE_INSTALL_PREFIX}/lib/libTestMocklib.so ) +# Thudner R4 will not generate libWPEFrameworkProtocols.so, libWPEFrameworkTracing.so. +# Thudner R2 will not generate libWPEFrameworkWebSocket.so. +if (USE_THUNDER_R4) +target_link_libraries(${PROJECT_NAME} ${CMAKE_INSTALL_PREFIX}/lib/libWPEFrameworkWebSocket.so) +else () +target_link_libraries(${PROJECT_NAME} ${CMAKE_INSTALL_PREFIX}/lib/libWPEFrameworkProtocols.so) +target_link_libraries(${PROJECT_NAME} ${CMAKE_INSTALL_PREFIX}/lib/libWPEFrameworkTracing.so) +endif (USE_THUNDER_R4) + target_compile_definitions(${PROJECT_NAME} PRIVATE CMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}" diff --git a/Tests/L2Tests/L2TestsPlugin/CMakeLists.txt b/Tests/L2Tests/L2TestsPlugin/CMakeLists.txt index bd64143f80..e23d256a0f 100755 --- a/Tests/L2Tests/L2TestsPlugin/CMakeLists.txt +++ b/Tests/L2Tests/L2TestsPlugin/CMakeLists.txt @@ -21,6 +21,9 @@ set(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME}) set(THUNDER_PORT 9998) find_package(${NAMESPACE}Plugins REQUIRED) +# We are not running VerifyContracts,Warehouse_L2Test tests for Thunder R4 as +# this work is not in this scope. In future we will enable these tests for Thunder R4. +if(NOT USE_THUNDER_R4) add_library(${MODULE_NAME} SHARED Module.cpp L2Tests.cpp @@ -30,6 +33,15 @@ add_library(${MODULE_NAME} SHARED tests/Telemetry_L2Test.cpp tests/Warehouse_L2Test.cpp tests/VerifyContracts.cpp) +else() +add_library(${MODULE_NAME} SHARED + Module.cpp + L2Tests.cpp + L2TestsMock.cpp + tests/SystemService_L2Test.cpp + tests/UsbAccess_L2Test.cpp + tests/Telemetry_L2Test.cpp) +endif(NOT USE_THUNDER_R4) set_target_properties(${MODULE_NAME} PROPERTIES CXX_STANDARD 11 diff --git a/UserSettings/CMakeLists.txt b/UserSettings/CMakeLists.txt index 02f848239a..e0c39d2e71 100755 --- a/UserSettings/CMakeLists.txt +++ b/UserSettings/CMakeLists.txt @@ -49,7 +49,24 @@ add_library(${PLUGIN_IMPLEMENTATION} SHARED UserSettingsImplementation.cpp Module.cpp) + +find_path(RBUS_API_HEADER NAMES rbus.h PATH_SUFFIXES rbus) + +if (NOT ${RBUS_API_HEADER} STREQUAL "RBUS_API_HEADER-NOTFOUND") + message("Found rbus.h ${RBUS_API_HEADER}") + add_definitions (-DHAS_RBUS) + set(RBUS_API_HEADERS ${RBUS_API_HEADER}) +find_library(RBUS_LIBRARY NAMES rbus) +endif() + +set(RBUS_LIBRARIES "") +if (NOT ${RBUS_LIBRARY} STREQUAL "RBUS_LIBRARY-NOTFOUND") + set(RBUS_LIBRARIES ${RBUS_LIBRARY}) +endif() + + include_directories( + ${RBUS_API_HEADERS} ../helpers) set_target_properties(${PLUGIN_IMPLEMENTATION} PROPERTIES @@ -59,7 +76,8 @@ set_target_properties(${PLUGIN_IMPLEMENTATION} PROPERTIES target_link_libraries(${PLUGIN_IMPLEMENTATION} PRIVATE CompileSettingsDebug::CompileSettingsDebug - ${NAMESPACE}Plugins::${NAMESPACE}Plugins) + ${NAMESPACE}Plugins::${NAMESPACE}Plugins + ${RBUS_LIBRARIES}) install(TARGETS ${PLUGIN_IMPLEMENTATION} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/${STORAGE_DIRECTORY}/plugins) diff --git a/UserSettings/UserSettings.h b/UserSettings/UserSettings.h index cdc83d4312..7ad29fd87e 100755 --- a/UserSettings/UserSettings.h +++ b/UserSettings/UserSettings.h @@ -104,6 +104,12 @@ namespace Plugin { Exchange::JUserSettings::Event::OnPreferredClosedCaptionServiceChanged(_parent, service); } + void OnPrivacyModeChanged(const string &privacyMode) override + { + LOGINFO("PrivacyModeChanged: %s\n", privacyMode.c_str()); + Exchange::JUserSettings::Event::OnPrivacyModeChanged(_parent, privacyMode); + } + private: UserSettings& _parent; }; diff --git a/UserSettings/UserSettingsImplementation.cpp b/UserSettings/UserSettingsImplementation.cpp index 5dd186fd0b..a3883a0b0e 100755 --- a/UserSettings/UserSettingsImplementation.cpp +++ b/UserSettings/UserSettingsImplementation.cpp @@ -31,6 +31,12 @@ #define USERSETTINGS_CAPTIONS_KEY "captions" #define USERSETTINGS_PREFERRED_CAPTIONS_LANGUAGES_KEY "preferredCaptionsLanguages" #define USERSETTINGS_PREFERRED_CLOSED_CAPTIONS_SERVICE_KEY "preferredClosedCaptionsService" +#define USERSETTINGS_PRIVACY_MODE_KEY "privacyMode" + +#ifdef HAS_RBUS +#define RBUS_COMPONENT_NAME "UserSettingsThunderPlugin" +#define RBUS_PRIVACY_MODE_EVENT_NAME "Device.X_RDKCENTRAL-COM_UserSettings.PrivacyModeChanged" +#endif namespace WPEFramework { namespace Plugin { @@ -45,6 +51,9 @@ UserSettingsImplementation::UserSettingsImplementation() , _remotStoreObject(nullptr) , _storeNotification(*this) , _registeredEventHandlers(false) +#ifdef HAS_RBUS +, _rbusHandleStatus(RBUS_ERROR_NOT_INITIALIZED) +#endif { LOGINFO("Create UserSettingsImplementation Instance"); @@ -122,6 +131,15 @@ UserSettingsImplementation::~UserSettingsImplementation() _remotStoreObject->Release(); } _registeredEventHandlers = false; + +#ifdef HAS_RBUS + if (RBUS_ERROR_SUCCESS == _rbusHandleStatus) + { + rbus_close(_rbusHandle); + _rbusHandleStatus = RBUS_ERROR_NOT_INITIALIZED; + } + +#endif } void UserSettingsImplementation::registerEventHandlers() @@ -246,6 +264,14 @@ void UserSettingsImplementation::Dispatch(Event event, const JsonValue params) } break; + case PRIVACY_MODE_CHANGED: + while (index != _userSettingNotification.end()) + { + (*index)->OnPrivacyModeChanged(params.String()); + ++index; + } + break; + default: break; } @@ -281,6 +307,10 @@ void UserSettingsImplementation::ValueChanged(const Exchange::IStore2::ScopeType { dispatchEvent(PREFERRED_CLOSED_CAPTIONS_SERVICE_CHANGED, JsonValue((string)value)); } + else if((ns.compare(USERSETTINGS_NAMESPACE) == 0) && (key.compare(USERSETTINGS_PRIVACY_MODE_KEY) == 0)) + { + dispatchEvent(PRIVACY_MODE_CHANGED, JsonValue((string)value)); + } else { LOGERR("Not supported"); @@ -550,5 +580,97 @@ uint32_t UserSettingsImplementation::GetPreferredClosedCaptionService(string &se return status; } + +uint32_t UserSettingsImplementation::SetPrivacyMode(const string& privacyMode) +{ + uint32_t status = Core::ERROR_GENERAL; + + LOGINFO("privacyMode: %s", privacyMode.c_str()); + + if (privacyMode != "SHARE" && privacyMode != "DO_NOT_SHARE") + { + LOGERR("Wrong privacyMode value: '%s', returning default", privacyMode.c_str()); + return status; + } + + _adminLock.Lock(); + + ASSERT (nullptr != _remotStoreObject); + + if (nullptr != _remotStoreObject) + { + uint32_t ttl = 0; + string oldPrivacyMode; + status = _remotStoreObject->GetValue(Exchange::IStore2::ScopeType::DEVICE, USERSETTINGS_NAMESPACE, USERSETTINGS_PRIVACY_MODE_KEY, oldPrivacyMode, ttl); + LOGINFO("oldPrivacyMode: %s", oldPrivacyMode.c_str()); + + if (privacyMode != oldPrivacyMode) + { +#ifdef HAS_RBUS + if (Core::ERROR_NONE == status) + { + if (RBUS_ERROR_SUCCESS != _rbusHandleStatus) + { + _rbusHandleStatus = rbus_open(&_rbusHandle, RBUS_COMPONENT_NAME); + } + + if (RBUS_ERROR_SUCCESS == _rbusHandleStatus) + { + rbusValue_t value; + rbusSetOptions_t opts = {true, 0}; + + rbusValue_Init(&value); + rbusValue_SetString(value, privacyMode.c_str()); + int rc = rbus_set(_rbusHandle, RBUS_PRIVACY_MODE_EVENT_NAME, value, &opts); + if (rc != RBUS_ERROR_SUCCESS) + { + std::stringstream str; + str << "Failed to set property " << RBUS_PRIVACY_MODE_EVENT_NAME << ": " << rc; + LOGERR("%s", str.str().c_str()); + } + rbusValue_Release(value); + } + else + { + std::stringstream str; + str << "rbus_open failed with error code " << _rbusHandleStatus; + LOGERR("%s", str.str().c_str()); + } + } +#endif + status = _remotStoreObject->SetValue(Exchange::IStore2::ScopeType::DEVICE, USERSETTINGS_NAMESPACE, USERSETTINGS_PRIVACY_MODE_KEY, privacyMode, 0); + } + } + + _adminLock.Unlock(); + + return status; +} + +uint32_t UserSettingsImplementation::GetPrivacyMode(string &privacyMode) const +{ + uint32_t status = Core::ERROR_GENERAL; + std::string value = ""; + uint32_t ttl = 0; + + _adminLock.Lock(); + + ASSERT (nullptr != _remotStoreObject); + + if (nullptr != _remotStoreObject) + { + status = _remotStoreObject->GetValue(Exchange::IStore2::ScopeType::DEVICE, USERSETTINGS_NAMESPACE, USERSETTINGS_PRIVACY_MODE_KEY, privacyMode, ttl); + if (privacyMode != "SHARE" && privacyMode != "DO_NOT_SHARE") + { + LOGWARN("Wrong privacyMode value: '%s', returning default", privacyMode.c_str()); + privacyMode = "SHARE"; + } + } + + _adminLock.Unlock(); + + return status; +} + } // namespace Plugin } // namespace WPEFramework diff --git a/UserSettings/UserSettingsImplementation.h b/UserSettings/UserSettingsImplementation.h index 83d967627b..d2cb8169ed 100755 --- a/UserSettings/UserSettingsImplementation.h +++ b/UserSettings/UserSettingsImplementation.h @@ -30,6 +30,10 @@ #include #include +#ifdef HAS_RBUS +#include "rbus.h" +#endif + namespace WPEFramework { namespace Plugin { class UserSettingsImplementation : public Exchange::IUserSettings{ @@ -82,7 +86,8 @@ namespace Plugin { PRESENTATION_LANGUAGE_CHANGED, CAPTIONS_CHANGED, PREFERRED_CAPTIONS_LANGUAGE_CHANGED, - PREFERRED_CLOSED_CAPTIONS_SERVICE_CHANGED + PREFERRED_CLOSED_CAPTIONS_SERVICE_CHANGED, + PRIVACY_MODE_CHANGED }; class EXTERNAL Job : public Core::IDispatch { @@ -139,6 +144,8 @@ namespace Plugin { uint32_t GetPreferredCaptionsLanguages(string &preferredLanguages) const override; uint32_t SetPreferredClosedCaptionService(const string& service) override; uint32_t GetPreferredClosedCaptionService(string &service) const override; + uint32_t SetPrivacyMode(const string& privacyMode) override; + uint32_t GetPrivacyMode(string &privacyMode) const override; void registerEventHandlers(); void ValueChanged(const Exchange::IStore2::ScopeType scope, const string& ns, const string& key, const string& value); @@ -153,6 +160,10 @@ namespace Plugin { Core::Sink _storeNotification; bool _registeredEventHandlers; +#ifdef HAS_RBUS + rbusError_t _rbusHandleStatus; + rbusHandle_t _rbusHandle; +#endif void dispatchEvent(Event, const JsonValue ¶ms); void Dispatch(Event event, const JsonValue params); diff --git a/WebKitBrowser/WebKitImplementation.cpp b/WebKitBrowser/WebKitImplementation.cpp index c21337fa64..9e1e5977bb 100644 --- a/WebKitBrowser/WebKitImplementation.cpp +++ b/WebKitBrowser/WebKitImplementation.cpp @@ -2689,6 +2689,15 @@ static GSourceFuncs _handlerIntervention = } browser->OnLoadFailed(failingURI); } + static void postExitJob() + { + struct ExitJob : public Core::IDispatch + { + virtual void Dispatch() { exit(1); } + }; + + Core::IWorkerPool::Instance().Submit(Core::ProxyType(Core::ProxyType::Create())); + } static void webProcessTerminatedCallback(VARIABLE_IS_NOT_USED WebKitWebView* webView, WebKitWebProcessTerminationReason reason, WebKitImplementation* browser) { switch (reason) { @@ -2703,11 +2712,7 @@ static GSourceFuncs _handlerIntervention = break; } g_signal_handlers_block_matched(webView, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, browser); - struct ExitJob : public Core::IDispatch - { - virtual void Dispatch() { exit(1); } - }; - Core::IWorkerPool::Instance().Submit(Core::ProxyType(Core::ProxyType::Create())); + postExitJob(); } static void closeCallback(VARIABLE_IS_NOT_USED WebKitWebView* webView, WebKitImplementation* browser) { @@ -3549,7 +3554,9 @@ static GSourceFuncs _handlerIntervention = void DeactivateBrowser(PluginHost::IShell::reason reason) { ASSERT(_service != nullptr); - Core::IWorkerPool::Instance().Submit(PluginHost::IShell::Job::Create(_service, PluginHost::IShell::DEACTIVATED, reason)); + const char *reasonStr = Core::EnumerateType(reason).Data(); + SYSLOG(Logging::Fatal, (_T("Posting a job to exit, reason - %s"), (reasonStr ? reasonStr : ""))); + postExitJob(); } private: diff --git a/docs/api/MonitorPlugin.md b/docs/api/MonitorPlugin.md index 139d55809c..c84e279e5d 100644 --- a/docs/api/MonitorPlugin.md +++ b/docs/api/MonitorPlugin.md @@ -2,7 +2,7 @@ # Monitor Plugin -**Version: [1.0.6](https://github.com/rdkcentral/rdkservices/blob/main/Monitor/CHANGELOG.md)** +**Version: [1.0.7](https://github.com/rdkcentral/rdkservices/blob/main/Monitor/CHANGELOG.md)** A Monitor plugin for Thunder framework. diff --git a/files/0001-Add-TextToSpeech-Interface.patch b/files/0001-Add-TextToSpeech-Interface.patch new file mode 100644 index 0000000000..07273acd18 --- /dev/null +++ b/files/0001-Add-TextToSpeech-Interface.patch @@ -0,0 +1,29 @@ +Index: git/interfaces/ITextToSpeech.h +=================================================================== +--- git.orig/interfaces/ITextToSpeech.h ++++ git/interfaces/ITextToSpeech.h +@@ -65,6 +65,7 @@ namespace Exchange { + + virtual void Register(ITextToSpeech::INotification* sink) = 0; + virtual void Unregister(ITextToSpeech::INotification* sink) = 0; ++ virtual void RegisterWithCallsign(const string callsign,ITextToSpeech::INotification* sink) = 0; + + // @property + // @brief Query the status/enable tts +@@ -80,6 +81,7 @@ namespace Exchange { + virtual uint32_t SetFallbackText(const string scenario,const string value) = 0; + virtual uint32_t SetAPIKey(const string apikey) = 0; + virtual uint32_t SetPrimaryVolDuck(const uint8_t prim) = 0; ++ virtual uint32_t SetACL(const string method,const string apps) = 0; + + // @brief Retrieve tts configuration attributes + // @param config tts configuration +@@ -94,7 +96,7 @@ namespace Exchange { + // @param text for conversion + // @param speechid returns id for the text + // @param status return status +- virtual uint32_t Speak(const string text,uint32_t &speechid/* @out */,TTSErrorDetail &status/* @out */) = 0; ++ virtual uint32_t Speak(const string callsign,const string text,uint32_t &speechid/* @out */,TTSErrorDetail &status/* @out */) = 0; + + // @brief Cancel the speech + // @param speechid id of text to be cancelled diff --git a/files/0003-R4.4.1-LocationSync-compilation-error.patch b/files/0003-R4.4.1-LocationSync-compilation-error.patch new file mode 100755 index 0000000000..a131f44a24 --- /dev/null +++ b/files/0003-R4.4.1-LocationSync-compilation-error.patch @@ -0,0 +1,1037 @@ +diff --git a/LocationSync/CMakeLists.txt b/LocationSync/CMakeLists.txt +index 7a5418b3..87941026 100644 +--- a/LocationSync/CMakeLists.txt ++++ b/LocationSync/CMakeLists.txt +@@ -21,15 +21,19 @@ cmake_minimum_required(VERSION 3.3) + + find_package(WPEFramework) + +-set(PLUGIN_NAME LocationSync) ++project_version(1.0.0) ++ + set(MODULE_NAME ${NAMESPACE}${PROJECT_NAME}) + ++message("Setup ${MODULE_NAME} v${PROJECT_VERSION}") ++ + set(PLUGIN_LOCATIONSYNC_AUTOSTART "true" CACHE STRING "Automatically start LocationSync plugin") + set(PLUGIN_LOCATIONSYNC_URI "location.webplatformforembedded.org" CACHE STRING "URI to request the location information") +-set(PLUGIN_LOCATIONSYNC_STARTUPORDER "" CACHE STRING "To configure startup order of LocationSync plugin") ++set(PLUGIN_LOCATIONSYNC_OVERRIDE_TIMEZONE CACHE STRING "Override Timezone value") + + find_package(${NAMESPACE}Plugins REQUIRED) + find_package(CompileSettingsDebug CONFIG REQUIRED) ++find_package(${NAMESPACE}Definitions REQUIRED) + + add_library(${MODULE_NAME} SHARED + Module.cpp +@@ -42,12 +46,15 @@ set_target_properties(${MODULE_NAME} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + ++target_compile_options (${MODULE_NAME} PRIVATE -Wno-psabi) ++ + target_link_libraries(${MODULE_NAME} + PRIVATE + CompileSettingsDebug::CompileSettingsDebug +- ${NAMESPACE}Plugins::${NAMESPACE}Plugins) ++ ${NAMESPACE}Plugins::${NAMESPACE}Plugins ++ ${NAMESPACE}Definitions::${NAMESPACE}Definitions) + + install(TARGETS ${MODULE_NAME} + DESTINATION lib/${STORAGE_DIRECTORY}/plugins) + +-write_config(${PLUGIN_NAME}) ++write_config() +diff --git a/LocationSync/LocationService.cpp b/LocationSync/LocationService.cpp +index 075ffe7a..6c9e6b0e 100644 +--- a/LocationSync/LocationService.cpp ++++ b/LocationSync/LocationService.cpp +@@ -20,7 +20,6 @@ + #include "LocationService.h" + + namespace WPEFramework { +- + namespace Plugin { + + struct IGeography { +@@ -30,8 +29,8 @@ namespace Plugin { + virtual string City() const = 0; + virtual string Region() const = 0; + virtual string TimeZone() const = 0; +- virtual string Latitude() const = 0; +- virtual string Longitude() const = 0; ++ virtual int32_t Latitude() const = 0; ++ virtual int32_t Longitude() const = 0; + virtual string IP() const = 0; + virtual void FromString(const string&) = 0; + }; +@@ -44,9 +43,9 @@ namespace Plugin { + // "region":"GE", + // "regionName":"Gelderland", + // "city":"Wijchen", +- // "lat":"51.798", +- // "lon":"5.726", + // "zip":"6605", ++ // "lat":51.798, ++ // "lon":5.726, + // "timezone":"Europe/Amsterdam", + // "isp":"T-Mobile Thuis BV", + // "org":"T-Mobile Thuis BV", +@@ -66,17 +65,17 @@ namespace Plugin { + , City() + , Region() + , TimeZone() +- , Latitude() +- , Longitude() + , IP() ++ , Latitude(51.832547) ++ , Longitude(5.674899) + { + Add(_T("country"), &Country); + Add(_T("city"), &City); + Add(_T("regionName"), &Region); + Add(_T("timezone"), &TimeZone); +- Add(_T("latitude"), &Latitude); +- Add(_T("longitude"), &Longitude); + Add(_T("query"), &IP); ++ Add(_T("lat"), &Latitude); ++ Add(_T("lon"), &Longitude); + } + ~Data() override = default; + +@@ -85,9 +84,9 @@ namespace Plugin { + Core::JSON::String City; + Core::JSON::String Region; + Core::JSON::String TimeZone; +- Core::JSON::String Latitude; +- Core::JSON::String Longitude; + Core::JSON::String IP; ++ Core::JSON::Double Latitude; ++ Core::JSON::Double Longitude; + }; + + public: +@@ -114,13 +113,13 @@ namespace Plugin { + { + return (_data.TimeZone.Value()); + } +- string Latitude() const override ++ int32_t Latitude() const override + { +- return (_data.Latitude.Value()); ++ return (static_cast(_data.Latitude.Value() * 1000000)); + } +- string Longitude() const override ++ int32_t Longitude() const override + { +- return (_data.Longitude.Value()); ++ return (static_cast(_data.Longitude.Value() * 1000000)); + } + string IP() const override + { +@@ -167,27 +166,41 @@ namespace Plugin { + , City() + , Region() + , TimeZone() +- , Latitude() +- , Longitude() + , _LL() + { + Add(_T("country"), &Country); + Add(_T("city"), &City); + Add(_T("region"), &Region); + Add(_T("tz"), &TimeZone); +- Add(_T("lat"), &Latitude); +- Add(_T("lon"), &Longitude); + Add(_T("ll"), &_LL); + } + ~Geography() override = default; + + public: ++ int32_t Latitude() const { ++ int32_t result = 51832547; ++ Core::JSON::ArrayType::ConstIterator index = _LL.Elements(); ++ ++ if (index.Next() == true) { ++ result = static_cast(index.Current() * 1000000); ++ } ++ ++ return (result); ++ } ++ int32_t Longitude() const { ++ int32_t result = 5674899; ++ Core::JSON::ArrayType::ConstIterator index = _LL.Elements(); ++ ++ if ( (index.Next() == true) && (index.Next() == true) ) { ++ result = static_cast(index.Current() * 1000000); ++ } ++ ++ return (result); ++ } + Core::JSON::String Country; + Core::JSON::String City; + Core::JSON::String Region; + Core::JSON::String TimeZone; +- Core::JSON::String Latitude; +- Core::JSON::String Longitude; + + private: + Core::JSON::ArrayType _LL; +@@ -239,13 +252,13 @@ namespace Plugin { + { + return (_data.Geo.TimeZone.Value()); + } +- string Latitude() const override ++ int32_t Latitude() const override + { +- return (_data.Geo.Latitude.Value()); ++ return (_data.Geo.Latitude()); + } +- string Longitude() const ++ int32_t Longitude() const override + { +- return (_data.Geo.Longitude.Value()); ++ return (_data.Geo.Longitude()); + } + string IP() const override + { +@@ -254,10 +267,10 @@ namespace Plugin { + void FromString(const string& data) override { + TRACE(Trace::Information, (_T("Metrological: Received a response: [%s]!"), data.c_str())); + +- _data.IElement::FromString(data); ++ _data.IElement::FromString(data); + +- string parsed; +- _data.IElement::ToString(parsed); ++ string parsed; ++ _data.IElement::ToString(parsed); + TRACE(Trace::Information, (_T("Metrological: reverted response: [%s]!"), parsed.c_str())); + } + +@@ -311,34 +324,29 @@ namespace Plugin { + return (index < (sizeof(g_domainFactory) / sizeof(DomainConstructor)) ? &(g_domainFactory[index]) : nullptr); + } + +-#ifdef __WINDOWS__ +-#pragma warning(disable : 4355) +-#endif +-#ifndef USE_THUNDER_R4 +- LocationService::LocationService(Core::IDispatchType* callback) +-#else ++PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) + LocationService::LocationService(Core::IDispatch* callback) +-#endif /* USE_THUNDER_R4 */ +- : BaseClass(1, g_Factory, false, Core::NodeId(), Core::NodeId(), 256, 1024) ++ : BaseClass(1, g_Factory, false, Core::NodeId(), Core::NodeId(), 256, (1024 * 2)) + , _adminLock() + , _state(IDLE) + , _remoteId() + , _sourceNode() + , _tryInterval(0) ++ , _retries(UINT32_MAX) + , _callback(callback) + , _publicIPAddress() + , _timeZone() + , _country() + , _region() + , _city() ++ , _latitude() ++ , _longitude() + , _activity(*this) + , _infoCarrier() + , _request(Core::ProxyType::Create()) + { + } +-#ifdef __WINDOWS__ +-#pragma warning(default : 4355) +-#endif ++POP_WARNING() + + LocationService::~LocationService() /* override */ + { +@@ -376,7 +384,11 @@ namespace Plugin { + _state = ACTIVE; + + // it runs till zero, so subtract by definition 1 :-) +- _retries = (retries - 1); ++ // If retires is UINT32_MAX it means retry unlimited ++ if (retries != UINT32_MAX) { ++ _retries = (retries - 1); ++ } ++ + _tryInterval = retryTimeSpan * 1000; // Move from seconds to mS. + _request->Host = hostName; + _request->Verb = Web::Request::HTTP_GET; +@@ -440,11 +452,7 @@ namespace Plugin { + + ASSERT(_infoCarrier.IsValid() == true); + +-#ifndef USE_THUNDER_R4 +- element->Body(Core::proxy_cast(Core::ProxyType::Create())); +-#else + element->Body(Core::ProxyType(Core::ProxyType::Create())); +-#endif + } + } + +@@ -465,6 +473,8 @@ namespace Plugin { + _country = _infoCarrier->Country(); + _region = _infoCarrier->Region(); + _city = _infoCarrier->City(); ++ _latitude = _infoCarrier->Latitude(); ++ _longitude = _infoCarrier->Longitude(); + + if (_state == IPV6_INPROGRESS) { + +@@ -533,6 +543,7 @@ namespace Plugin { + void LocationService::Dispatch() + { + uint32_t result = Core::infinite; ++ TRACE(Trace::Information, (_T("LocationService: job is dispatched"))); + + if ((Close(100) != Core::ERROR_NONE) || (IsClosed() == false)) { + +@@ -542,7 +553,12 @@ namespace Plugin { + _adminLock.Lock(); + + if (_state == IPV4_INPROGRESS) { +- _state = (_retries-- == 0 ? FAILED : ACTIVE); ++ if(_retries != UINT32_MAX) { ++ _state = (_retries-- == 0 ? FAILED : ACTIVE); ++ } ++ else { ++ _state = ACTIVE; ++ } + } + + if ((_state != LOADED) && (_state != FAILED)) { +@@ -551,10 +567,10 @@ namespace Plugin { + + if (remote.IsValid() == false) { + +- TRACE(Trace::Warning, (_T("DNS resolving failed. Sleep for %d mS for attempt %d"), _tryInterval, _retries)); ++ TRACE(Trace::Warning, (_T("DNS resolving failed. Sleep for %d mS for attempt %u"), _tryInterval, _retries)); + + // Name resolving does not even work. Retry this after a few seconds, if we still can.. +- if (_retries-- == 0) ++ if (_retries != UINT32_MAX && _retries-- == 0) + _state = FAILED; + else + result = _tryInterval; +@@ -569,12 +585,12 @@ namespace Plugin { + + if ((status == Core::ERROR_NONE) || (status == Core::ERROR_INPROGRESS)) { + +- TRACE(Trace::Information, (_T("Sending out a network package on %s. Attempt: %d"), (remote.Type() == Core::NodeId::TYPE_IPV6 ? _T("IPv6") : _T("IPv4")), _retries)); ++ TRACE(Trace::Information, (_T("Sending out a network package on %s. Attempt: %u"), (remote.Type() == Core::NodeId::TYPE_IPV6 ? _T("IPv6") : _T("IPv4")), _retries)); + + // We need to get a response in the given time.. + result = _tryInterval; + } else { +- TRACE(Trace::Warning, (_T("Failed on network %s. Reschedule for the next attempt: %d"), (remote.Type() == Core::NodeId::TYPE_IPV6 ? _T("IPv6") : _T("IPv4")), _retries)); ++ TRACE(Trace::Warning, (_T("Failed on network %s. Reschedule for the next attempt: %u"), (remote.Type() == Core::NodeId::TYPE_IPV6 ? _T("IPv6") : _T("IPv4")), _retries)); + + // Seems we could not open this connection, move on to the next attempt. + Close(0); +@@ -599,11 +615,7 @@ namespace Plugin { + + // See if we need rescheduling + if (result != Core::infinite) { +-#ifndef USE_THUNDER_R4 +- _activity.Schedule(Core::Time::Now().Add(result)); +-#else + _activity.Reschedule(Core::Time::Now().Add(result)); +-#endif /* USE_THUNDER_R4 */ + } + } + +diff --git a/LocationSync/LocationService.h b/LocationSync/LocationService.h +index 0381af73..d11ea71b 100644 +--- a/LocationSync/LocationService.h ++++ b/LocationSync/LocationService.h +@@ -28,7 +28,7 @@ namespace Plugin { + + struct IGeography; + +- class EXTERNAL LocationService ++ class LocationService + : public PluginHost::ISubSystem::ILocation, + public PluginHost::ISubSystem::IInternet, + public Web::WebLinkType&> { +@@ -53,11 +53,7 @@ namespace Plugin { + typedef Web::WebLinkType&> BaseClass; + + public: +-#ifndef USE_THUNDER_R4 +- LocationService(Core::IDispatchType* update); +-#else + LocationService(Core::IDispatch* update); +-#endif /* USE_THUNDER_R4 */ + ~LocationService() override; + + public: +@@ -71,6 +67,9 @@ namespace Plugin { + static uint32_t IsSupported(const string& remoteNode); + uint32_t Probe(const string& remoteNode, const uint32_t retries, const uint32_t retryTimeSpan); + void Stop(); ++ bool Valid() const { ++ return _state == LOADED; ++ } + + /* + * ------------------------------------------------------------------------------------------------------------ +@@ -106,6 +105,14 @@ namespace Plugin { + { + return (_city); + } ++ int32_t Latitude() const override ++ { ++ return (_latitude); ++ } ++ int32_t Longitude() const override ++ { ++ return (_longitude); ++ } + + private: + // Notification of a Partial Request received, time to attach a body.. +@@ -132,6 +139,8 @@ namespace Plugin { + string _country; + string _region; + string _city; ++ int32_t _latitude; ++ int32_t _longitude; + Core::WorkerPool::JobType _activity; + Core::ProxyType _infoCarrier; + Core::ProxyType _request; +diff --git a/LocationSync/LocationSync.conf.in b/LocationSync/LocationSync.conf.in +index ab5aa27e..04b90673 100644 +--- a/LocationSync/LocationSync.conf.in ++++ b/LocationSync/LocationSync.conf.in +@@ -1,9 +1,10 @@ +-precondition = ["Network"] + autostart = "@PLUGIN_LOCATIONSYNC_AUTOSTART@" +-startuporder = "@PLUGIN_LOCATIONSYNC_STARTUPORDER@" + + configuration = JSON() + + configuration.add("interval", 10) +-configuration.add("retries", 60) ++configuration.add("retries", 20) + configuration.add("source", "@PLUGIN_LOCATIONSYNC_URI@") ++configuration.add("timezone", "@PLUGIN_LOCATIONSYNC_OVERRIDE_TIMEZONE@") ++ ++ +diff --git a/LocationSync/LocationSync.cpp b/LocationSync/LocationSync.cpp +index 6e3ed999..3b464093 100644 +--- a/LocationSync/LocationSync.cpp ++++ b/LocationSync/LocationSync.cpp +@@ -19,51 +19,76 @@ + + #include "LocationSync.h" + +-#define API_VERSION_NUMBER_MAJOR 1 +-#define API_VERSION_NUMBER_MINOR 0 +-#define API_VERSION_NUMBER_PATCH 0 ++#include + + namespace WPEFramework { + namespace Plugin { + +- SERVICE_REGISTRATION(LocationSync, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); ++ namespace { ++ ++ static Metadata metadata( ++ // Version ++ 1, 0, 0, ++ // Preconditions ++ { subsystem::NETWORK }, ++ // Terminations ++ {}, ++ // Controls ++ { subsystem::INTERNET, subsystem::LOCATION } ++ ); ++ } + + static Core::ProxyPoolType responseFactory(4); + static Core::ProxyPoolType> jsonResponseFactory(4); + +-#ifdef __WINDOWS__ +-#pragma warning(disable : 4355) +-#endif ++namespace { ++ constexpr TCHAR FactorySetTimeZone[] = _T("Factory"); ++} ++ ++PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) + LocationSync::LocationSync() + : _skipURL(0) + , _source() + , _sink(this) + , _service(nullptr) ++ , _timezoneoverriden(false) ++ , _locationinfo() ++ , _adminLock() ++ , _timezoneoberservers() ++ , _activateOnFailure(true) + { +- RegisterAll(); +- } +-#ifdef __WINDOWS__ +-#pragma warning(default : 4355) +-#endif +- +- LocationSync::~LocationSync() /* override */ +- { +- UnregisterAll(); + } ++POP_WARNING() + + const string LocationSync::Initialize(PluginHost::IShell* service) /* override */ + { + string result; + Config config; + config.FromString(service->ConfigLine()); +- string version = service->Version(); + + if (LocationService::IsSupported(config.Source.Value()) == Core::ERROR_NONE) { ++ if( ( config.TimeZone.IsSet() == true ) && ( config.TimeZone.Value().empty() == false ) ) { ++ _locationinfo.TimeZone(config.TimeZone.Value()); ++ _timezoneoverriden = true; ++ UpdateSystemTimeZone(config.TimeZone.Value()); ++ } ++ ++ if( ( config.Latitude.IsSet() == true ) && ( config.Longitude.IsSet() == true ) ) { ++ _locationinfo.Latitude(config.Latitude.Value()); ++ _locationinfo.Longitude(config.Longitude.Value()); ++ } ++ + _skipURL = static_cast(service->WebPrefix().length()); + _source = config.Source.Value(); ++ _activateOnFailure = config.ActivateOnFailure.Value(); + _service = service; +- ++ _service->AddRef(); ++ + _sink.Initialize(config.Source.Value(), config.Interval.Value(), config.Retries.Value()); ++ ++ RegisterAll(); ++ Exchange::JTimeZone::Register(*this, this); ++ + } else { + result = _T("URL for retrieving location is incorrect !!!"); + } +@@ -74,9 +99,33 @@ namespace Plugin { + + void LocationSync::Deinitialize(PluginHost::IShell* service VARIABLE_IS_NOT_USED) /* override */ + { +- ASSERT(_service == service); ++ if (_service != nullptr) { ++ ASSERT(_service == service); ++ ++ UnregisterAll(); ++ Exchange::JTimeZone::Unregister(*this); ++ ++ _sink.Deinitialize(); ++ ++ Config config; ++ config.FromString(_service->ConfigLine()); ++ ++ Exchange::Controller::IConfiguration* controller = nullptr; ++ if ( (_timezoneoverriden == true) && ++ ( _locationinfo.TimeZone() != config.TimeZone.Value() ) && ++ ( ( controller = _service->QueryInterfaceByCallsign(_T("")) ) != nullptr ) ++ ) { ++ config.TimeZone = _locationinfo.TimeZone(); ++ string newconfig; ++ config.ToString(newconfig); ++ _service->ConfigLine(newconfig); ++ controller->Persist(); ++ controller->Release(); ++ } + +- _sink.Deinitialize(); ++ _service->Release(); ++ _service = nullptr; ++ } + } + + string LocationSync::Information() const /* override */ +@@ -120,11 +169,7 @@ namespace Plugin { + response->City = location->City(); + + result->ContentType = Web::MIMETypes::MIME_JSON; +-#ifndef USE_THUNDER_R4 +- result->Body(Core::proxy_cast(response)); +-#else + result->Body(Core::ProxyType(response)); +-#endif /* USE_THUNDER_R4 */ + } else { + result->ErrorCode = Web::STATUS_SERVICE_UNAVAILABLE; + result->Message = _T("Internet and Location Service not yet available"); +@@ -149,24 +194,148 @@ namespace Plugin { + return result; + } + ++ uint32_t LocationSync::Register(Exchange::ITimeZone::INotification* sink) { ++ _adminLock.Lock(); ++ TimeZoneObservers::iterator index = std::find(_timezoneoberservers.begin(), _timezoneoberservers.end(), sink); ++ ASSERT (index == _timezoneoberservers.end()); ++ if (index == _timezoneoberservers.end()) { ++ sink->AddRef(); ++ _timezoneoberservers.emplace_back(sink); ++ } ++ _adminLock.Unlock(); ++ return Core::ERROR_NONE; ++ } ++ ++ uint32_t LocationSync::Unregister(Exchange::ITimeZone::INotification* sink) { ++ _adminLock.Lock(); ++ TimeZoneObservers::iterator index = std::find(_timezoneoberservers.begin(), _timezoneoberservers.end(), sink); ++ ASSERT (index != _timezoneoberservers.end()); ++ if (index != _timezoneoberservers.end()) { ++ sink->Release(); ++ _timezoneoberservers.erase(index); ++ } ++ _adminLock.Unlock(); ++ return Core::ERROR_NONE; ++ } ++ ++ uint32_t LocationSync::TimeZone(string& timeZone /* @out */) const { ++ timeZone = CurrentTimeZone(); ++ return Core::ERROR_NONE; ++ } ++ ++ uint32_t LocationSync::TimeZone(const string& timeZone) { ++ ++ _adminLock.Lock(); ++ ++ _timezoneoverriden = true; ++ ++ if(_locationinfo.TimeZone() != timeZone) { ++ ++ _locationinfo.TimeZone(timeZone); ++ ++ _adminLock.Unlock(); ++ ++ UpdateSystemTimeZone(timeZone); ++ ++ // let's check if we need to update the subsystem. As there is no support in this plugin for unsetting the Location subsystem that is not taken into account ++ PluginHost::ISubSystem* subSystem = _service->SubSystems(); ++ ASSERT(subSystem != nullptr); ++ if(subSystem != nullptr) { ++ SetLocationSubsystem(*subSystem, true); ++ subSystem->Release(); ++ } ++ ++ NotifyTimeZoneChanged(timeZone); ++ ++ } else { ++ _adminLock.Unlock(); ++ } ++ ++ return Core::ERROR_NONE; ++ } ++ ++ string LocationSync::CurrentTimeZone() const { ++ Core::SafeSyncType guard(_adminLock); ++ return _locationinfo.TimeZone(); ++ } ++ ++ void LocationSync::NotifyTimeZoneChanged(const string& timezone) const { ++ _adminLock.Lock(); ++ for (auto observer : _timezoneoberservers) { ++ observer->TimeZoneChanged(timezone); ++ } ++ _adminLock.Unlock(); ++ ++ Exchange::JTimeZone::Event::TimeZoneChanged(const_cast(static_cast(*this)), timezone); ++ SYSLOG(Logging::Startup, (_T("TimeZone change to \"%s\", local date time is now %s."), timezone.c_str(), Core::Time::Now().ToRFC1123(true).c_str())); ++ } ++ ++ void LocationSync::SetLocationSubsystem(PluginHost::ISubSystem& subsystem, bool update) /* cannot be const due to subsystem Set*/ { ++ if(update == false) { ++ _adminLock.Lock(); ++ subsystem.Set(PluginHost::ISubSystem::LOCATION, &_locationinfo); ++ _adminLock.Unlock(); ++ } else { ++ _adminLock.Lock(); ++ if(subsystem.IsActive(PluginHost::ISubSystem::LOCATION) == true) { ++ subsystem.Set(PluginHost::ISubSystem::LOCATION, &_locationinfo); ++ } ++ _adminLock.Unlock(); ++ } ++ } ++ + void LocationSync::SyncedLocation() + { +- PluginHost::ISubSystem* subSystem = _service->SubSystems(); +- +- ASSERT(subSystem != nullptr); ++ if ((_sink.Location() != nullptr) && (_sink.Valid() == true)) { // _sink.Location() != nullptr basically is always true ++ string newtimezone; ++ _adminLock.Lock(); ++ if( (_locationinfo.Latitude() == std::numeric_limits::min()) || (_locationinfo.Longitude() == std::numeric_limits::min()) ) { ++ _locationinfo.Latitude(_sink.Location()->Latitude()); ++ _locationinfo.Longitude(_sink.Location()->Longitude()); ++ } ++ _locationinfo.Country(_sink.Location()->Country()); ++ _locationinfo.Region(_sink.Location()->Region()); ++ _locationinfo.City(_sink.Location()->City()); ++ if( (_sink.Location()->TimeZone().empty() == false) && (_timezoneoverriden == false) ) { ++ newtimezone = _sink.Location()->TimeZone(); ++ _locationinfo.TimeZone(newtimezone); ++ } ++ _adminLock.Unlock(); + +- if (subSystem != nullptr) { ++ if(newtimezone.empty() == false) { ++ UpdateSystemTimeZone(newtimezone); ++ NotifyTimeZoneChanged(newtimezone); ++ } ++ } else { ++ _adminLock.Lock(); ++ // if they are not overriden in the config and we cannot get them from the lookup, set them to default ++ if( (_locationinfo.Latitude() == std::numeric_limits::min()) || (_locationinfo.Longitude() == std::numeric_limits::min()) ) { ++ _locationinfo.Latitude(51977956); ++ _locationinfo.Longitude(5726384); ++ } ++ _adminLock.Unlock(); ++ } + +- subSystem->Set(PluginHost::ISubSystem::INTERNET, _sink.Network()); +- subSystem->Set(PluginHost::ISubSystem::LOCATION, _sink.Location()); +- subSystem->Release(); ++ PluginHost::ISubSystem* subSystem = _service->SubSystems(); ++ ASSERT(subSystem != nullptr); + +- if ((_sink.Location() != nullptr) && (_sink.Location()->TimeZone().empty() == false)) { +-#ifndef DISABLE_GEOGRAPHY_TIMEZONE +- Core::SystemInfo::SetEnvironment(_T("TZ"), _sink.Location()->TimeZone()); +-#endif ++ if (subSystem != nullptr) { ++ if( (_activateOnFailure == true) || (_sink.Location() == nullptr) || ( _sink.Valid() == true ) ) { // again _sink.Location() == nullptr should not happen but added to make it backards compatibe ++ subSystem->Set(PluginHost::ISubSystem::INTERNET, _sink.Network()); ++ SetLocationSubsystem(*subSystem, false); ++ event_locationchange(); ++ } else if(_timezoneoverriden == true) { // if the probing failed but the timezone was explicitely set we only set the location subsystem to pass on the timezone info ++ SetLocationSubsystem(*subSystem, false); + event_locationchange(); + } ++ subSystem->Release(); ++ } ++ } ++ ++ void LocationSync::UpdateSystemTimeZone(const string& newtimezone) ++ { ++ if( newtimezone != FactorySetTimeZone ) { ++ Core::SystemInfo::Instance().SetTimeZone(newtimezone, false); + } + } + +diff --git a/LocationSync/LocationSync.h b/LocationSync/LocationSync.h +index 4bfcf64f..de3b7faf 100644 +--- a/LocationSync/LocationSync.h ++++ b/LocationSync/LocationSync.h +@@ -20,14 +20,17 @@ + #ifndef LOCATIONSYNC_LOCATIONSYNC_H + #define LOCATIONSYNC_LOCATIONSYNC_H + ++#include "Module.h" + #include "LocationService.h" + #include +-#include "Module.h" ++#include ++ ++#include + + namespace WPEFramework { + namespace Plugin { + +- class LocationSync : public PluginHost::IPlugin, public PluginHost::IWeb, public PluginHost::JSONRPC { ++ class LocationSync : public PluginHost::IPlugin, public Exchange::ITimeZone, public PluginHost::IWeb, public PluginHost::JSONRPC { + public: + class Data : public Core::JSON::Container { + public: +@@ -69,9 +72,7 @@ namespace Plugin { + Notification& operator=(const Notification&) = delete; + + public: +-#ifdef __WINDOWS__ +-#pragma warning(disable : 4355) +-#endif ++PUSH_WARNING(DISABLE_WARNING_THIS_IN_MEMBER_INITIALIZER_LIST) + explicit Notification(LocationSync* parent) + : _parent(*parent) + , _source() +@@ -81,9 +82,7 @@ namespace Plugin { + { + ASSERT(parent != nullptr); + } +-#ifdef __WINDOWS__ +-#pragma warning(default : 4355) +-#endif ++POP_WARNING() + ~Notification() + { + _locator->Release(); +@@ -118,6 +117,11 @@ namespace Plugin { + { + return (_locator); + } ++ bool Valid() const { ++ ASSERT(_locator != nullptr); ++ return _locator->Valid(); ++ } ++ + + private: + inline uint32_t Probe() +@@ -125,7 +129,7 @@ namespace Plugin { + + ASSERT(_locator != nullptr); + +- return (_locator != nullptr ? _locator->Probe(_source, _retries, _interval) : static_cast(Core::ERROR_UNAVAILABLE)); ++ return (_locator != nullptr ? _locator->Probe(_source, (_retries == 0 ? UINT32_MAX : _retries), _interval) : static_cast(Core::ERROR_UNAVAILABLE)); + } + + void Dispatch() override +@@ -150,11 +154,19 @@ namespace Plugin { + Config() + : Interval(30) + , Retries(8) ++ , ActivateOnFailure(true) // as in some cases startup of the system depends on the Internet and Locatioin subsystems to be flagged this enables the activation of these subsystems even though probing was unsuccesfull (and for backward compatibility it is even the default) + , Source() ++ , TimeZone() ++ , Latitude(51977956) // Divider 1.000.000 ++ , Longitude(5726384) // Divider 1.000.000 + { + Add(_T("interval"), &Interval); + Add(_T("retries"), &Retries); ++ Add(_T("activateonfailure"), &ActivateOnFailure); + Add(_T("source"), &Source); ++ Add(_T("timezone"), &TimeZone); ++ Add(_T("latitude"), &Latitude); ++ Add(_T("longitude"), &Longitude); + } + ~Config() + { +@@ -163,22 +175,81 @@ namespace Plugin { + public: + Core::JSON::DecUInt16 Interval; + Core::JSON::DecUInt8 Retries; ++ Core::JSON::Boolean ActivateOnFailure; // as in some cases startup of the system depends on the Internet and Locatioin subsystems to be flagged this enables the activation of these subsystems even though probing was unsuccesfull (and for backward compatibility it is even the default) + Core::JSON::String Source; ++ Core::JSON::String TimeZone; ++ Core::JSON::DecSInt32 Latitude; ++ Core::JSON::DecSInt32 Longitude; + }; + +- private: ++ class LocationInfo : public PluginHost::ISubSystem::ILocation { ++ public: ++ LocationInfo(const LocationInfo&) = default; ++ LocationInfo(LocationInfo&&) = default; ++ LocationInfo& operator=(const LocationInfo&) = default; ++ LocationInfo& operator=(LocationInfo&&) = default; ++ ++ LocationInfo() ++ : _timeZone() ++ , _country() ++ , _region() ++ , _city() ++ , _latitude(std::numeric_limits::min()) ++ , _longitude(std::numeric_limits::min()) ++ { ++ } ++ LocationInfo(int32_t latitude, int32_t longitude) ++ : _timeZone() ++ , _country() ++ , _region() ++ , _city() ++ , _latitude(latitude) ++ , _longitude(longitude) ++ { ++ } ++ ~LocationInfo() override = default; ++ ++ public: ++ BEGIN_INTERFACE_MAP(Location) ++ INTERFACE_ENTRY(PluginHost::ISubSystem::ILocation) ++ END_INTERFACE_MAP ++ ++ public: ++ string TimeZone() const override { return _timeZone; } ++ void TimeZone(const string& timezone) { _timeZone = timezone; } ++ string Country() const override { return _country; } ++ void Country(const string& country) { _country = country; } ++ string Region() const override { return _region; } ++ void Region(const string& region) { _region = region; } ++ string City() const override { return _city; } ++ void City(const string& city) { _city = city; } ++ int32_t Latitude() const override { return _latitude; } ++ void Latitude(const int32_t latitude) { _latitude = latitude; } ++ int32_t Longitude() const override { return _longitude; } ++ void Longitude(const int32_t longitude) { _longitude = longitude; } ++ ++ private: ++ string _timeZone; ++ string _country; ++ string _region; ++ string _city; ++ int32_t _latitude; ++ int32_t _longitude; ++ }; ++ ++ public: + LocationSync(const LocationSync&) = delete; + LocationSync& operator=(const LocationSync&) = delete; + +- public: + LocationSync(); +- ~LocationSync() override; ++ ~LocationSync() override = default; + + // Build QueryInterface implementation, specifying all possible interfaces to be returned. + BEGIN_INTERFACE_MAP(LocationSync) +- INTERFACE_ENTRY(PluginHost::IPlugin) +- INTERFACE_ENTRY(PluginHost::IWeb) +- INTERFACE_ENTRY(PluginHost::IDispatcher) ++ INTERFACE_ENTRY(PluginHost::IPlugin) ++ INTERFACE_ENTRY(PluginHost::IWeb) ++ INTERFACE_ENTRY(PluginHost::IDispatcher) ++ INTERFACE_ENTRY(Exchange::ITimeZone) + END_INTERFACE_MAP + + public: +@@ -193,7 +264,17 @@ namespace Plugin { + void Inbound(Web::Request& request) override; + Core::ProxyType Process(const Web::Request& request) override; + ++ // ITimeZone methods ++ // ------------------------------------------------------------------------------------------------------- ++ uint32_t Register(ITimeZone::INotification* sink) override ; ++ uint32_t Unregister(ITimeZone::INotification* sink) override; ++ uint32_t TimeZone(string& timeZone ) const override; ++ uint32_t TimeZone(const string& timeZone) override; ++ + private: ++ string CurrentTimeZone() const; ++ void NotifyTimeZoneChanged(const string& timezone) const; ++ void SetLocationSubsystem(PluginHost::ISubSystem& subsystem, bool update); + void RegisterAll(); + void UnregisterAll(); + uint32_t endpoint_sync(); +@@ -201,12 +282,20 @@ namespace Plugin { + void event_locationchange(); + + void SyncedLocation(); ++ void UpdateSystemTimeZone(const string& timezone); + + private: ++ using TimeZoneObservers = std::list; ++ + uint16_t _skipURL; + string _source; + Core::Sink _sink; +- PluginHost::IShell* _service; ++ PluginHost::IShell* _service; ++ bool _timezoneoverriden; ++ Core::Sink _locationinfo; ++ mutable Core::CriticalSection _adminLock; ++ TimeZoneObservers _timezoneoberservers; ++ bool _activateOnFailure; + }; + + } // namespace Plugin +diff --git a/LocationSync/LocationSync.vcxproj b/LocationSync/LocationSync.vcxproj +index 4e236405..da21b2b0 100644 +--- a/LocationSync/LocationSync.vcxproj ++++ b/LocationSync/LocationSync.vcxproj +@@ -29,26 +29,26 @@ + + DynamicLibrary + true +- v142 ++ v143 + MultiByte + + + DynamicLibrary + false +- v142 ++ v143 + true + MultiByte + + + DynamicLibrary + true +- v142 ++ v143 + MultiByte + + + DynamicLibrary + false +- v142 ++ v143 + true + MultiByte + +@@ -107,6 +107,7 @@ + _CRT_SECURE_NO_WARNINGS;_DEBUG;WEBSERVER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(FrameworkPath);$(ContractsPath);$(WindowsPath);$(WindowsPath)zlib ++ true + + + Windows +@@ -123,6 +124,7 @@ + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;WEBSERVER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(FrameworkPath);$(ContractsPath);$(WindowsPath);$(WindowsPath)zlib ++ true + + + Windows +@@ -141,6 +143,7 @@ + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;WEBSERVER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(FrameworkPath);$(ContractsPath);$(WindowsPath);$(WindowsPath)zlib ++ true + + + Windows +@@ -161,6 +164,7 @@ + _CRT_SECURE_NO_WARNINGS;NDEBUG;WEBSERVER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + $(FrameworkPath);$(ContractsPath);$(WindowsPath);$(WindowsPath)zlib ++ true + + + Windows +diff --git a/LocationSync/LocationSyncJsonRpc.cpp b/LocationSync/LocationSyncJsonRpc.cpp +index 070eff0a..abcfb82c 100644 +--- a/LocationSync/LocationSyncJsonRpc.cpp ++++ b/LocationSync/LocationSyncJsonRpc.cpp +@@ -32,14 +32,14 @@ namespace Plugin { + + void LocationSync::RegisterAll() + { +- Register(_T("sync"), &LocationSync::endpoint_sync, this); +- Property(_T("location"), &LocationSync::get_location, nullptr, this); ++ PluginHost::JSONRPC::Register(_T("sync"), &LocationSync::endpoint_sync, this); ++ PluginHost::JSONRPC::Property(_T("location"), &LocationSync::get_location, nullptr, this); + } + + void LocationSync::UnregisterAll() + { +- Unregister(_T("sync")); +- Unregister(_T("location")); ++ PluginHost::JSONRPC::Unregister(_T("sync")); ++ PluginHost::JSONRPC::Unregister(_T("location")); + } + + // API implementation diff --git a/files/0003-R4.4.1-SystemAudioPlayer-compilation-error.patch b/files/0003-R4.4.1-SystemAudioPlayer-compilation-error.patch new file mode 100755 index 0000000000..2d1896f3e9 --- /dev/null +++ b/files/0003-R4.4.1-SystemAudioPlayer-compilation-error.patch @@ -0,0 +1,1336 @@ +diff --git a/SystemAudioPlayer/test/CMakeLists.txt b/SystemAudioPlayer/test/CMakeLists.txt +index ddff4dbd..93529bd3 100644 +--- a/SystemAudioPlayer/test/CMakeLists.txt ++++ b/SystemAudioPlayer/test/CMakeLists.txt +@@ -17,6 +17,7 @@ + + set(PLUGIN_NAME SystemAudioPlayerAPITest) + if (USE_THUNDER_R4) ++ find_package(${NAMESPACE}Core REQUIRED) + find_package(${NAMESPACE}COM REQUIRED) + else () + find_package(${NAMESPACE}Protocols REQUIRED) +@@ -36,7 +37,7 @@ set(LIBRARIES WPEFrameworkSecurityUtil) + target_include_directories(${PLUGIN_NAME} PRIVATE ../../helpers ../impl) + + if (USE_THUNDER_R4) +-target_link_libraries(${PLUGIN_NAME} PUBLIC ${LIBRARIES} PRIVATE ${NAMESPACE}COM::${NAMESPACE}COM ${NAMESPACE}WebSocket::${NAMESPACE}WebSocket) ++target_link_libraries(${PLUGIN_NAME} PUBLIC ${LIBRARIES} PRIVATE ${NAMESPACE}Core::${NAMESPACE}Core ${NAMESPACE}COM::${NAMESPACE}COM ${NAMESPACE}WebSocket::${NAMESPACE}WebSocket) + else () + target_link_libraries(${PLUGIN_NAME} PUBLIC ${LIBRARIES} + PRIVATE +diff --git a/SystemAudioPlayer/ProxyStubs_SystemAudioPlayer.cpp b/SystemAudioPlayer/ProxyStubs_SystemAudioPlayer.cpp +index fd3730f2..1c125e2c 100644 +--- a/SystemAudioPlayer/ProxyStubs_SystemAudioPlayer.cpp ++++ b/SystemAudioPlayer/ProxyStubs_SystemAudioPlayer.cpp +@@ -1,800 +1,708 @@ + // +-// ++// generated automatically from "ISystemAudioPlayer.h" + // +-// implements RPC proxy stubs for: +-// - class ISystemAudioPlayer +-// - class ISystemAudioPlayer::INotification ++// implements COM-RPC proxy stubs for: ++// - class Exchange::ISystemAudioPlayer ++// - class Exchange::ISystemAudioPlayer::INotification + // + +-#include "ISystemAudioPlayer.h" + #include "Module.h" ++#include "ISystemAudioPlayer.h" ++ ++#include + + namespace WPEFramework { + + namespace ProxyStubs { + +- using namespace Exchange; ++ PUSH_WARNING(DISABLE_WARNING_DEPRECATED_USE) ++ PUSH_WARNING(DISABLE_WARNING_TYPE_LIMITS) + + // ----------------------------------------------------------------- +- // STUB ++ // STUBS + // ----------------------------------------------------------------- + + // +- // ISystemAudioPlayer interface stub definitions ++ // Exchange::ISystemAudioPlayer interface stub definitions + // + // Methods: + // (0) virtual uint32_t Configure(PluginHost::IShell*) = 0 +- // (1) virtual void Register(ISystemAudioPlayer::INotification*) = 0 +- // (2) virtual void Unregister(ISystemAudioPlayer::INotification*) = 0 +- // (3) virtual uint32_t Open(const string &input, string &output /* @out */) = 0; +- // (4) virtual uint32_t Play(const string &input, string &output /* @out */) = 0; +- // (5) virtual uint32_t PlayBuffer(const string &input, string &output /* @out */) = 0; +- // (6) virtual uint32_t Pause(const string &input, string &output /* @out */) = 0; +- // (7) virtual uint32_t Resume(const string &input, string &output /* @out */) = 0; +- // (8) virtual uint32_t Stop(const string &input, string &output /* @out */) = 0; +- // (9) virtual uint32_t Close(const string &input, string &output /* @out */) = 0; +- // (10) virtual uint32_t SetMixerLevels(const string &input, string &output /* @out */) = 0; +- // (11) virtual uint32_t SetSmartVolControl(const string &input, string &output /* @out */) = 0; +- // (12) virtual uint32_t IsPlaying(const string &input, string &output /* @out */) = 0; ++ // (1) virtual void Register(Exchange::ISystemAudioPlayer::INotification*) = 0 ++ // (2) virtual void Unregister(Exchange::ISystemAudioPlayer::INotification*) = 0 ++ // (3) virtual uint32_t Open(const string&, string&) = 0 ++ // (4) virtual uint32_t Play(const string&, string&) = 0 ++ // (5) virtual uint32_t PlayBuffer(const string&, string&) = 0 ++ // (6) virtual uint32_t Pause(const string&, string&) = 0 ++ // (7) virtual uint32_t Resume(const string&, string&) = 0 ++ // (8) virtual uint32_t Stop(const string&, string&) = 0 ++ // (9) virtual uint32_t Close(const string&, string&) = 0 ++ // (10) virtual uint32_t SetMixerLevels(const string&, string&) = 0 ++ // (11) virtual uint32_t SetSmartVolControl(const string&, string&) = 0 ++ // (12) virtual uint32_t IsPlaying(const string&, string&) = 0 ++ // (13) virtual uint32_t Config(const string&, string&) = 0 ++ // (14) virtual uint32_t GetPlayerSessionId(const string&, string&) = 0 + // + +- ProxyStub::MethodHandler SystemAudioPlayerStubMethods[] = { +- // virtual uint32_t Configure(PluginHost::IShell*) = 0 ++ ProxyStub::MethodHandler ExchangeSystemAudioPlayerStubMethods[] = { ++ // (0) virtual uint32_t Configure(PluginHost::IShell*) = 0 + // + [](Core::ProxyType& channel, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); +- +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +-#ifndef USE_THUNDER_R4 +- RPC::instance_id param0 = reader.Number(); +-#else +- Core::instance_id param0 = reader.Number(); +-#endif /* USE_THUNDER_R4 */ +- PluginHost::IShell* param0_proxy = nullptr; +- ProxyStub::UnknownProxy* param0_proxy_inst = nullptr; +- if (param0 != 0) { +- param0_proxy_inst = RPC::Administrator::Instance().ProxyInstance(channel, param0, false, param0_proxy); +- ASSERT((param0_proxy_inst != nullptr) && (param0_proxy != nullptr) && "Failed to get instance of PluginHost::IShell proxy"); +- +- if ((param0_proxy_inst == nullptr) || (param0_proxy == nullptr)) { +- TRACE_L1("Failed to get instance of PluginHost::IShell proxy"); +- } ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const Core::instance_id serviceImplementation = reader.Number(); ++ ++ PluginHost::IShell* _service = nullptr; ++ ProxyStub::UnknownProxy* serviceProxy = nullptr; ++ if (serviceImplementation != 0) { ++ serviceProxy = RPC::Administrator::Instance().ProxyInstance(channel, serviceImplementation, false, _service); ++ ++ ASSERT((_service != nullptr) && (serviceProxy != nullptr)); + } + +- // write return value +- RPC::Data::Frame::Writer writer(message->Response().Writer()); ++ uint32_t result = implementation->Configure(_service); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Configure(param0_proxy); +- writer.Number(output); ++ RPC::Data::Frame::Writer writer(message->Response().Writer()); ++ writer.Number(result); + +- if (param0_proxy_inst != nullptr) { +- RPC::Administrator::Instance().Release(param0_proxy_inst, message->Response()); ++ if (serviceProxy != nullptr) { ++ RPC::Administrator::Instance().Release(serviceProxy, message->Response()); + } + }, + +- // virtual void Register(ISystemAudioPlayer::INotification*) = 0 ++ // (1) virtual void Register(Exchange::ISystemAudioPlayer::INotification*) = 0 + // + [](Core::ProxyType& channel, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); +- +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +-#ifndef USE_THUNDER_R4 +- RPC::instance_id param0 = reader.Number(); +-#else +- Core::instance_id param0 = reader.Number(); +-#endif /* USE_THUNDER_R4 */ +- ISystemAudioPlayer::INotification* param0_proxy = nullptr; +- ProxyStub::UnknownProxy* param0_proxy_inst = nullptr; +- if (param0 != 0) { +- param0_proxy_inst = RPC::Administrator::Instance().ProxyInstance(channel, param0, false, param0_proxy); +- ASSERT((param0_proxy_inst != nullptr) && (param0_proxy != nullptr) && "Failed to get instance of ISystemAudiPlayer::INotification proxy"); +- +- if ((param0_proxy_inst == nullptr) || (param0_proxy == nullptr)) { +- TRACE_L1("Failed to get instance of ISystemAudioPlayer::INotification proxy"); +- } ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const Core::instance_id sinkImplementation = reader.Number(); ++ ++ Exchange::ISystemAudioPlayer::INotification* _sink = nullptr; ++ ProxyStub::UnknownProxy* sinkProxy = nullptr; ++ if (sinkImplementation != 0) { ++ sinkProxy = RPC::Administrator::Instance().ProxyInstance(channel, sinkImplementation, false, _sink); ++ ++ ASSERT((_sink != nullptr) && (sinkProxy != nullptr)); + } + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- implementation->Register(param0_proxy); ++ implementation->Register(_sink); + +- if (param0_proxy_inst != nullptr) { +- RPC::Administrator::Instance().Release(param0_proxy_inst, message->Response()); ++ if (sinkProxy != nullptr) { ++ RPC::Administrator::Instance().Release(sinkProxy, message->Response()); + } + }, + +- // virtual void Unregister(ISystemAudioPlayer::INotification*) = 0 ++ // (2) virtual void Unregister(Exchange::ISystemAudioPlayer::INotification*) = 0 + // + [](Core::ProxyType& channel, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); +- +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +-#ifndef USE_THUNDER_R4 +- RPC::instance_id param0 = reader.Number(); +-#else +- Core::instance_id param0 = reader.Number(); +-#endif /* USE_THUNDER_R4 */ +- ISystemAudioPlayer::INotification* param0_proxy = nullptr; +- ProxyStub::UnknownProxy* param0_proxy_inst = nullptr; +- if (param0 != 0) { +- param0_proxy_inst = RPC::Administrator::Instance().ProxyInstance(channel, param0, false, param0_proxy); +- ASSERT((param0_proxy_inst != nullptr) && (param0_proxy != nullptr) && "Failed to get instance of ISystemAudioPlayer::INotification proxy"); +- +- if ((param0_proxy_inst == nullptr) || (param0_proxy == nullptr)) { +- TRACE_L1("Failed to get instance of ISystemAudioPlayer::INotification proxy"); +- } ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const Core::instance_id sinkImplementation = reader.Number(); ++ ++ Exchange::ISystemAudioPlayer::INotification* _sink = nullptr; ++ ProxyStub::UnknownProxy* sinkProxy = nullptr; ++ if (sinkImplementation != 0) { ++ sinkProxy = RPC::Administrator::Instance().ProxyInstance(channel, sinkImplementation, false, _sink); ++ ++ ASSERT((_sink != nullptr) && (sinkProxy != nullptr)); + } + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- implementation->Unregister(param0_proxy); ++ implementation->Unregister(_sink); + +- if (param0_proxy_inst != nullptr) { +- RPC::Administrator::Instance().Release(param0_proxy_inst, message->Response()); ++ if (sinkProxy != nullptr) { ++ RPC::Administrator::Instance().Release(sinkProxy, message->Response()); + } + }, + +- // virtual uint32_t Open(const string &input, string &output /* @out */) +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ // (3) virtual uint32_t Open(const string&, string&) = 0 ++ // ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Open(param0, param1); ++ string _output{}; ++ ++ uint32_t result = implementation->Open(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t Play(const string&, string&) = 0 ++ // (4) virtual uint32_t Play(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ string _output{}; + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Play(param0, param1); ++ uint32_t result = implementation->Play(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t PlayBuffer(const string&, string&) = 0 ++ // (5) virtual uint32_t PlayBuffer(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->PlayBuffer(param0, param1); ++ string _output{}; ++ ++ uint32_t result = implementation->PlayBuffer(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t Pause(const string&, string&) = 0 ++ // (6) virtual uint32_t Pause(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ string _output{}; + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Pause(param0, param1); ++ uint32_t result = implementation->Pause(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t Resume(const string&, string&) = 0 ++ // (7) virtual uint32_t Resume(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Resume(param0, param1); ++ string _output{}; ++ ++ uint32_t result = implementation->Resume(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t Stop(const string&, string&) = 0 ++ // (8) virtual uint32_t Stop(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ string _output{}; + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Stop(param0, param1); ++ uint32_t result = implementation->Stop(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t Close(const string&, string&) = 0 ++ // (9) virtual uint32_t Close(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ string _output{}; + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Close(param0, param1); ++ uint32_t result = implementation->Close(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t SetMixerLevels(const string&, string&) = 0 ++ // (10) virtual uint32_t SetMixerLevels(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->SetMixerLevels(param0, param1); ++ string _output{}; ++ ++ uint32_t result = implementation->SetMixerLevels(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t SetSmartVolControl(const string&, string&) = 0 ++ // (11) virtual uint32_t SetSmartVolControl(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); ++ ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ string _output{}; + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->SetSmartVolControl(param0, param1); ++ uint32_t result = implementation->SetSmartVolControl(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t IsPlaying(const string&, string&) = 0 ++ // (12) virtual uint32_t IsPlaying(const string&, string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->IsPlaying(param0, param1); ++ string _output{}; ++ ++ uint32_t result = implementation->IsPlaying(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t Config(const string &input, string &output /* @out */) +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ // (13) virtual uint32_t Config(const string&, string&) = 0 ++ // ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->Config(param0, param1); ++ string _output{}; ++ ++ uint32_t result = implementation->Config(static_cast(_input), _output); + +- // write return values + RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); ++ writer.Number(result); ++ writer.Text(_output); + }, + +- // virtual uint32_t GetPlayerSessionId(const string &input, string &output /* @out */) +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ // (14) virtual uint32_t GetPlayerSessionId(const string&, string&) = 0 ++ // ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); +- string param1{}; // storage ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _input = reader.Text(); + +- // call implementation +- ISystemAudioPlayer* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer implementation pointer"); +- const uint32_t output = implementation->GetPlayerSessionId(param0, param1); ++ string _output{}; + +- // write return values +- RPC::Data::Frame::Writer writer(message->Response().Writer()); +- writer.Number(output); +- writer.Text(param1); +- }, ++ uint32_t result = implementation->GetPlayerSessionId(static_cast(_input), _output); + +- nullptr +- }; // SystemAudioPlayerStubMethods[] ++ RPC::Data::Frame::Writer writer(message->Response().Writer()); ++ writer.Number(result); ++ writer.Text(_output); ++ } ++ }; // ExchangeSystemAudioPlayerStubMethods + + // +- // ISystemAudioPlayer::INotification interface stub definitions ++ // Exchange::ISystemAudioPlayer::INotification interface stub definitions + // + // Methods: +- // virtual void OnSAPEvents(const string &data) = 0; ++ // (0) virtual void OnSAPEvents(const string&) = 0 + // + +- ProxyStub::MethodHandler SystemAudioPlayerNotificationStubMethods[] = { +- // virtual void OnSAPEvents(const string&) = 0 ++ ProxyStub::MethodHandler ExchangeSystemAudioPlayerNotificationStubMethods[] = { ++ // (0) virtual void OnSAPEvents(const string&) = 0 + // +- [](Core::ProxyType& channel VARIABLE_IS_NOT_USED, Core::ProxyType& message) { +- RPC::Data::Input& input(message->Parameters()); ++ [](Core::ProxyType& /* channel */, Core::ProxyType& message) { ++ Exchange::ISystemAudioPlayer::INotification* implementation = reinterpret_cast(message->Parameters().Implementation()); ++ ASSERT(implementation != nullptr); + +- // read parameters +- RPC::Data::Frame::Reader reader(input.Reader()); +- const string param0 = reader.Text(); ++ RPC::Data::Frame::Reader reader(message->Parameters().Reader()); ++ const string _data = reader.Text(); + +- // call implementation +- ISystemAudioPlayer::INotification* implementation = reinterpret_cast(input.Implementation()); +- ASSERT((implementation != nullptr) && "Null ISystemAudioPlayer::INotification implementation pointer"); +- implementation->OnSAPEvents(param0); +- }, +- +- nullptr +- }; // SystemAudioPlayerNotificationStubMethods[] ++ implementation->OnSAPEvents(static_cast(_data)); ++ } ++ }; // ExchangeSystemAudioPlayerNotificationStubMethods + + // ----------------------------------------------------------------- +- // PROXY ++ // PROXIES + // ----------------------------------------------------------------- + + // +- // ISystemAudioPlayer interface proxy definitions ++ // Exchange::ISystemAudioPlayer interface proxy definitions + // + // Methods: + // (0) virtual uint32_t Configure(PluginHost::IShell*) = 0 +- // (1) virtual void Register(ITextToSpeech::INotification*) = 0 +- // (2) virtual void Unregister(ITextToSpeech::INotification*) = 0 +- // (3) virtual uint32_t Enable(const string&, string&) = 0 +- // (4) virtual uint32_t ListVoices(const string&, string&) = 0 +- // (5) virtual uint32_t SetConfiguration(const string&, string&) = 0 +- // (6) virtual uint32_t GetConfiguration(const string&, string&) = 0 +- // (7) virtual uint32_t IsEnabled(const string&, string&) = 0 +- // (8) virtual uint32_t Speak(const string&, string&) = 0 +- // (9) virtual uint32_t Cancel(const string&, string&) = 0 +- // (10) virtual uint32_t Pause(const string&, string&) = 0 +- // (11) virtual uint32_t Resume(const string&, string&) = 0 +- // (12) virtual uint32_t IsSpeaking(const string&, string&) = 0 +- // (13) virtual uint32_t GetSpeechState(const string&, string&) = 0 ++ // (1) virtual void Register(Exchange::ISystemAudioPlayer::INotification*) = 0 ++ // (2) virtual void Unregister(Exchange::ISystemAudioPlayer::INotification*) = 0 ++ // (3) virtual uint32_t Open(const string&, string&) = 0 ++ // (4) virtual uint32_t Play(const string&, string&) = 0 ++ // (5) virtual uint32_t PlayBuffer(const string&, string&) = 0 ++ // (6) virtual uint32_t Pause(const string&, string&) = 0 ++ // (7) virtual uint32_t Resume(const string&, string&) = 0 ++ // (8) virtual uint32_t Stop(const string&, string&) = 0 ++ // (9) virtual uint32_t Close(const string&, string&) = 0 ++ // (10) virtual uint32_t SetMixerLevels(const string&, string&) = 0 ++ // (11) virtual uint32_t SetSmartVolControl(const string&, string&) = 0 ++ // (12) virtual uint32_t IsPlaying(const string&, string&) = 0 ++ // (13) virtual uint32_t Config(const string&, string&) = 0 ++ // (14) virtual uint32_t GetPlayerSessionId(const string&, string&) = 0 + // + +- class SystemAudioPlayerProxy final : public ProxyStub::UnknownProxyType { ++ class ExchangeSystemAudioPlayerProxy final : public ProxyStub::UnknownProxyType { + public: +-#ifndef USE_THUNDER_R4 +- SystemAudioPlayerProxy(const Core::ProxyType& channel, RPC::instance_id implementation, const bool otherSideInformed) +-#else +- SystemAudioPlayerProxy(const Core::ProxyType& channel, Core::instance_id implementation, const bool otherSideInformed) +-#endif /* USE_THUNDER_R4 */ ++ ExchangeSystemAudioPlayerProxy(const Core::ProxyType& channel, const Core::instance_id implementation, const bool otherSideInformed) + : BaseClass(channel, implementation, otherSideInformed) + { + } + +- uint32_t Configure(PluginHost::IShell* param0) override ++ uint32_t Complete(RPC::Data::Frame::Reader& reader) + { +- IPCMessage newMessage(BaseClass::Message(0)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +-#ifndef USE_THUNDER_R4 +- writer.Number(RPC::instance_cast(param0)); +-#else +- writer.Number(RPC::instance_cast(param0)); +-#endif /* USE_THUNDER_R4 */ +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return value +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- +- Complete(reader); ++ uint32_t result = Core::ERROR_NONE; ++ ++ while (reader.HasData() == true) { ++ const Core::instance_id implementation = reader.Number(); ++ ASSERT(implementation != 0); ++ ++ const uint32_t id = reader.Number(); ++ const RPC::Data::Output::mode how = reader.Number(); ++ ++ result = UnknownProxyType::Complete(implementation, id, how); ++ if (result != Core::ERROR_NONE) { return (COM_ERROR | result); } + } + +- return output; ++ return (result); + } + +- void Register(ISystemAudioPlayer::INotification* param0) override ++ uint32_t Configure(PluginHost::IShell* _service) override + { +- IPCMessage newMessage(BaseClass::Message(1)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +-#ifndef USE_THUNDER_R4 +- writer.Number(RPC::instance_cast(param0)); +-#else +- writer.Number(RPC::instance_cast(param0)); +-#endif /* USE_THUNDER_R4 */ +- +- // invoke the method handler +- if (Invoke(newMessage) == Core::ERROR_NONE) { +- // read return value +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- Complete(reader); +- } ++ IPCMessage message(BaseClass::Message(0)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Number(RPC::instance_cast(_service)); ++ ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ ++ Complete(reader); ++ ++ return (result); + } + +- void Unregister(ISystemAudioPlayer::INotification* param0) override ++ void Register(Exchange::ISystemAudioPlayer::INotification* _sink) override + { +- IPCMessage newMessage(BaseClass::Message(2)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +-#ifndef USE_THUNDER_R4 +- writer.Number(RPC::instance_cast(param0)); +-#else +- writer.Number(RPC::instance_cast(param0)); +-#endif /* USE_THUNDER_R4 */ +- +- // invoke the method handler +- if (Invoke(newMessage) == Core::ERROR_NONE) { +- // read return value +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- Complete(reader); +- } ++ IPCMessage message(BaseClass::Message(1)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Number(RPC::instance_cast(_sink)); ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ ++ Complete(reader); + } +- +- uint32_t Open(const string& param0, string& /* out */ param1) override ++ ++ void Unregister(Exchange::ISystemAudioPlayer::INotification* _sink) override + { +- IPCMessage newMessage(BaseClass::Message(3)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(2)); + +- return output; ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Number(RPC::instance_cast(_sink)); ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ ++ Complete(reader); + } + +- uint32_t Play(const string& param0, string& /* out */ param1) override ++ uint32_t Open(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(4)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(3)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); + +- return output; ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + +- uint32_t PlayBuffer(const string& param0, string& /* out */ param1) override ++ uint32_t Play(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(5)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(4)); + +- return output; ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + +- uint32_t Pause(const string& param0, string& /* out */ param1) override ++ uint32_t PlayBuffer(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(6)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(5)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); + +- return output; ++ return (result); + } + +- uint32_t Resume(const string& param0, string& /* out */ param1) override ++ uint32_t Pause(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(7)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(6)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); + +- return output; ++ return (result); + } + +- uint32_t Stop(const string& param0, string& /* out */ param1) override ++ uint32_t Resume(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(8)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(7)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; + +- return output; ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + +- uint32_t Close(const string& param0, string& /* out */ param1) override ++ uint32_t Stop(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(9)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(8)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; + +- return output; ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + +- uint32_t SetMixerLevels(const string& param0, string& /* out */ param1) override ++ uint32_t Close(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(10)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(9)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); + +- return output; ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + +- uint32_t SetSmartVolControl(const string& param0, string& /* out */ param1) override ++ uint32_t SetMixerLevels(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(11)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(10)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); + +- return output; ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + +- +- uint32_t IsPlaying(const string& param0, string& /* out */ param1) override ++ uint32_t SetSmartVolControl(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(12)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(11)); + +- return output; ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + +- uint32_t Config(const string& param0, string& /* out */ param1) override ++ uint32_t IsPlaying(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(13)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(12)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); + +- return output; ++ return (result); + } +- +- uint32_t GetPlayerSessionId(const string& param0, string& /* out */ param1) override ++ ++ uint32_t Config(const string& _input, string& _output) override + { +- IPCMessage newMessage(BaseClass::Message(14)); +- +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); +- +- // invoke the method handler +- uint32_t output{}; +- if ((output = Invoke(newMessage)) == Core::ERROR_NONE) { +- // read return values +- RPC::Data::Frame::Reader reader(newMessage->Response().Reader()); +- output = reader.Number(); +- param1 = reader.Text(); +- } ++ IPCMessage message(BaseClass::Message(13)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); ++ ++ uint32_t result{}; + +- return output; ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); + } + ++ uint32_t GetPlayerSessionId(const string& _input, string& _output) override ++ { ++ IPCMessage message(BaseClass::Message(14)); ++ ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_input)); + +- }; // class SystemAudioPlayerProxy ++ uint32_t result{}; ++ ++ UnknownProxyType::Invoke(message); ++ RPC::Data::Frame::Reader reader(message->Response().Reader()); ++ result = reader.Number(); ++ _output = reader.Text(); ++ ++ return (result); ++ } ++ ++ }; // class ExchangeSystemAudioPlayerProxy + + // +- // ISystemAudioPlayer::INotification interface proxy definitions ++ // Exchange::ISystemAudioPlayer::INotification interface proxy definitions + // + // Methods: + // (0) virtual void OnSAPEvents(const string&) = 0 + // + +- class SystemAudioPlayerNotificationProxy final : public ProxyStub::UnknownProxyType { ++ class ExchangeSystemAudioPlayerNotificationProxy final : public ProxyStub::UnknownProxyType { + public: +-#ifndef USE_THUNDER_R4 +- SystemAudioPlayerNotificationProxy(const Core::ProxyType& channel, RPC::instance_id implementation, const bool otherSideInformed) +-#else +- SystemAudioPlayerNotificationProxy(const Core::ProxyType& channel, Core::instance_id implementation, const bool otherSideInformed) +-#endif /* USE_THUNDER_R4 */ ++ ExchangeSystemAudioPlayerNotificationProxy(const Core::ProxyType& channel, const Core::instance_id implementation, const bool otherSideInformed) + : BaseClass(channel, implementation, otherSideInformed) + { + } + +- void OnSAPEvents(const string& param0) override ++ uint32_t Complete(RPC::Data::Frame::Reader& reader) ++ { ++ uint32_t result = Core::ERROR_NONE; ++ ++ while (reader.HasData() == true) { ++ const Core::instance_id implementation = reader.Number(); ++ ASSERT(implementation != 0); ++ ++ const uint32_t id = reader.Number(); ++ const RPC::Data::Output::mode how = reader.Number(); ++ ++ result = UnknownProxyType::Complete(implementation, id, how); ++ if (result != Core::ERROR_NONE) { return (COM_ERROR | result); } ++ } ++ ++ return (result); ++ } ++ ++ void OnSAPEvents(const string& _data) override + { +- IPCMessage newMessage(BaseClass::Message(0)); ++ IPCMessage message(BaseClass::Message(0)); + +- // write parameters +- RPC::Data::Frame::Writer writer(newMessage->Parameters().Writer()); +- writer.Text(param0); ++ RPC::Data::Frame::Writer writer(message->Parameters().Writer()); ++ writer.Text(static_cast(_data)); + +- // invoke the method handler +- Invoke(newMessage); ++ UnknownProxyType::Invoke(message); + } +- +- }; // class SystemAudioPlayerNotificationProxy ++ ++ }; // class ExchangeSystemAudioPlayerNotificationProxy ++ ++ POP_WARNING() ++ POP_WARNING() + + // ----------------------------------------------------------------- + // REGISTRATION +@@ -802,20 +710,20 @@ namespace ProxyStubs { + + namespace { + +- typedef ProxyStub::UnknownStubType SystemAudioPlayerStub; +- typedef ProxyStub::UnknownStubType SystemAudioPlayerNotificationStub; ++ typedef ProxyStub::UnknownStubType ExchangeSystemAudioPlayerStub; ++ typedef ProxyStub::UnknownStubType ExchangeSystemAudioPlayerNotificationStub; + + static class Instantiation { + public: + Instantiation() + { +- RPC::Administrator::Instance().Announce(); +- RPC::Administrator::Instance().Announce(); ++ RPC::Administrator::Instance().Announce(); ++ RPC::Administrator::Instance().Announce(); + } + ~Instantiation() + { +- RPC::Administrator::Instance().Recall(); +- RPC::Administrator::Instance().Recall(); ++ RPC::Administrator::Instance().Recall(); ++ RPC::Administrator::Instance().Recall(); + } + } ProxyStubRegistration; + diff --git a/files/0007-RDK-IDeviceInfo-Changes.patch b/files/0007-RDK-IDeviceInfo-Changes.patch new file mode 100755 index 0000000000..23c432ce48 --- /dev/null +++ b/files/0007-RDK-IDeviceInfo-Changes.patch @@ -0,0 +1,997 @@ +diff --git a/interfaces/IDeviceInfo.h b/interfaces/IDeviceInfo.h +index b674799..2a3b48c 100644 +--- a/interfaces/IDeviceInfo.h ++++ b/interfaces/IDeviceInfo.h +@@ -1,22 +1,3 @@ +-/* +- * If not stated otherwise in this file or this component's LICENSE file the +- * following copyright and licenses apply: +- * +- * Copyright 2021 Metrological +- * +- * 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" +@@ -31,17 +12,12 @@ namespace Exchange { + + virtual ~IDeviceInfo() override = default; + +- virtual uint32_t Configure(const PluginHost::IShell* service) = 0; +- +- virtual uint32_t SerialNumber(string& value /* @out */) const = 0; +- virtual uint32_t Sku(string& value /* @out */) const = 0; +- virtual uint32_t Make(string& value /* @out */) const = 0; +- virtual uint32_t ModelName(string& value/*@out*/) const = 0; +- virtual uint32_t ModelYear(uint16_t& value/*@out*/) const = 0; +- virtual uint32_t FriendlyName(string& value/*@out*/) const = 0; +- virtual uint32_t DeviceType(string& value /* @out */) const = 0; +- virtual uint32_t PlatformName(string& value/*@out*/) const = 0; +- virtual uint32_t DistributorId(string& value /* @out */) const = 0; ++ virtual uint32_t SerialNumber(string& serialNumber /* @out */) const = 0; ++ virtual uint32_t Sku(string& sku /* @out */) const = 0; ++ virtual uint32_t Make(string& make /* @out */) const = 0; ++ virtual uint32_t Model(string& model /* @out */) const = 0; ++ virtual uint32_t DeviceType(string& deviceType /* @out */) const = 0; ++ virtual uint32_t DistributorId(string& distributorId /* @out */) const = 0; + }; + + struct EXTERNAL IDeviceAudioCapabilities : virtual public Core::IUnknown { +@@ -88,10 +64,10 @@ namespace Exchange { + typedef RPC::IIteratorType IMS12CapabilityIterator; + typedef RPC::IIteratorType IMS12ProfileIterator; + +- virtual uint32_t AudioOutputs(IAudioOutputIterator*& audioOutputs /* @out */) const = 0; +- virtual uint32_t AudioCapabilities(const AudioOutput audioOutput /* @in */, IAudioCapabilityIterator*& audioCapabilities /* @out */) const = 0; +- virtual uint32_t MS12Capabilities(const AudioOutput audioOutput /* @in */, IMS12CapabilityIterator*& ms12Capabilities /* @out */) const = 0; +- virtual uint32_t MS12AudioProfiles(const AudioOutput audioOutput /* @in */, IMS12ProfileIterator*& ms12Profiles /* @out */) const = 0; ++ virtual uint32_t SupportedAudioPorts(RPC::IStringIterator*& supportedAudioPorts /* @out */) const = 0; ++ virtual uint32_t AudioCapabilities(const string& audioPort /* @in */, IAudioCapabilityIterator*& audioCapabilities /* @out */) const = 0; ++ virtual uint32_t MS12Capabilities(const string& audioPort /* @in */, IMS12CapabilityIterator*& ms12Capabilities /* @out */) const = 0; ++ virtual uint32_t SupportedMS12AudioProfiles(const string& audioPort /* @in */, RPC::IStringIterator*& supportedMS12AudioProfiles /* @out */) const = 0; + }; + + struct EXTERNAL IDeviceVideoCapabilities : virtual public Core::IUnknown { +@@ -147,14 +123,11 @@ namespace Exchange { + typedef RPC::IIteratorType IVideoOutputIterator; + typedef RPC::IIteratorType IScreenResolutionIterator; + +- virtual uint32_t VideoOutputs(IVideoOutputIterator*& videoOutputs /* @out */) const = 0; +- virtual uint32_t DefaultResolution(const VideoOutput videoOutput /* @in */, ScreenResolution& defaultResolution /* @out */) const = 0; +- virtual uint32_t Resolutions(const VideoOutput videoOutput /* @in */, IScreenResolutionIterator*& resolutions /* @out */) const = 0; +- virtual uint32_t Hdcp(const VideoOutput videoOutput /* @in */, CopyProtection& hdcpVersion /* @out */) const = 0; ++ virtual uint32_t SupportedVideoDisplays(RPC::IStringIterator*& supportedVideoDisplays /* @out */) const = 0; ++ virtual uint32_t DefaultResolution(const string& videoDisplay /* @in */, string& defaultResolution /* @out */) const = 0; ++ virtual uint32_t SupportedResolutions(const string& videoDisplay /* @in */, RPC::IStringIterator*& supportedResolutions /* @out */) const = 0; + virtual uint32_t HostEDID(string& edid /* @out */) const = 0; +- virtual uint32_t HDR(bool& supportsHDR /*@out*/) const = 0; +- virtual uint32_t Atmos(bool& supportsAtmos /*@out*/) const = 0; +- virtual uint32_t CEC(bool& supportsCEC /*@out*/) const = 0; ++ virtual uint32_t SupportedHdcp(const string& videoDisplay /* @in */, CopyProtection& supportedHDCPVersion /* @out */) const = 0; + }; + } + } +diff --git a/jsonrpc/DeviceInfo.json b/jsonrpc/DeviceInfo.json +index c0519fc..82cf33d 100644 +--- a/jsonrpc/DeviceInfo.json ++++ b/jsonrpc/DeviceInfo.json +@@ -33,153 +33,13 @@ + "example": 789132680, + "description": "15min cpuload average" + } +- }, ++ }, + "required": [ + "avg1min", + "avg5min", + "avg15min" + ] + }, +- "audioPort": { +- "type": "string", +- "enum": [ +- "OTHER", +- "RF_MODULATOR", +- "ANALOG", +- "SPDIF0", +- "HDMI0", +- "HDMI1", +- "DISPLAYPORT" +- ], +- "enumvalues": [ +- 0, +- 1, +- 2, +- 3, +- 4, +- 5, +- 6 +- ], +- "description": "Audio output supported by the device", +- "example": "analog" +- }, +- "audiooutputs": { +- "type": "array", +- "items": { +- "$ref": "#/definitions/audioPort" +- } +- }, +- "audiocapability": { +- "type": "string", +- "enum": [ +- "none", +- "ATMOS", +- "DOLBY DIGITAL", +- "DOLBY DIGITAL PLUS", +- "Dual Audio Decode", +- "DAPv2", +- "MS12" +- ], +- "enumids": [ +- "NONE", +- "ATMOS", +- "DD", +- "DDPLUS", +- "DAD", +- "DAPV2", +- "MS12" +- ], +- "description": "Audio capability", +- "example": "none" +- }, +- "audiocapabilities": { +- "summary": "An array of audio capabilities", +- "type": "array", +- "items": { +- "$ref": "#/definitions/audiocapability" +- } +- }, +- "ms12capability": { +- "type": "string", +- "enum": [ +- "none", +- "Dolby Volume", +- "Inteligent Equalizer", +- "Dialogue Enhancer" +- ], +- "enumids": [ +- "NONE", +- "DOLBYVOLUME", +- "INTELIGENTEQUALIZER", +- "DIALOGUEENHANCER" +- ], +- "description": "MS12 audio capability", +- "example": "dolby_volume" +- }, +- "ms12capabilities": { +- "summary": "An array of MS12 audio capabilities", +- "type": "array", +- "items": { +- "$ref": "#/definitions/ms12capability" +- } +- }, +- "ms12profile": { +- "type": "string", +- "enum": [ +- "None", +- "Music", +- "Movie", +- "Voice" +- ], +- "enumids": [ +- "NONE", +- "MUSIC", +- "MOVIE", +- "VOICE" +- ], +- "description": "MS12 Profile", +- "example": "music" +- }, +- "ms12profiles": { +- "summary": "An array of MS12 audio profiles", +- "type": "array", +- "items": { +- "$ref": "#/definitions/ms12profile" +- } +- }, +- "videoDisplay": { +- "type": "string", +- "enum": [ +- "OTHER", +- "RF_MODULATOR", +- "COMPOSITE", +- "SVIDEO", +- "COMPONET", +- "SCART_RGB", +- "HDMI0", +- "HDMI1", +- "DISPLAYPORT" +- ], +- "enumvalues": [ +- 0, +- 1, +- 2, +- 3, +- 4, +- 5, +- 6, +- 7, +- 8 +- ], +- "description": "Video output supported by the device", +- "example": "displayport" +- }, +- "videooutputs": { +- "type": "array", +- "items": { +- "$ref": "#/definitions/videoDisplay" +- } +- }, + "output_resolution": { + "type": "string", + "enum": [ +@@ -206,40 +66,34 @@ + "4320p30", + "4320p60" + ], +- "enumvalues": [ +- 0, +- 1, +- 2, +- 3, +- 4, +- 5, +- 6, +- 7, +- 8, +- 9, +- 10, +- 11, +- 12, +- 13, +- 14, +- 15, +- 16, +- 17, +- 18, +- 19, +- 20, +- 21 ++ "enumids": [ ++ "RESOLUTION_UNKNOWN", ++ "RESOLUTION_480I", ++ "RESOLUTION_480P", ++ "RESOLUTION_576I", ++ "RESOLUTION_576P", ++ "RESOLUTION_576P50", ++ "RESOLUTION_720P", ++ "RESOLUTION_720P50", ++ "RESOLUTION_1080I", ++ "RESOLUTION_1080I25", ++ "RESOLUTION_1080I50", ++ "RESOLUTION_1080P", ++ "RESOLUTION_1080P24", ++ "RESOLUTION_1080P25", ++ "RESOLUTION_1080P30", ++ "RESOLUTION_1080P50", ++ "RESOLUTION_1080P60", ++ "RESOLUTION_2160P30", ++ "RESOLUTION_2160P50", ++ "RESOLUTION_2160P60", ++ "RESOLUTION_4320P30", ++ "RESOLUTION_4320P60" + ], + "description": "Resolution supported by the device", + "example": "1080p" + }, +- "output_resolutions": { +- "type": "array", +- "items": { +- "$ref": "#/definitions/output_resolution" +- } +- }, +- "copyprotection": { ++ "copy_protection": { + "type": "string", + "enum": [ + "unavailable", +@@ -258,77 +112,11 @@ + "description": "HDCP support", + "example": "hdcp_20" + }, +- "videooutputcapabilities": { +- "summary": "Video capabilities of the output", +- "type": "object", +- "properties": { +- "hdcp": { +- "description": "HDCP support", +- "type": "string", +- "$ref": "#/definitions/copyprotection", +- "example": "hdcp_20" +- }, +- "videoDisplay": { +- "description": "Video Output support", +- "type": "string", +- "$ref": "#/definitions/videoDisplay", +- "example": "[hdmi, displayport]" +- }, +- "output_resolutions": { +- "description": "Supported resolutions", +- "type": "string", +- "$ref": "#/definitions/output_resolutions", +- "example": "[480p, 720p]" +- }, +- "defaultresolution": { +- "description": "Default resolution", +- "type": "string", +- "$ref": "#/definitions/output_resolution", +- "example": "[720p]" +- } +- }, +- "required": [ +- "hdcp", +- "videooutputs", +- "output_resolutions", +- "defaultresolution" +- ] +- }, +- "audiooutputcapabilities": { +- "summary": "Audio capabilities of the output", +- "type": "object", +- "properties": { +- "audioPort": { +- "description": "Audio Output support", +- "type": "string", +- "$ref": "#/definitions/audioPort", +- "example": "[hdmi, spdif]" +- }, +- "audiocapabilities": { +- "description": "Audio capabilities for the specified audio port", +- "type": "string", +- "$ref": "#/definitions/audiocapabilities", +- "example": "" +- }, +- "ms12capabilities": { +- "description": "Audio ms12 capabilities for the specified audio port", +- "type": "string", +- "$ref": "#/definitions/ms12capabilities", +- "example": "" +- }, +- "ms12profiles": { +- "description": "Audio ms12 profiles for the specified audio port", +- "type": "string", +- "$ref": "#/definitions/ms12profiles", +- "example": "" +- } +- }, +- "required": [ +- "audiooutputs", +- "audiocapabilities", +- "ms12capabilities", +- "ms12profiles" +- ] ++ "output_resolutions": { ++ "type": "array", ++ "items": { ++ "$ref": "#/definitions/output_resolution" ++ } + }, + "devicetype": { + "type": "string", +@@ -456,124 +244,63 @@ + ], + "description": "Partner ID or distributor ID for device", + "example": "comcast" +- } +- }, +- "properties": { +- "deviceaudiocapabilities":{ +- "summary": "Audio capabilities of the device", +- "readonly": true, +- "params":{ +- "type": "object", +- "properties": { +- "audiooutputcapabilities": { +- "type": "array", +- "items": { +- "$ref": "#/definitions/audiooutputcapabilities" +- } +- } +- } +- }, +- "required": [ +- "audiooutputcapabilities" +- ] + }, +- "devicevideocapabilities":{ +- "summary": "Video capabilities of the device", +- "readonly": true, +- "params":{ +- "type": "object", +- "properties": { +- "hostedid": { +- "description": "EDID of the host", +- "type" : "string", +- "example" : "" +- }, +- "hdr": { +- "description": "Is HDR supported by this device", +- "type": "boolean", +- "example": false +- }, +- "atmos": { +- "description": "Is Atmos supported by this device", +- "type": "boolean", +- "example": false +- }, +- "cec": { +- "description": "Is CEC supported by this device", +- "type": "boolean", +- "example": true +- }, +- "videooutputcapabilities": { +- "type": "array", +- "items": { +- "$ref": "#/definitions/videooutputcapabilities" +- } +- } +- }, +- "required": [ +- "hdr", +- "atmos", +- "cec", +- "hostedid", +- "videooutputcapabilities" +- ] +- } ++ "audiocapability": { ++ "type": "string", ++ "enum": [ ++ "none", ++ "ATMOS", ++ "DOLBY DIGITAL", ++ "DOLBY DIGITAL PLUS", ++ "Dual Audio Decode", ++ "DAPv2", ++ "MS12" ++ ], ++ "enumids": [ ++ "NONE", ++ "ATMOS", ++ "DD", ++ "DDPLUS", ++ "DAD", ++ "DAPV2", ++ "MS12" ++ ], ++ "description": "Audio capability", ++ "example": "none" + }, +- "deviceinfo":{ +- "summary": "Device meta data", +- "readonly": true, +- "params":{ +- "type": "object", +- "properties": { +- "devicetype" : { +- "description": "Device type", +- "type": "string", +- "example": "IpStb" +- }, +- "friendlyname": { +- "description": "Friendly name", +- "type": "string", +- "example": "my device" +- }, +- "distributorid": { +- "description": "Partner ID or distributor ID for device", +- "type": "string", +- "example": "Comcast" +- }, +- "make" : { +- "description": "Device manufacturer", +- "type": "string", +- "example": "pace" +- }, +- "modelname": { +- "description": "Model Name", +- "type": "string", +- "example": "model A" +- }, +- "modelyear": { +- "description": "Model Year", +- "type": "number", +- "size": 16, +- "example": "2020" +- }, +- "platformname": { +- "description": "Platform name", +- "type": "string", +- "example": "linux" +- }, +- "serialnumber": { +- "description": "Device serial number", +- "type": "string", +- "example": "WPEuCfrLF45" +- }, +- "sku" : { +- "description": "Device model number or SKU", +- "type": "string", +- "example": "PX051AEI" +- } +- } ++ "audiocapabilities": { ++ "summary": "An array of audio capabilities", ++ "type": "array", ++ "items": { ++ "$ref": "#/definitions/audiocapability" + } + }, ++ "ms12capability": { ++ "type": "string", ++ "enum": [ ++ "none", ++ "Dolby Volume", ++ "Inteligent Equalizer", ++ "Dialogue Enhancer" ++ ], ++ "enumids": [ ++ "NONE", ++ "DOLBYVOLUME", ++ "INTELIGENTEQUALIZER", ++ "DIALOGUEENHANCER" ++ ], ++ "description": "MS12 audio capability", ++ "example": "Dolby Volume" ++ }, ++ "ms12capabilities": { ++ "summary": "An array of MS12 audio capabilities", ++ "type": "array", ++ "items": { ++ "$ref": "#/definitions/ms12capability" ++ } ++ } ++ }, ++ "properties": { + "systeminfo": { + "summary": "System general information", + "readonly": true, +@@ -688,7 +415,7 @@ + ] + } + } +- }, ++ }, + "socketinfo": { + "summary": "Socket information", + "readonly": true, +@@ -726,77 +453,6 @@ + ] + } + }, +- "supportedaudioports": { +- "summary": "Audio ports supported on the device (all ports that are physically present)", +- "readonly": true, +- "params": { +- "type": "object", +- "properties": { +- "supportedAudioPorts": { +- "description": "Audio Output support", +- "type": "string", +- "$ref": "#/definitions/audiooutputs", +- "example": "[hdmi, spdif]" +- } +- }, +- "required": [ +- "supportedAudioPorts" +- ] +- }, +- "errors": [ +- { +- "description": "General error", +- "$ref": "#/common/errors/general" +- } +- ] +- }, +- "supportedvideodisplays": { +- "summary": "Video ports supported on the device (all ports that are physically present)", +- "readonly": true, +- "params": { +- "type": "object", +- "properties": { +- "supportedVideoDisplays": { +- "description": "Video Output support", +- "type": "string", +- "$ref": "#/definitions/videooutputs", +- "example": "[hdmi, spdif]" +- } +- }, +- "required": [ +- "supportedVideoDisplays" +- ] +- }, +- "errors": [ +- { +- "description": "General error", +- "$ref": "#/common/errors/general" +- } +- ] +- }, +- "hostedid": { +- "summary": "EDID of the host", +- "readonly": true, +- "params": { +- "type": "object", +- "properties": { +- "EDID": { +- "summary": "A base64 encoded byte array string representing the EDID", +- "type": "string", +- "example": "AP///////wAQrMLQVEJTMQUdAQOANR546q11qVRNnSYPUFSlSwCBALMA0QBxT6lAgYDRwAEBVl4AoKCgKVAwIDUADighAAAaAAAA/wBNWTNORDkxVjFTQlQKAAAA/ABERUxMIFAyNDE4RAogAAAA/QAxVh1xHAAKICAgICAgARsCAxuxUJAFBAMCBxYBBhESFRMUHyBlAwwAEAACOoAYcTgtQFgsRQAOKCEAAB4BHYAYcRwWIFgsJQAOKCEAAJ6/FgCggDgTQDAgOgAOKCEAABp+OQCggDgfQDAgOgAOKCEAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2A" +- } +- }, +- "required": [ +- "EDID" +- ] +- }, +- "errors": [ +- { +- "description": "General error", +- "$ref": "#/common/errors/general" +- } +- ] +- }, + "firmwareversion": { + "summary": "Versions maintained in version.txt", + "readonly": true, +@@ -853,18 +509,18 @@ + } + ] + }, +- "make": { +- "summary": "Device manufacturer", ++ "modelid": { ++ "summary": "Device model number or SKU", + "readonly": true, + "params": { + "type": "object", + "properties": { +- "make": { +- "$ref": "#/definitions/make" ++ "sku": { ++ "$ref": "#/definitions/sku" + } + }, + "required": [ +- "make" ++ "sku" + ] + }, + "errors": [ +@@ -874,18 +530,18 @@ + } + ] + }, +- "modelid": { +- "summary": "Device model number or SKU", ++ "make": { ++ "summary": "Device manufacturer", + "readonly": true, + "params": { + "type": "object", + "properties": { +- "sku": { +- "$ref": "#/definitions/sku" ++ "make": { ++ "$ref": "#/definitions/make" + } + }, + "required": [ +- "sku" ++ "make" + ] + }, + "errors": [ +@@ -896,7 +552,7 @@ + ] + }, + "modelname": { +- "summary": "Device model name", ++ "summary": "Friendly device model name", + "readonly": true, + "params": { + "type": "object", +@@ -917,20 +573,18 @@ + } + ] + }, +- "modelyear": { +- "summary": "Device model year", ++ "devicetype": { ++ "summary": "Device type", + "readonly": true, + "params": { + "type": "object", + "properties": { +- "year": { +- "type": "number", +- "size": 16, +- "example": "2020" ++ "devicetype": { ++ "$ref": "#/definitions/devicetype" + } + }, + "required": [ +- "year" ++ "devicetype" + ] + }, + "errors": [ +@@ -940,19 +594,18 @@ + } + ] + }, +- "friendlyname": { +- "summary": "Device friendly name", ++ "distributorid": { ++ "summary": "Partner ID or distributor ID for device", + "readonly": true, + "params": { + "type": "object", + "properties": { +- "name": { +- "type": "string", +- "example": "My device" ++ "distributorid": { ++ "$ref": "#/definitions/distributorid" + } + }, + "required": [ +- "name" ++ "distributorid" + ] + }, + "errors": [ +@@ -962,19 +615,22 @@ + } + ] + }, +- "platformname": { +- "summary": "Device Platform name", ++ "supportedaudioports": { ++ "summary": "Audio ports supported on the device (all ports that are physically present)", + "readonly": true, + "params": { + "type": "object", + "properties": { +- "name": { +- "type": "string", +- "example": "Linux" ++ "supportedAudioPorts": { ++ "type": "array", ++ "items": { ++ "type": "string", ++ "example": "HDMI0" ++ } + } + }, + "required": [ +- "name" ++ "supportedAudioPorts" + ] + }, + "errors": [ +@@ -984,18 +640,22 @@ + } + ] + }, +- "devicetype": { +- "summary": "Device type", ++ "supportedvideodisplays": { ++ "summary": "Video ports supported on the device (all ports that are physically present)", + "readonly": true, + "params": { + "type": "object", + "properties": { +- "devicetype": { +- "$ref": "#/definitions/devicetype" ++ "supportedVideoDisplays": { ++ "type": "array", ++ "items": { ++ "type": "string", ++ "example": "HDMI0" ++ } + } + }, + "required": [ +- "devicetype" ++ "supportedVideoDisplays" + ] + }, + "errors": [ +@@ -1005,18 +665,20 @@ + } + ] + }, +- "distributorid": { +- "summary": "Partner ID or distributor ID for device", ++ "hostedid": { ++ "summary": "EDID of the host", + "readonly": true, + "params": { + "type": "object", + "properties": { +- "distributorid": { +- "$ref": "#/definitions/distributorid" ++ "EDID": { ++ "summary": "A base64 encoded byte array string representing the EDID", ++ "type": "string", ++ "example": "AP///////wAQrMLQVEJTMQUdAQOANR546q11qVRNnSYPUFSlSwCBALMA0QBxT6lAgYDRwAEBVl4AoKCgKVAwIDUADighAAAaAAAA/wBNWTNORDkxVjFTQlQKAAAA/ABERUxMIFAyNDE4RAogAAAA/QAxVh1xHAAKICAgICAgARsCAxuxUJAFBAMCBxYBBhESFRMUHyBlAwwAEAACOoAYcTgtQFgsRQAOKCEAAB4BHYAYcRwWIFgsJQAOKCEAAJ6/FgCggDgTQDAgOgAOKCEAABp+OQCggDgfQDAgOgAOKCEAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2A" + } + }, + "required": [ +- "distributorid" ++ "EDID" + ] + }, + "errors": [ +@@ -1034,7 +696,9 @@ + "type": "object", + "properties": { + "videoDisplay": { +- "$ref": "#/definitions/videoDisplay" ++ "description": "Video display port name", ++ "type": "string", ++ "example": "HDMI0" + } + }, + "required": [ +@@ -1054,7 +718,7 @@ + }, + "errors": [ + { +- "description": "general error", ++ "description": "General error", + "$ref": "#/common/errors/general" + } + ] +@@ -1065,7 +729,9 @@ + "type": "object", + "properties": { + "videoDisplay": { +- "$ref": "#/definitions/videoDisplay" ++ "description": "Video display port name", ++ "type": "string", ++ "example": "HDMI0" + } + }, + "required": [ +@@ -1085,7 +751,7 @@ + }, + "errors": [ + { +- "description": "general error", ++ "description": "General error", + "$ref": "#/common/errors/general" + } + ] +@@ -1096,7 +762,9 @@ + "type": "object", + "properties": { + "videoDisplay": { +- "$ref": "#/definitions/videoDisplay" ++ "description": "Video display port name", ++ "type": "string", ++ "example": "HDMI0" + } + }, + "required": [ +@@ -1107,7 +775,7 @@ + "type": "object", + "properties": { + "supportedHDCPVersion": { +- "$ref": "#/definitions/copyprotection" ++ "$ref": "#/definitions/copy_protection" + } + }, + "required": [ +@@ -1116,7 +784,7 @@ + }, + "errors": [ + { +- "description": "general error", ++ "description": "General error", + "$ref": "#/common/errors/general" + } + ] +@@ -1127,7 +795,9 @@ + "type": "object", + "properties": { + "audioPort": { +- "$ref": "#/definitions/audioPort" ++ "description": "Audio port name", ++ "type": "string", ++ "example": "HDMI0" + } + }, + "required": [ +@@ -1147,18 +817,20 @@ + }, + "errors": [ + { +- "description": "general error", ++ "description": "General error", + "$ref": "#/common/errors/general" + } + ] + }, + "ms12capabilities": { +- "summary": "Audio ms12 capabilities for the specified audio port", ++ "summary": "MS12 audio capabilities for the specified audio port", + "params": { + "type": "object", + "properties": { + "audioPort": { +- "$ref": "#/definitions/audioPort" ++ "description": "Audio port name", ++ "type": "string", ++ "example": "HDMI0" + } + }, + "required": [ +@@ -1175,21 +847,23 @@ + "required": [ + "MS12Capabilities" + ] +- }, ++ }, + "errors": [ + { +- "description": "general error", ++ "description": "General error", + "$ref": "#/common/errors/general" + } + ] + }, + "supportedms12audioprofiles": { +- "summary": "Supported ms12 audio profiles for the specified audio port", ++ "summary": "Supported MS12 audio profiles for the specified audio port", + "params": { + "type": "object", + "properties": { + "audioPort": { +- "$ref": "#/definitions/audioPort" ++ "description": "Audio port name", ++ "type": "string", ++ "example": "HDMI0" + } + }, + "required": [ +@@ -1200,10 +874,12 @@ + "type": "object", + "properties": { + "supportedMS12AudioProfiles": { +- "description": "An array of ms12 audio profiles", +- "type": "string", +- "$ref": "#/definitions/ms12profiles", +- "example": "[muisc, movie]" ++ "summary": "An array of MS12 audio profiles", ++ "type": "array", ++ "items": { ++ "type": "string", ++ "example": "Movie" ++ } + } + }, + "required": [ diff --git a/files/SplitDeviceCapablities.patch b/files/SplitDeviceCapablities.patch new file mode 100755 index 0000000000..2b6723406b --- /dev/null +++ b/files/SplitDeviceCapablities.patch @@ -0,0 +1,38 @@ +diff --git a/interfaces/Ids.h b/interfaces/Ids.h +index a37db24..2932adf 100644 +--- a/interfaces/Ids.h ++++ b/interfaces/Ids.h +@@ -264,6 +264,7 @@ namespace Exchange { + ID_DEVICE_CAPABILITIES_VIDEO = ID_DEVICE_INFO + 6, + ID_DEVICE_CAPABILITIES_VIDEO_OUTPUT = ID_DEVICE_INFO + 7, + ID_DEVICE_CAPABILITIES_RESOLUTION = ID_DEVICE_INFO + 8, ++ ID_FIRMWARE_VERSION = ID_DEVICE_INFO + 9, + + ID_DIALSERVER = RPC::IDS::ID_EXTERNAL_INTERFACE_OFFSET + 0x380, + ID_DIALSERVER_APPLICATION = ID_DIALSERVER + 1, + +diff --git a/interfaces/IFirmwareVersion.h b/interfaces/IFirmwareVersion.h +new file mode 100644 +index 0000000..ba6ce5a +--- /dev/null ++++ b/interfaces/IFirmwareVersion.h +@@ -0,0 +1,19 @@ ++#pragma once ++ ++#include "Module.h" ++ ++namespace WPEFramework { ++namespace Exchange { ++ ++ struct EXTERNAL IFirmwareVersion : virtual public Core::IUnknown { ++ enum { ID = ID_FIRMWARE_VERSION }; ++ ++ virtual ~IFirmwareVersion() override = default; ++ ++ virtual uint32_t Imagename(string& imagename /* @out */) const = 0; ++ virtual uint32_t Sdk(string& sdk /* @out */) const = 0; ++ virtual uint32_t Mediarite(string& mediarite /* @out */) const = 0; ++ virtual uint32_t Yocto(string& yocto /* @out */) const = 0; ++ }; ++} ++} diff --git a/l2tests.cmake b/l2tests.cmake index ad6d11044e..b2132dbf90 100755 --- a/l2tests.cmake +++ b/l2tests.cmake @@ -111,9 +111,19 @@ set(CMAKE_DISABLE_FIND_PACKAGE_CEC ON) set(PLUGIN_SYSTEMSERVICES ON) set(PLUGIN_WAREHOUSE ON) set(PLUGIN_TELEMETRY ON) + +# We are not compiling TEXTTOSPEECH, NETWORK, HDCPPROFILE plugins for Thunder R4 as +# this work is not in this scope. In future we will enable these plugins for Thunder R4. +if (USE_THUNDER_R4) +set(PLUGIN_HDCPPROFILE OFF) +set(PLUGIN_NETWORK OFF) +set(PLUGIN_TEXTTOSPEECH OFF) +else () set(PLUGIN_HDCPPROFILE ON) set(PLUGIN_NETWORK ON) set(PLUGIN_TEXTTOSPEECH ON) +endif (USE_THUNDER_R4) + set(PLUGIN_USBACCESS ON) set(PLUGIN_L2Tests ON) set(BUILD_SHARED_LIBS ON)