diff --git a/DeviceIdentification/DeviceIdentification.cpp b/DeviceIdentification/DeviceIdentification.cpp index c220e34563..5e59cac179 100644 --- a/DeviceIdentification/DeviceIdentification.cpp +++ b/DeviceIdentification/DeviceIdentification.cpp @@ -94,55 +94,59 @@ namespace Plugin { message = _T("DeviceIdentification plugin could not be instantiated."); } +#ifndef USE_THUNDER_R4 if (message.length() != 0) { Deinitialize(service); } +#endif return message; } /* virtual */ void DeviceIdentification::Deinitialize(PluginHost::IShell* service) { - ASSERT(_service == service); + if (_service != nullptr) { + ASSERT(_service == service); - _service->Unregister(&_notification); + _service->Unregister(&_notification); - if (_deviceId.empty() != true) { + if (_deviceId.empty() != true) { #ifndef DISABLE_DEVICEID_CONTROL - service->SubSystems()->Set(PluginHost::ISubSystem::IDENTIFIER, nullptr); + service->SubSystems()->Set(PluginHost::ISubSystem::IDENTIFIER, nullptr); #endif - _deviceId.clear(); - } - if(_identifier != nullptr) { + _deviceId.clear(); + } + if (_identifier != nullptr) { - UnregisterAll(); + UnregisterAll(); - // Stop processing: - RPC::IRemoteConnection* connection = service->RemoteConnection(_connectionId); + // Stop processing: + RPC::IRemoteConnection* connection = service->RemoteConnection(_connectionId); - VARIABLE_IS_NOT_USED uint32_t result = _identifier->Release(); - _identifier = nullptr; + VARIABLE_IS_NOT_USED uint32_t result = _identifier->Release(); + _identifier = nullptr; - // It should have been the last reference we are releasing, - // so it should endup in a DESTRUCTION_SUCCEEDED, if not we - // are leaking... - ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + // It should have been the last reference we are releasing, + // so it should endup in a DESTRUCTION_SUCCEEDED, if not we + // are leaking... + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); - // If this was running in a (container) process... - if (connection != nullptr) { - // Lets trigger the cleanup sequence for - // out-of-process code. Which will guard - // that unwilling processes, get shot if - // not stopped friendly :-) - connection->Terminate(); - connection->Release(); + // If this was running in a (container) process... + if (connection != nullptr) { + // Lets trigger the cleanup sequence for + // out-of-process code. Which will guard + // that unwilling processes, get shot if + // not stopped friendly :-) + connection->Terminate(); + connection->Release(); + } } - } - _connectionId = 0; + _connectionId = 0; - _service->Release(); - _service = nullptr; + _service->Release(); + _service = nullptr; + } } /* virtual */ string DeviceIdentification::Information() const diff --git a/DeviceIdentification/DeviceIdentification.h b/DeviceIdentification/DeviceIdentification.h index 12eb325e0e..6f5a8fcfb9 100644 --- a/DeviceIdentification/DeviceIdentification.h +++ b/DeviceIdentification/DeviceIdentification.h @@ -56,6 +56,9 @@ namespace Plugin { { _parent.Deactivated(connectionId); } + void Terminated(RPC::IRemoteConnection* /* connection */) override + { + } BEGIN_INTERFACE_MAP(Notification) INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) diff --git a/DeviceIdentification/Implementation/Amlogic/Amlogic.cpp b/DeviceIdentification/Implementation/Amlogic/Amlogic.cpp index ee554eca21..9fea4e873c 100644 --- a/DeviceIdentification/Implementation/Amlogic/Amlogic.cpp +++ b/DeviceIdentification/Implementation/Amlogic/Amlogic.cpp @@ -5,11 +5,15 @@ namespace WPEFramework { namespace Plugin { class DeviceImplementation : public PluginHost::ISubSystem::IIdentifier { - static constexpr const TCHAR* ChipsetInfo= _T("T962X3"); + static constexpr const TCHAR* ChipsetInfo= _T("T962X3"); static constexpr const TCHAR* VERSIONFile = _T("/version.txt"); + static constexpr const TCHAR* CMDLineFile = _T("/proc/cmdline"); public: DeviceImplementation() + : _chipset() + , _firmwareVersion() + , _identity() { UpdateChipset(_chipset); UpdateFirmwareVersion(_firmwareVersion); @@ -88,11 +92,26 @@ namespace Plugin { inline void UpdateIdentifier() { - /* - * @TODO : Update proper code for identifier when SOC ID is made - * available for Amlogic boards - */ - _identity.assign(""); + string line; + std::ifstream file(CMDLineFile); + if (file.is_open()) { + while (getline(file, line)) { + std::size_t position; + if ((position = line.find("serialno")) != std::string::npos) { + position = line.find("=", position); + if (position != std::string::npos) { + std::size_t begin = position + 2; + std::size_t end = line.find(' ', begin); + _identity.assign(line.substr(begin, (end - begin))); + break; + } + } + } + file.close(); + } + if (_identity.empty() == true) { + TRACE(Trace::Error, (_T("There is no any valid identifier available"))); + } } private: diff --git a/DeviceIdentification/Implementation/RPI/RPI.cpp b/DeviceIdentification/Implementation/RPI/RPI.cpp index 79d59ab4a5..a98803152c 100644 --- a/DeviceIdentification/Implementation/RPI/RPI.cpp +++ b/DeviceIdentification/Implementation/RPI/RPI.cpp @@ -92,9 +92,7 @@ namespace Plugin { } inline void UpdateDeviceIdentifier(string& identifier) const { - string fileName = SerialInfoPath; - WPEFramework::Core::File serialFile(fileName); - + WPEFramework::Core::File serialFile(SerialInfoPath); if (serialFile.Open(true) == true) { uint8_t serialInfo[serialFile.Size()]; uint32_t size = serialFile.Read(serialInfo, static_cast(sizeof(serialInfo))); diff --git a/DisplayInfo/CMakeLists.txt b/DisplayInfo/CMakeLists.txt index 346c0987b1..15e3842ce0 100644 --- a/DisplayInfo/CMakeLists.txt +++ b/DisplayInfo/CMakeLists.txt @@ -52,8 +52,6 @@ set_target_properties(${MODULE_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES) -target_compile_definitions(${MODULE_NAME} PRIVATE MODULE_NAME=Plugin_${PLUGIN_NAME}) - target_link_libraries(${MODULE_NAME} PRIVATE CompileSettingsDebug::CompileSettingsDebug diff --git a/DisplayInfo/DeviceSettings/Amlogic/SoC_abstraction.cpp b/DisplayInfo/DeviceSettings/Amlogic/SoC_abstraction.cpp index 824b633705..d9e7b4ca48 100644 --- a/DisplayInfo/DeviceSettings/Amlogic/SoC_abstraction.cpp +++ b/DisplayInfo/DeviceSettings/Amlogic/SoC_abstraction.cpp @@ -96,7 +96,7 @@ 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) + if (*plane) printf("fb id : %d\n", (*plane)->fb_id); } @@ -113,14 +113,14 @@ static void getGraphicSize(uint32_t &w, uint32_t &h) /* Setup KMS */ kms = kms_setup(drm_fd); - if(!kms || !kms->crtc ) { + if (!kms || !kms->crtc ) { cout << "[Amlogic] kms_setup fail" << endl; break; } /* Get primary buffer */ getPrimaryPlane(drm_fd, kms, &plane); - if( !plane) { + if ( !plane) { cout << "[Amlogic] fail to getPrimaryPlane" << endl; break; } @@ -137,7 +137,7 @@ static void getGraphicSize(uint32_t &w, uint32_t &h) } /* Get the width and height */ - if(fb) { + if (fb) { w = fb->width; h = fb->height; drmModeFreeFB(fb); @@ -146,14 +146,14 @@ static void getGraphicSize(uint32_t &w, uint32_t &h) /* release */ /* Cleanup buffer info */ - if(kms) { + if (kms) { kms_cleanup_context(kms); free(kms); } cout << "[getGraphicSize] width : " << w << endl; cout << "[getGraphicSize] height : " << h << endl; - if(drm_fd >= 0){ + if (drm_fd >= 0) { close(drm_fd); } } diff --git a/DisplayInfo/DeviceSettings/Amlogic/kms.c b/DisplayInfo/DeviceSettings/Amlogic/kms.c index cde7d05d7f..65aeb6b184 100644 --- a/DisplayInfo/DeviceSettings/Amlogic/kms.c +++ b/DisplayInfo/DeviceSettings/Amlogic/kms.c @@ -25,11 +25,11 @@ void kms_setup_encoder( int fd, kms_ctx *kms ) { - for( int i = 0; i < kms->res->count_encoders; i++ ) { + for ( int i = 0; i < kms->res->count_encoders; i++ ) { kms->encoder = drmModeGetEncoder(fd,kms->res->encoders[i]); - if(!kms->encoder){ + if ( !kms->encoder ) { return; } @@ -40,9 +40,9 @@ void kms_setup_encoder( int fd, kms_ctx *kms ) } - for( int j = 0; j < kms->res->count_crtcs; j++ ) { + for ( int j = 0; j < kms->res->count_crtcs; j++ ) { - if( kms->encoder->possible_crtcs & ( 1 << j ) ) { + if ( kms->encoder->possible_crtcs & ( 1 << j ) ) { drmModeFreeEncoder( kms->encoder ); kms->encoder = drmModeGetEncoder(fd, kms->res->encoders[j]); @@ -65,12 +65,12 @@ void kms_setup_connector( int fd, kms_ctx *kms ) int i = 0; drmModeConnector *connector = NULL; - for( i = 0; i < kms->res->count_connectors; i++ ) { + for ( i = 0; i < kms->res->count_connectors; i++ ) { connector = drmModeGetConnector(fd, kms->res->connectors[i]); - if( connector ) { + if ( connector ) { - if( connector->count_modes && ( connector->connection == DRM_MODE_CONNECTED ) ) { + if ( connector->count_modes && ( connector->connection == DRM_MODE_CONNECTED ) ) { break; } } @@ -88,11 +88,11 @@ void kms_setup_connector( int fd, kms_ctx *kms ) void kms_setup_crtc( int fd, kms_ctx *kms ) { - if( kms->encoder ) { + if ( kms->encoder ) { kms->crtc = drmModeGetCrtc(fd, kms->encoder->crtc_id); - if( kms->crtc && kms->crtc->mode_valid ) { + if ( kms->crtc && kms->crtc->mode_valid ) { kms->current_info = kms->crtc->mode; kms->crtc_id = kms->encoder->crtc_id; @@ -107,7 +107,7 @@ kms_ctx* kms_setup( int fd ) { kms_ctx *kms = NULL; kms = (kms_ctx*)calloc(1,sizeof(*kms)); - if( !kms ) + if ( !kms ) assert(0); kms->res = drmModeGetResources(fd); @@ -121,16 +121,16 @@ kms_ctx* kms_setup( int fd ) void kms_cleanup_context( kms_ctx *kms ) { - if( kms->connector ) + if ( kms->connector ) drmModeFreeConnector(kms->connector); - if( kms->encoder ) + if ( kms->encoder ) drmModeFreeEncoder(kms->encoder); - if( kms->crtc ) + if ( kms->crtc ) drmModeFreeCrtc(kms->crtc); - if( kms->res ) + if ( kms->res ) drmModeFreeResources(kms->res); } @@ -172,7 +172,7 @@ void kms_get_plane( int fd, kms_ctx *kms ) planeRes = drmModeGetPlaneResources( fd ); if ( planeRes ) { - for( n= 0; n < planeRes->count_planes; ++n ) { + for ( n= 0; n < planeRes->count_planes; ++n ) { plane = drmModeGetPlane( fd, planeRes->planes[n] ); @@ -181,7 +181,7 @@ void kms_get_plane( int fd, kms_ctx *kms ) props = drmModeObjectGetProperties( fd, planeRes->planes[n], DRM_MODE_OBJECT_PLANE ); if ( props ) { - for( j= 0; j < props->count_props; ++j ) { + for ( j= 0; j < props->count_props; ++j ) { prop = drmModeGetProperty( fd, props->props[j] ); if ( prop ) { diff --git a/DisplayInfo/DeviceSettings/Broadcom/SoC_abstraction.cpp b/DisplayInfo/DeviceSettings/Broadcom/SoC_abstraction.cpp index 505f3ecd55..ca2e35a485 100644 --- a/DisplayInfo/DeviceSettings/Broadcom/SoC_abstraction.cpp +++ b/DisplayInfo/DeviceSettings/Broadcom/SoC_abstraction.cpp @@ -96,14 +96,14 @@ string parse_proc_brcm_core(string columnHeader) { while (getline(procfile,line)) { - if(line.find(columnHeader) != string::npos) + if (line.find(columnHeader) != string::npos) { tokens.clear(); sanitizeLine(line); tokenize(line, tokens, ' '); column = find(tokens.begin(), tokens.end(), columnHeader) - tokens.begin(); //found the column where the data can be found } - if(line.find("GFX") != string::npos) + if (line.find("GFX") != string::npos) { tokens.clear(); sanitizeLine(line); @@ -132,7 +132,7 @@ string parse_proc_brcm_display() { while (getline(procfile,line)) { - if(line.find("graphics") != string::npos) + if (line.find("graphics") != string::npos) { tokens.clear(); sanitizeLine(line); @@ -189,7 +189,7 @@ uint32_t SoC_GetGraphicsWidth() string value = parse_proc_brcm_display(); LOGINFO("graphics plane dimensions returned from proc = %s" , value.c_str()); tokenize(value, resolution, 'x'); // graphics resolution is in the format 1280x720 - if(resolution.size() > WIDTH) + if (resolution.size() > WIDTH) { try { @@ -212,7 +212,7 @@ uint32_t SoC_GetGraphicsHeight() string value = parse_proc_brcm_display(); LOGINFO("graphics plane dimensions returned from proc = %s" , value.c_str()); tokenize(value, resolution, 'x'); // graphics resolution is in the format 1280x720 - if(resolution.size() > HEIGHT) + if (resolution.size() > HEIGHT) { try { @@ -225,4 +225,4 @@ uint32_t SoC_GetGraphicsHeight() } } return ret; -} \ No newline at end of file +} diff --git a/DisplayInfo/DeviceSettings/PlatformImplementation.cpp b/DisplayInfo/DeviceSettings/PlatformImplementation.cpp index e2fd03ccb6..bdf04136eb 100644 --- a/DisplayInfo/DeviceSettings/PlatformImplementation.cpp +++ b/DisplayInfo/DeviceSettings/PlatformImplementation.cpp @@ -146,7 +146,7 @@ class DisplayInfoImplementation : } } - if(DisplayInfoImplementation::_instance) + if (DisplayInfoImplementation::_instance) { DisplayInfoImplementation::_instance->ResolutionChangeImpl(eventtype); } @@ -245,7 +245,7 @@ class DisplayInfoImplementation : int hdcpversion = 1; string portname; PortName(portname); - if(!portname.empty()) + if (!portname.empty()) { try { @@ -275,7 +275,7 @@ class DisplayInfoImplementation : dsHdcpProtocolVersion_t hdcpversion = dsHDCP_VERSION_MAX; string portname; PortName(portname); - if(!portname.empty()) + if (!portname.empty()) { switch(value) { @@ -287,7 +287,7 @@ class DisplayInfoImplementation : try { device::VideoOutputPort vPort = device::Host::getInstance().getVideoOutputPort(portname); - if(!vPort.SetHdmiPreference(hdcpversion)) + if (!vPort.SetHdmiPreference(hdcpversion)) { TRACE(Trace::Information, (_T("HDCPProtection: SetHdmiPreference failed"))); } @@ -312,7 +312,7 @@ class DisplayInfoImplementation : if (Core::ERROR_NONE == ret) { std::string strVideoPort = device::Host::getInstance().getDefaultVideoPortName(); - if(edidVec.size() > EDID_MAX_VERTICAL_SIZE) + if (edidVec.size() > EDID_MAX_VERTICAL_SIZE) { width = edidVec[EDID_MAX_HORIZONTAL_SIZE]; TRACE(Trace::Information, (_T("Width in cm = %d"), width)); @@ -338,7 +338,7 @@ class DisplayInfoImplementation : vPort.getDisplay().getEDIDBytes(edidVec); - if(edidVec.size() > EDID_MAX_VERTICAL_SIZE) + if (edidVec.size() > EDID_MAX_VERTICAL_SIZE) { height = edidVec[EDID_MAX_VERTICAL_SIZE]; TRACE(Trace::Information, (_T("Height in cm = %d"), height)); @@ -383,7 +383,7 @@ class DisplayInfoImplementation : } //convert to base64 uint16_t size = min(edidVec.size(), (size_t)numeric_limits::max()); - if(edidVec.size() > (size_t)numeric_limits::max()) + if (edidVec.size() > (size_t)numeric_limits::max()) LOGERR("Size too large to use ToString base64 wpe api"); int i = 0; for (; i < length && i < size; i++) @@ -474,19 +474,19 @@ class DisplayInfoImplementation : device::FrameRate fr = resolution.getFrameRate(); if (fr == device::FrameRate::k24 ) { rate = FRAMERATE_24; - } else if(fr == device::FrameRate::k25) { + } else if (fr == device::FrameRate::k25) { rate = FRAMERATE_25; - } else if(fr == device::FrameRate::k30) { + } else if (fr == device::FrameRate::k30) { rate = FRAMERATE_30; - } else if(fr == device::FrameRate::k60) { + } else if (fr == device::FrameRate::k60) { rate = FRAMERATE_60; - } else if(fr == device::FrameRate::k23dot98) { + } else if (fr == device::FrameRate::k23dot98) { rate = FRAMERATE_23_976; - } else if(fr == device::FrameRate::k29dot97) { + } else if (fr == device::FrameRate::k29dot97) { rate = FRAMERATE_29_97; - } else if(fr == device::FrameRate::k50) { + } else if (fr == device::FrameRate::k50) { rate = FRAMERATE_50; - } else if(fr == device::FrameRate::k59dot94) { + } else if (fr == device::FrameRate::k59dot94) { rate = FRAMERATE_59_94; } else { rate = FRAMERATE_UNKNOWN; @@ -675,12 +675,12 @@ class DisplayInfoImplementation : { TRACE(Trace::Error, (_T("Exception during DeviceSetting library call. code = %d message = %s"), err.getCode(), err.what())); } - if(!capabilities) hdrCapabilities.push_back(HDR_OFF); - if(capabilities & dsHDRSTANDARD_HDR10) hdrCapabilities.push_back(HDR_10); - if(capabilities & dsHDRSTANDARD_HLG) hdrCapabilities.push_back(HDR_HLG); - if(capabilities & dsHDRSTANDARD_DolbyVision) hdrCapabilities.push_back(HDR_DOLBYVISION); - if(capabilities & dsHDRSTANDARD_TechnicolorPrime) hdrCapabilities.push_back(HDR_TECHNICOLOR); - if(capabilities & dsHDRSTANDARD_Invalid)hdrCapabilities.push_back(HDR_OFF); + if (!capabilities) hdrCapabilities.push_back(HDR_OFF); + if (capabilities & dsHDRSTANDARD_HDR10) hdrCapabilities.push_back(HDR_10); + if (capabilities & dsHDRSTANDARD_HLG) hdrCapabilities.push_back(HDR_HLG); + if (capabilities & dsHDRSTANDARD_DolbyVision) hdrCapabilities.push_back(HDR_DOLBYVISION); + if (capabilities & dsHDRSTANDARD_TechnicolorPrime) hdrCapabilities.push_back(HDR_TECHNICOLOR); + if (capabilities & dsHDRSTANDARD_Invalid)hdrCapabilities.push_back(HDR_OFF); type = Core::Service::Create(hdrCapabilities); @@ -703,12 +703,12 @@ class DisplayInfoImplementation : { TRACE(Trace::Error, (_T("Exception during DeviceSetting library call. code = %d message = %s"), err.getCode(), err.what())); } - if(!capabilities) hdrCapabilities.push_back(HDR_OFF); - if(capabilities & dsHDRSTANDARD_HDR10) hdrCapabilities.push_back(HDR_10); - if(capabilities & dsHDRSTANDARD_HLG) hdrCapabilities.push_back(HDR_HLG); - if(capabilities & dsHDRSTANDARD_DolbyVision) hdrCapabilities.push_back(HDR_DOLBYVISION); - if(capabilities & dsHDRSTANDARD_TechnicolorPrime) hdrCapabilities.push_back(HDR_TECHNICOLOR); - if(capabilities & dsHDRSTANDARD_Invalid)hdrCapabilities.push_back(HDR_OFF); + if (!capabilities) hdrCapabilities.push_back(HDR_OFF); + if (capabilities & dsHDRSTANDARD_HDR10) hdrCapabilities.push_back(HDR_10); + if (capabilities & dsHDRSTANDARD_HLG) hdrCapabilities.push_back(HDR_HLG); + if (capabilities & dsHDRSTANDARD_DolbyVision) hdrCapabilities.push_back(HDR_DOLBYVISION); + if (capabilities & dsHDRSTANDARD_TechnicolorPrime) hdrCapabilities.push_back(HDR_TECHNICOLOR); + if (capabilities & dsHDRSTANDARD_Invalid)hdrCapabilities.push_back(HDR_OFF); type = Core::Service::Create(hdrCapabilities); diff --git a/DisplayInfo/DeviceSettings/Realtek/SoC_abstraction.cpp b/DisplayInfo/DeviceSettings/Realtek/SoC_abstraction.cpp index 85c8788a12..fbcd0ef788 100644 --- a/DisplayInfo/DeviceSettings/Realtek/SoC_abstraction.cpp +++ b/DisplayInfo/DeviceSettings/Realtek/SoC_abstraction.cpp @@ -95,7 +95,7 @@ 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) + if (*plane) printf("fb id : %d\n", (*plane)->fb_id); } @@ -112,14 +112,14 @@ static void getGraphicSize(uint32_t &w, uint32_t &h) /* Setup KMS */ kms = kms_setup(drm_fd); - if(!kms || !kms->crtc ) { + if (!kms || !kms->crtc ) { cout << "[Realtek] kms_setup fail" << endl; break; } /* Get primary buffer */ getPrimaryPlane(drm_fd, kms, &plane); - if( !plane) { + if ( !plane) { cout << "[Realtek] fail to getPrimaryPlane" << endl; break; } @@ -136,7 +136,7 @@ static void getGraphicSize(uint32_t &w, uint32_t &h) } /* Get the width and height */ - if(fb) { + if (fb) { w = fb->width; h = fb->height; drmModeFreeFB(fb); @@ -145,7 +145,7 @@ static void getGraphicSize(uint32_t &w, uint32_t &h) /* release */ /* Cleanup buffer info */ - if(kms) { + if (kms) { kms_cleanup_context(kms); free(kms); } diff --git a/DisplayInfo/DeviceSettings/Realtek/kms.c b/DisplayInfo/DeviceSettings/Realtek/kms.c index 6253b177b8..428f8ec601 100644 --- a/DisplayInfo/DeviceSettings/Realtek/kms.c +++ b/DisplayInfo/DeviceSettings/Realtek/kms.c @@ -30,7 +30,7 @@ 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){ + if (!kms->encoder){ return; } @@ -43,7 +43,7 @@ void kms_setup_encoder( int fd, kms_ctx *kms ) for( int j = 0; j < kms->res->count_crtcs; j++ ) { - if( kms->encoder->possible_crtcs & ( 1 << j ) ) { + if ( kms->encoder->possible_crtcs & ( 1 << j ) ) { drmModeFreeEncoder( kms->encoder ); kms->encoder = drmModeGetEncoder(fd, kms->res->encoders[j]); @@ -70,9 +70,9 @@ void kms_setup_connector( int fd, kms_ctx *kms ) for( i = 0; i < kms->res->count_connectors; i++ ) { connector = drmModeGetConnector(fd, kms->res->connectors[i]); - if( connector ) { + if ( connector ) { - if( connector->count_modes && ( connector->connection == DRM_MODE_CONNECTED ) ) { + if ( connector->count_modes && ( connector->connection == DRM_MODE_CONNECTED ) ) { break; } } @@ -90,11 +90,11 @@ void kms_setup_connector( int fd, kms_ctx *kms ) void kms_setup_crtc( int fd, kms_ctx *kms ) { - if( kms->encoder ) { + if ( kms->encoder ) { kms->crtc = drmModeGetCrtc(fd, kms->encoder->crtc_id); - if( kms->crtc && kms->crtc->mode_valid ) { + if ( kms->crtc && kms->crtc->mode_valid ) { kms->current_info = kms->crtc->mode; kms->crtc_id = kms->encoder->crtc_id; @@ -109,7 +109,7 @@ kms_ctx* kms_setup( int fd ) { kms_ctx *kms = NULL; kms = (kms_ctx*)calloc(1,sizeof(*kms)); - if( !kms ) + if ( !kms ) assert(0); kms->res = drmModeGetResources(fd); @@ -123,16 +123,16 @@ kms_ctx* kms_setup( int fd ) void kms_cleanup_context( kms_ctx *kms ) { - if( kms->connector ) + if ( kms->connector ) drmModeFreeConnector(kms->connector); - if( kms->encoder ) + if ( kms->encoder ) drmModeFreeEncoder(kms->encoder); - if( kms->crtc ) + if ( kms->crtc ) drmModeFreeCrtc(kms->crtc); - if( kms->res ) + if ( kms->res ) drmModeFreeResources(kms->res); } diff --git a/DisplayInfo/DisplayInfo.cpp b/DisplayInfo/DisplayInfo.cpp index 50f844a3a9..7635ba98a0 100644 --- a/DisplayInfo/DisplayInfo.cpp +++ b/DisplayInfo/DisplayInfo.cpp @@ -88,9 +88,7 @@ namespace Plugin { _displayProperties = _connectionProperties->QueryInterface(); if (_displayProperties == nullptr) { SYSLOG(Logging::Startup, (_T("Display Properties service is unavailable."))); - } - else - { + } else { Exchange::JDisplayProperties::Register(*this, _displayProperties); } } @@ -99,65 +97,68 @@ namespace Plugin { message = _T("DisplayInfo could not be instantiated. Could not acquire ConnectionProperties interface"); } +#ifndef USE_THUNDER_R4 if (message.length() != 0) { Deinitialize(service); } +#endif return message; } void DisplayInfo::Deinitialize(PluginHost::IShell* service) /* override */ { - ASSERT(service == _service); + if (_service != nullptr) { + ASSERT(service == _service); - _service->Unregister(&_notification); + _service->Unregister(&_notification); - if(_connectionProperties != nullptr) { - _connectionProperties->Unregister(&_notification); - Exchange::JConnectionProperties::Unregister(*this); + if (_connectionProperties != nullptr) { + _connectionProperties->Unregister(&_notification); + Exchange::JConnectionProperties::Unregister(*this); - if (_hdrProperties != nullptr) { - Exchange::JHDRProperties::Unregister(*this); - _hdrProperties->Release(); - _hdrProperties = nullptr; - } + if (_hdrProperties != nullptr) { + Exchange::JHDRProperties::Unregister(*this); + _hdrProperties->Release(); + _hdrProperties = nullptr; + } - if (_graphicsProperties != nullptr) { - Exchange::JGraphicsProperties::Unregister(*this); - _graphicsProperties->Release(); - _graphicsProperties = nullptr; - } + if (_graphicsProperties != nullptr) { + Exchange::JGraphicsProperties::Unregister(*this); + _graphicsProperties->Release(); + _graphicsProperties = nullptr; + } - if (_displayProperties != nullptr) - { - _displayProperties->Release(); - Exchange::JDisplayProperties::Unregister(*this); - _displayProperties = nullptr; - } + if (_displayProperties != nullptr) { + _displayProperties->Release(); + Exchange::JDisplayProperties::Unregister(*this); + _displayProperties = nullptr; + } - // Stop processing: - RPC::IRemoteConnection* connection = service->RemoteConnection(_connectionId); - VARIABLE_IS_NOT_USED uint32_t result = _connectionProperties->Release(); - _connectionProperties = nullptr; - - // It should have been the last reference we are releasing, - // so it should endup in a DESTRUCTION_SUCCEEDED, if not we - // are leaking... - ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); - - // If this was running in a (container) process... - if (connection != nullptr) { - // Lets trigger the cleanup sequence for - // out-of-process code. Which will guard - // that unwilling processes, get shot if - // not stopped friendly :-) - connection->Terminate(); - connection->Release(); + // Stop processing: + RPC::IRemoteConnection* connection = service->RemoteConnection(_connectionId); + VARIABLE_IS_NOT_USED uint32_t result = _connectionProperties->Release(); + _connectionProperties = nullptr; + + // It should have been the last reference we are releasing, + // so it should endup in a DESTRUCTION_SUCCEEDED, if not we + // are leaking... + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + + // If this was running in a (container) process... + if (connection != nullptr) { + // Lets trigger the cleanup sequence for + // out-of-process code. Which will guard + // that unwilling processes, get shot if + // not stopped friendly :-) + connection->Terminate(); + connection->Release(); + } } + _connectionId = 0; + _service->Release(); + _service = nullptr; } - _connectionId = 0; - _service->Release(); - _service = nullptr; } string DisplayInfo::Information() const /* override */ diff --git a/DisplayInfo/ExtendedDisplayIdentification.h b/DisplayInfo/ExtendedDisplayIdentification.h new file mode 100644 index 0000000000..acc452c412 --- /dev/null +++ b/DisplayInfo/ExtendedDisplayIdentification.h @@ -0,0 +1,315 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include "Module.h" + +namespace WPEFramework { +namespace Plugin { + + class ExtendedDisplayIdentification { + public: + enum Type { + Undefined = 0, + HDMIa = 2, + HDMIb = 3, + MDDI = 4, + DisplayPort = 5 + }; + + class Buffer { + private: + static constexpr uint16_t edid_block_size = 128; + public: + Buffer() { + } + Buffer(const Buffer& copy) { + ::memcpy(_data, copy._data, sizeof(_data)); + } + ~Buffer() = default; + + Buffer& operator= (const Buffer& copy) = delete; + + public: + uint16_t Length() const { + return (edid_block_size); + } + operator uint8_t* () { + return (_data); + } + operator const uint8_t* () const { + return (_data); + } + + private: + uint8_t _data[edid_block_size]; + }; + + using BufferList = std::list; + + class Iterator { + public: + Iterator() + : _segments(nullptr) + , _index() + , _reset(true) { + } + Iterator(const BufferList& rhs) + : _segments(&rhs) + , _index() + , _reset(true) { + } + Iterator(const Iterator& copy) + : _segments(copy._segments) + , _index() + , _reset(true) { + } + ~Iterator() = default; + + Iterator& operator= (const Iterator&) = delete; + + public: + bool IsValid() const { + return ((_reset == false) && (_segments != nullptr) && (_index != _segments->cend())); + } + void Reset() { + _reset = true; + } + bool Next() { + if (_reset == true) { + _reset = false; + + if (_segments != nullptr) { + _index = _segments->cbegin(); + } + } + else if ((_segments != nullptr) && (_index != _segments->cend())) { + _index++; + } + return ((_segments != nullptr) && (_index != _segments->cend())); + } + uint8_t Type() const { + return (IsValid() ? (*_index)[0] : 0xFF); + } + const Buffer& Current() const { + ASSERT(IsValid() == true); + return (*_index); + } + + private: + const BufferList* _segments; + BufferList::const_iterator _index; + bool _reset; + }; + + class CEA { + public: + CEA() = delete; + CEA(const CEA&) = delete; + CEA& operator= (const CEA&) = delete; + + CEA(const Buffer& data) + : _segment(data) { + ASSERT(_segment[0] == 0x02); + } + ~CEA() { + } + + public: + uint8_t Version() const { + return (_segment[1]); + } + + private: + Buffer _segment; + }; + + + public: + ExtendedDisplayIdentification (const ExtendedDisplayIdentification&) = delete; + ExtendedDisplayIdentification& operator= (const ExtendedDisplayIdentification&) = delete; + + ExtendedDisplayIdentification() + : _segments() { + // It is already invalid if the first byte != 0x00 + _base[0] = 0x55; + } + ~ExtendedDisplayIdentification() { + } + + public: + // ------------------------------------------------------------- + // Only use the accessors if this method return true!!! + // ------------------------------------------------------------- + inline bool IsValid() const { + return ( (_base[0] == 0x00) && + (_base[1] == 0xFF) && + (_base[2] == 0xFF) && + (_base[3] == 0xFF) && + (_base[4] == 0xFF) && + (_base[5] == 0xFF) && + (_base[6] == 0xFF) && + (_base[7] == 0x00) ); + } + + uint16_t Raw(const uint16_t length, uint8_t data[]) const { + uint16_t written = 0; + + // We always have a base if it is valid... + if (IsValid() == true) { + uint16_t segment = std::min(Length(), length); + BufferList::const_iterator index(_segments.cbegin()); + + // By definition, we can copy the base... + ::memcpy(data, _base, segment); + written = segment; + + while ( (written < length) && (index != _segments.cend()) ) { + segment = std::min(Length(), static_cast(length - written)); + ::memcpy(&(data[written]), *index, segment); + index++; + written += segment; + } + } + + return (written); + } + + // ------------------------------------------------------------- + // Accessors to the base information of the EDID raw buffer. + // ------------------------------------------------------------- + string Manufacturer() const { + string result; + if (IsValid() == true) { + uint16_t value = ((_base[0x08] << 8) | (_base[0x09])); + result = ManufactereChar(value >> 10); + result += ManufactereChar(value >> 5); + result += ManufactereChar(value); + } + return (result); + } + uint16_t ProductCode() const { + uint16_t result = ~0; + + if (IsValid() == true) { + result = _base[0x0B] << 8 | + _base[0x0A]; + } + return (result); + } + uint32_t Serial() const { + uint32_t result = ~0; + if (IsValid() == true) { + result = _base[0x0F] << 24 | + _base[0x0E] << 16 | + _base[0x0D] << 8 | + _base[0x0C]; + } + return (result); + } + // If the Week = 0xFF, it means the year is the year when this model was + // release. If 0 <= week <= 53 the year represnt the year when the device + // was manufactured. + uint8_t Week() const { + return (IsValid() ? _base[0x10] : 0x00); + } + uint16_t Year() const { + return (IsValid() ? 1990 + _base[0x11] : 0x00); + } + uint8_t Major() const { + return (IsValid() ? _base[0x12] : 0x00); + } + uint8_t Minor() const { + return (IsValid() ? _base[0x13] : 0x00); + } + + bool Digital() const { + return ((_base[14] & 0x80) != 0); + } + uint8_t BitsPerColor() const { + static uint8_t bitsPerColor[] = { 0, 6, 8, 10, 12, 14, 16, 255 }; + return (bitsPerColor[(_base[0x14] >> 4) & 0x7]); + } + Type VideoInterface() const { + return (static_cast (_base[0x14] & 0x0F)); + } + + Iterator Extensions() const { + return (Iterator(_segments)); + } + + // ------------------------------------------------------------- + // Operators to get access to the EDID strorage raw information. + // ------------------------------------------------------------- + uint16_t Length () const { + return (_base.Length()); + } + uint8_t Segments() const { + return (IsValid() ? _base[0x7e] + 1 : 1); + } + uint8_t* Segment(const uint8_t index) { + uint8_t* result = nullptr; + + ASSERT (index <= Segments()); + + if (index == 0) { + result = _base.operator uint8_t* (); + } + else if (index <= Segments()) { + BufferList::iterator pointer = _segments.begin(); + uint8_t current = 1; + while (current <= index) { + if (pointer != _segments.end()) { + pointer++; + } + else { + _segments.emplace_back(); + } + current++; + } + result = (pointer != _segments.end() ? pointer->operator uint8_t*() : _segments.back().operator uint8_t* ()); + } + + return (result); + } + + uint8_t WidthInCentimeters() const { + return IsValid() ? _base[21] : 0; + } + + uint8_t HeightInCentimeters() const { + return IsValid() ? _base[22] : 0; + } + + void Clear() { + _base[0] = 0x55; + _segments.clear(); + } + + private: + inline TCHAR ManufactereChar(uint8_t value) const { + return static_cast('A' + ((value - 1) & 0x1F)); + } + + private: + Buffer _base; + BufferList _segments; + }; +} +} diff --git a/DisplayInfo/Linux/PlatformImplementation.cpp b/DisplayInfo/Linux/PlatformImplementation.cpp index 84827fd143..5f77d52b05 100644 --- a/DisplayInfo/Linux/PlatformImplementation.cpp +++ b/DisplayInfo/Linux/PlatformImplementation.cpp @@ -140,11 +140,22 @@ namespace Plugin { */ static constexpr auto UDEV_MONITOR_MAGIC = 0xfeedcafe; struct udev_monitor_netlink_header { + /* "libudev" prefix to distinguish libudev and kernel messages */ char prefix[8]; + /* + * magic to protect against daemon <-> library message format mismatch + * used in the kernel from socket filter rules; needs to be stored in network order + */ unsigned int magic; + /* total length of header structure known to the sender */ unsigned int header_size; + /* properties string buffer */ unsigned int properties_off; unsigned int properties_len; + /* + * hashes of primary device properties strings, to let libudev subscribers + * use in-kernel socket filters; values need to be stored in network order + */ unsigned int filter_subsystem_hash; unsigned int filter_devtype_hash; unsigned int filter_tag_bloom_hi; @@ -428,7 +439,9 @@ namespace Plugin { Exchange::IConnectionProperties::HDCPProtectionType _hdcpLevel; }; - class DisplayInfoImplementation : public Exchange::IConnectionProperties, public Exchange::IConfiguration { + class DisplayInfoImplementation : public Exchange::IConnectionProperties, + public Exchange::IConfiguration, + public Exchange::IDisplayProperties { public: DisplayInfoImplementation(const DisplayInfoImplementation&) = delete; @@ -625,9 +638,40 @@ namespace Plugin { } } + uint32_t ColorSpace(ColourSpaceType&) const override + { + return (Core::ERROR_UNAVAILABLE); + } + + uint32_t FrameRate(FrameRateType&) const override + { + return (Core::ERROR_UNAVAILABLE); + } + + uint32_t ColourDepth(ColourDepthType&) const override + { + return (Core::ERROR_UNAVAILABLE); + } + + uint32_t Colorimetry(IColorimetryIterator*&) const override + { + return (Core::ERROR_UNAVAILABLE); + } + + uint32_t QuantizationRange(QuantizationRangeType&) const override + { + return (Core::ERROR_UNAVAILABLE); + } + + uint32_t EOTF(EotfType&) const override + { + return (Core::ERROR_UNAVAILABLE); + } + BEGIN_INTERFACE_MAP(DisplayInfoImplementation) INTERFACE_ENTRY(Exchange::IConnectionProperties) INTERFACE_ENTRY(Exchange::IConfiguration) + INTERFACE_ENTRY(Exchange::IDisplayProperties) INTERFACE_AGGREGATE(Exchange::IGraphicsProperties, _graphics) INTERFACE_AGGREGATE(Exchange::IHDRProperties, _hdr) END_INTERFACE_MAP diff --git a/DisplayInfo/RPI/PlatformImplementation.cpp b/DisplayInfo/RPI/PlatformImplementation.cpp index ff8436b183..0e18254a84 100644 --- a/DisplayInfo/RPI/PlatformImplementation.cpp +++ b/DisplayInfo/RPI/PlatformImplementation.cpp @@ -1,4 +1,4 @@ -/* +/* * If not stated otherwise in this file or this component's LICENSE file the * following copyright and licenses apply: * @@ -256,7 +256,7 @@ class DisplayInfoImplementation : public Exchange::IHDRProperties, return (Core::ERROR_UNAVAILABLE); } - virtual uint32_t EOTF(EotfType&) const override + uint32_t EOTF(EotfType&) const override { return (Core::ERROR_UNAVAILABLE); } diff --git a/LocationSync/CMakeLists.txt b/LocationSync/CMakeLists.txt index 7a5418b36e..386b04af39 100644 --- a/LocationSync/CMakeLists.txt +++ b/LocationSync/CMakeLists.txt @@ -26,10 +26,12 @@ set(MODULE_NAME ${NAMESPACE}${PROJECT_NAME}) 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_OVERRIDE_TIMEZONE CACHE STRING "Override Timezone value") set(PLUGIN_LOCATIONSYNC_STARTUPORDER "" CACHE STRING "To configure startup order of LocationSync plugin") find_package(${NAMESPACE}Plugins REQUIRED) find_package(CompileSettingsDebug CONFIG REQUIRED) +find_package(${NAMESPACE}Definitions REQUIRED) add_library(${MODULE_NAME} SHARED Module.cpp @@ -45,7 +47,8 @@ set_target_properties(${MODULE_NAME} PROPERTIES 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) diff --git a/LocationSync/LocationService.cpp b/LocationSync/LocationService.cpp index 075ffe7a05..77ab490d61 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 { @@ -325,12 +338,15 @@ namespace Plugin { , _remoteId() , _sourceNode() , _tryInterval(0) + , _retries(UINT32_MAX) , _callback(callback) , _publicIPAddress() , _timeZone() , _country() , _region() , _city() + , _latitude() + , _longitude() , _activity(*this) , _infoCarrier() , _request(Core::ProxyType::Create()) @@ -376,7 +392,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; @@ -465,6 +485,8 @@ namespace Plugin { _country = _infoCarrier->Country(); _region = _infoCarrier->Region(); _city = _infoCarrier->City(); + _latitude = _infoCarrier->Latitude(); + _longitude = _infoCarrier->Longitude(); if (_state == IPV6_INPROGRESS) { @@ -533,6 +555,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 +565,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 +579,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 +597,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); diff --git a/LocationSync/LocationService.h b/LocationSync/LocationService.h index 0381af7397..ca00a45b02 100644 --- a/LocationSync/LocationService.h +++ b/LocationSync/LocationService.h @@ -71,6 +71,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,7 +109,16 @@ namespace Plugin { { return (_city); } - +#ifdef USE_THUNDER_R4 + int32_t Latitude() const override + { + return (_latitude); + } + int32_t Longitude() const override + { + return (_longitude); + } +#endif private: // Notification of a Partial Request received, time to attach a body.. void LinkBody(Core::ProxyType& element) override; @@ -132,6 +144,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 ab5aa27ee9..e4ffa44d1c 100644 --- a/LocationSync/LocationSync.conf.in +++ b/LocationSync/LocationSync.conf.in @@ -5,5 +5,6 @@ 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.config b/LocationSync/LocationSync.config index bd71d3c592..c285b5a244 100644 --- a/LocationSync/LocationSync.config +++ b/LocationSync/LocationSync.config @@ -10,5 +10,9 @@ map() kv(interval 10) kv(retries 20) kv(source ${PLUGIN_LOCATIONSYNC_URI}) + if(PLUGIN_LOCATIONSYNC_OVERRIDE_TIMEZONE) + kv(timezone ${PLUGIN_LOCATIONSYNC_OVERRIDE_TIMEZONE}) + endif() + end() ans(configuration) diff --git a/LocationSync/LocationSync.cpp b/LocationSync/LocationSync.cpp index 6e3ed99941..8d0e47ed5b 100644 --- a/LocationSync/LocationSync.cpp +++ b/LocationSync/LocationSync.cpp @@ -39,8 +39,12 @@ namespace Plugin { , _source() , _sink(this) , _service(nullptr) + , _timezoneoverriden(false) + , _locationinfo() + , _adminLock() + , _timezoneoberservers() + , _activateOnFailure(true) { - RegisterAll(); } #ifdef __WINDOWS__ #pragma warning(default : 4355) @@ -48,7 +52,6 @@ namespace Plugin { LocationSync::~LocationSync() /* override */ { - UnregisterAll(); } const string LocationSync::Initialize(PluginHost::IShell* service) /* override */ @@ -56,27 +59,73 @@ namespace Plugin { 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 !!!"); } +#ifndef USE_THUNDER_R4 + if (result.length() != 0) { + Deinitialize(service); + } +#endif + // On success return empty, to indicate there is no error text. return (result); } 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(); - _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(); + } + + _service->Release(); + _service = nullptr; + } } string LocationSync::Information() const /* override */ @@ -149,24 +198,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 4bfcf64f54..ad5728f1f9 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: @@ -118,6 +121,11 @@ namespace Plugin { { return (_locator); } + bool Valid() const { + ASSERT(_locator != nullptr); + return _locator->Valid(); + } + private: inline uint32_t Probe() @@ -125,7 +133,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 +158,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 +179,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 +268,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 +286,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; + bool _timezoneoverriden; + Core::Sink _locationinfo; + mutable Core::CriticalSection _adminLock; + TimeZoneObservers _timezoneoberservers; + bool _activateOnFailure; }; } // namespace Plugin diff --git a/LocationSync/LocationSyncJsonRpc.cpp b/LocationSync/LocationSyncJsonRpc.cpp index 070eff0ac9..abcfb82cdd 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/MessageControl/CMakeLists.txt b/MessageControl/CMakeLists.txt index cae3802bdd..6fc1d7abf2 100644 --- a/MessageControl/CMakeLists.txt +++ b/MessageControl/CMakeLists.txt @@ -42,7 +42,6 @@ find_package(CompileSettingsDebug CONFIG REQUIRED) add_library(${MODULE_NAME} SHARED MessageControl.cpp MessageOutput.cpp - MessageControlImplementation.cpp Module.cpp) set_target_properties(${MODULE_NAME} PROPERTIES diff --git a/MessageControl/MessageControl.cpp b/MessageControl/MessageControl.cpp index f9964c69c4..574f88bba9 100644 --- a/MessageControl/MessageControl.cpp +++ b/MessageControl/MessageControl.cpp @@ -63,11 +63,21 @@ namespace WPEFramework { , _config() , _outputDirector() , _webSocketExporter() - , _control(nullptr) - , _collect(nullptr) + , _callback(nullptr) , _observer(*this) - , _connectionId(0) - , _service(nullptr) { + , _service(nullptr) + , _dispatcherIdentifier(Messaging::MessageUnit::Instance().Identifier()) + , _dispatcherBasePath(Messaging::MessageUnit::Instance().BasePath()) + , _client(_dispatcherIdentifier, _dispatcherBasePath, Messaging::MessageUnit::Instance().SocketPort()) + , _worker(*this) + , _tracingFactory() + , _loggingFactory() + , _warningReportingFactory() + { + _client.AddInstance(0); + _client.AddFactory(Core::Messaging::Metadata::type::TRACING, &_tracingFactory); + _client.AddFactory(Core::Messaging::Metadata::type::LOGGING, &_loggingFactory); + _client.AddFactory(Core::Messaging::Metadata::type::REPORTING, &_warningReportingFactory); } const string MessageControl::Initialize(PluginHost::IShell* service) @@ -79,109 +89,73 @@ namespace WPEFramework { _config.Clear(); _config.FromString(service->ConfigLine()); + Core::Messaging::MessageInfo::abbreviate abbreviate; + + if (_config.Abbreviated.Value() == 0) { + abbreviate = Core::Messaging::MessageInfo::abbreviate::FULL; + } + else { + abbreviate = Core::Messaging::MessageInfo::abbreviate::ABBREVIATED; + } + _service = service; _service->AddRef(); - _control = _service->Root(_connectionId, RPC::CommunicationTimeOut, _T("MessageControlImplementation")); - ASSERT(_control != nullptr); - - if (_control != nullptr) { - // Lets see if we can create the Message catcher... - _collect = _control->QueryInterface(); - ASSERT(_collect != nullptr); + if ((service->Background() == false) && (((_config.SysLog.IsSet() == false) && (_config.Console.IsSet() == false)) || (_config.Console.Value() == true))) { + Announce(new Publishers::ConsoleOutput(abbreviate)); } - - if (_control == nullptr) { - message = _T("MessageControl plugin could not be instantiated."); + if ((service->Background() == true) && (((_config.SysLog.IsSet() == false) && (_config.Console.IsSet() == false)) || (_config.SysLog.Value() == true))) { + Announce(new Publishers::SyslogOutput(abbreviate)); } - else if (_collect == nullptr) { - message = _T("MessageControl plugin could not be instantiated (collect)."); + if (_config.FileName.Value().empty() == false) { + _config.FileName = service->VolatilePath() + _config.FileName.Value(); + Announce(new Publishers::FileOutput(abbreviate, _config.FileName.Value())); + } + if ((_config.Remote.Binding.Value().empty() == false) && (_config.Remote.Port.Value() != 0)) { + Announce(new Publishers::UDPOutput(Core::NodeId(_config.Remote.NodeId()))); } - else { - if ((service->Background() == false) && (((_config.SysLog.IsSet() == false) && (_config.Console.IsSet() == false)) || (_config.Console.Value() == true))) { - Announce(new Publishers::ConsoleOutput(_config.Abbreviated.Value())); - } - if ((service->Background() == true) && (((_config.SysLog.IsSet() == false) && (_config.Console.IsSet() == false)) || (_config.SysLog.Value() == true))) { - Announce(new Publishers::SyslogOutput(_config.Abbreviated.Value())); - } - if (_config.FileName.Value().empty() == false) { - _config.FileName = service->VolatilePath() + _config.FileName.Value(); - Announce(new Publishers::FileOutput(_config.Abbreviated.Value(), _config.FileName.Value())); - } - if ((_config.Remote.Binding.Value().empty() == false) && (_config.Remote.Port.Value() != 0)) { - Announce(new Publishers::UDPOutput(Core::NodeId(_config.Remote.NodeId()))); - } - _webSocketExporter.Initialize(service, _config.MaxExportConnections.Value()); + _webSocketExporter.Initialize(service, _config.MaxExportConnections.Value()); - Exchange::JMessageControl::Register(*this, _control); + Exchange::JMessageControl::Register(*this, this); - _service->Register(&_observer); + _service->Register(&_observer); - if (_collect->Callback(&_observer) != Core::ERROR_NONE) { - message = _T("MessageControl plugin could not be _configured."); - } + if (Callback(&_observer) != Core::ERROR_NONE) { + message = _T("MessageControl plugin could not be _configured."); } - return message; + return (message); } - void MessageControl::Deinitialize(PluginHost::IShell* service) + void MessageControl::Deinitialize(VARIABLE_IS_NOT_USED PluginHost::IShell* service) { - ASSERT (_service == service); + if (_service != nullptr) { + ASSERT (_service == service); - if ((_collect != nullptr) && (_control != nullptr)) { Exchange::JMessageControl::Unregister(*this); - _collect->Callback(nullptr); + Callback(nullptr); - service->Unregister(&_observer); - } - - _outputLock.Lock(); - - _outputDirector.clear(); - _webSocketExporter.Deinitialize(); - - _outputLock.Unlock(); + _service->Unregister(&_observer); - RPC::IRemoteConnection* connection(service->RemoteConnection(_connectionId)); + _outputLock.Lock(); - if (_collect != nullptr) { - _collect->Release(); - _collect = nullptr; - } - - if (_control != nullptr) { - VARIABLE_IS_NOT_USED uint32_t result = _control->Release(); - _control = nullptr; + _webSocketExporter.Deinitialize(); - // It should have been the last reference we are releasing, - // so it should endup in a DESTRUCTION_SUCCEEDED, if not we - // are leaking... - ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); - } + _outputLock.Unlock(); - // The process can disappear in the meantime... - if (connection != nullptr) { - // But if it did not dissapear in the meantime, forcefully terminate it. Shoot to kill :-) - connection->Terminate(); - connection->Release(); - } + while (_outputDirector.empty() == false) { + delete _outputDirector.back(); + _outputDirector.pop_back(); + } - while (_outputDirector.empty() == false) { - delete _outputDirector.back(); - _outputDirector.pop_back(); + _service->Release(); + _service = nullptr; } - - _service->Release(); - _service = nullptr; - - _connectionId = 0; } - string MessageControl::Information() const - { + string MessageControl::Information() const { // No additional info to report. return (string()); } @@ -189,6 +163,7 @@ namespace WPEFramework { bool MessageControl::Attach(PluginHost::Channel& channel) { TRACE(Trace::Information, (Core::Format(_T("Attaching channel ID [%d]"), channel.Id()).c_str())); + return (_webSocketExporter.Attach(channel.Id())); } @@ -198,15 +173,13 @@ namespace WPEFramework { _webSocketExporter.Detach(channel.Id()); } - Core::ProxyType MessageControl::Inbound(const string&) - { + Core::ProxyType MessageControl::Inbound(const string&) { return (_webSocketExporter.Command()); } - Core::ProxyType MessageControl::Inbound(const uint32_t ID, const Core::ProxyType& element) - { + Core::ProxyType MessageControl::Inbound(const uint32_t ID, const Core::ProxyType& element) { return (Core::ProxyType(_webSocketExporter.Received(ID, element))); } } // namespace Plugin -} // namespace WPEFramework +} diff --git a/MessageControl/MessageControl.h b/MessageControl/MessageControl.h index bacaffac42..b2a3ada371 100644 --- a/MessageControl/MessageControl.h +++ b/MessageControl/MessageControl.h @@ -21,10 +21,56 @@ #include "Module.h" #include "MessageOutput.h" +#include namespace WPEFramework { + namespace Plugin { - class MessageControl : public PluginHost::JSONRPC, public PluginHost::IPluginExtended, public PluginHost::IWebSocket { + + class MessageControl : public PluginHost::JSONRPC, public PluginHost::IPluginExtended, public PluginHost::IWebSocket, public Exchange::IMessageControl { + private: + using Cleanups = std::vector; + + class WorkerThread : public Core::Thread { + public: + WorkerThread() = delete; + WorkerThread(const WorkerThread&) = delete; + WorkerThread& operator= (const WorkerThread&) = delete; + + WorkerThread(MessageControl& parent) + : Core::Thread() + , _parent(parent) + { + } + ~WorkerThread() override = default; + + private: + uint32_t Worker() override + { + _parent.Dispatch(); + + return (Core::infinite); + } + + private: + MessageControl& _parent; + }; + + private: + struct ICollect { + + struct ICallback { + + virtual void Message(const Core::Messaging::MessageInfo& metadata, const string& text) = 0; + + virtual ~ICallback() = default; + }; + + virtual uint32_t Callback(ICallback* callback) = 0; + + virtual ~ICollect() = default; + }; + private: using OutputList = std::vector; @@ -78,14 +124,14 @@ namespace Plugin { class Observer : public RPC::IRemoteConnection::INotification - , public Exchange::IMessageControl::ICollect::ICallback { + , public Plugin::MessageControl::ICollect::ICallback { private: enum state { ATTACHING, DETACHING, OBSERVING }; - using ObservingMap = std::unordered_map; + using Observers = std::unordered_map; public: Observer() = delete; @@ -96,7 +142,8 @@ namespace Plugin { : _parent(parent) , _adminLock() , _observing() - , _job(*this) { + , _job(*this) + { } ~Observer() override { _job.Revoke(); @@ -106,24 +153,21 @@ namespace Plugin { // // Exchange::IMessageControl::INotification // ---------------------------------------------------------- - void Message(const Exchange::IMessageControl::messagetype type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timestamp, const string& message) override { - _parent.Message(static_cast(type), module, category , fileName, lineNumber, className, timestamp, message); + void Message(const Core::Messaging::MessageInfo& metadata, const string& message) override { + _parent.Message(metadata, message); } // // RPC::IRemoteConnection::INotification // ---------------------------------------------------------- - void Activated(RPC::IRemoteConnection* connection) override { - + void Activated(RPC::IRemoteConnection* connection) override + { uint32_t id = connection->Id(); _adminLock.Lock(); // Seems the ID is already in here, thats odd, and impossible :-) - ObservingMap::iterator index = _observing.find(id); + Observers::iterator index = _observing.find(id); if (index == _observing.end()) { _observing.emplace(std::piecewise_construct, @@ -138,23 +182,53 @@ namespace Plugin { _job.Submit(); } - void Deactivated(RPC::IRemoteConnection* connection) override { - uint32_t id = connection->Id(); + void Deactivated(RPC::IRemoteConnection* connection) override + { + ASSERT(connection != nullptr); + + RPC::IMonitorableProcess* controlled (connection->QueryInterface()); + + if (controlled != nullptr) { + // This is a connection that is controleld by WPEFramework. For this we can wait till we + // receive a terminated. + controlled->Release(); + } + else { + // We have no clue where this is coming from, just assume that if there are message files + // with this ID that it can be closed. + Drop(connection->Id()); + } + } + + void Terminated(RPC::IRemoteConnection* connection) override + { + ASSERT(connection != nullptr); + Drop(connection->Id()); + } + BEGIN_INTERFACE_MAP(Observer) + INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) + END_INTERFACE_MAP + + private: + friend class Core::ThreadPool::JobType; + + void Drop (const uint32_t id) + { _adminLock.Lock(); // Seems the ID is already in here, thats odd, and impossible :-) - ObservingMap::iterator index = _observing.find(id); + Observers::iterator index = _observing.find(id); + + ASSERT(index != _observing.end()); if (index != _observing.end()) { if (index->second == state::ATTACHING) { _observing.erase(index); } else if (index->second == state::OBSERVING) { - _observing.emplace(std::piecewise_construct, - std::make_tuple(id), - std::make_tuple(state::DETACHING)); + index->second = state::DETACHING; } } @@ -163,32 +237,39 @@ namespace Plugin { _job.Submit(); } - BEGIN_INTERFACE_MAP(Observer) - INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) - INTERFACE_ENTRY(Exchange::IMessageControl::ICollect::ICallback) - END_INTERFACE_MAP - - private: - friend class Core::ThreadPool::JobType; - void Dispatch() { _adminLock.Lock(); - ObservingMap::iterator index = _observing.begin(); - - while (index != _observing.end()) { - if (index->second == state::ATTACHING) { - index->second = state::OBSERVING; - _parent.Attach(index->first); - index++; - } - else if (index->second == state::DETACHING) { - _parent.Detach(index->first); - index = _observing.erase(index); - } - else { - index++; + bool done = false; + + while (done == false) { + Observers::iterator index = _observing.begin(); + + while (done == false) { + if (index->second == state::ATTACHING) { + const uint32_t id = index->first; + index->second = state::OBSERVING; + _adminLock.Unlock(); + _parent.Attach(id); + _adminLock.Lock(); + break; + } + else if (index->second == state::DETACHING) { + const uint32_t id = index->first; + _observing.erase(index); + _adminLock.Unlock(); + _parent.Detach(id); + _adminLock.Lock(); + break; + } + else { + index++; + + if (index == _observing.end()) { + done = true; + } + } } } @@ -198,7 +279,7 @@ namespace Plugin { private: MessageControl& _parent; Core::CriticalSection _adminLock; - ObservingMap _observing; + Observers _observing; Core::WorkerPool::JobType _job; }; @@ -207,13 +288,20 @@ namespace Plugin { MessageControl& operator=(const MessageControl&) = delete; MessageControl(); - ~MessageControl() override = default; + + ~MessageControl() override + { + _worker.Stop(); + _worker.Wait(Core::Thread::STOPPED, Core::infinite); + _client.ClearInstances(); + } BEGIN_INTERFACE_MAP(MessageControl) INTERFACE_ENTRY(PluginHost::IPlugin) INTERFACE_ENTRY(PluginHost::IDispatcher) INTERFACE_ENTRY(PluginHost::IPluginExtended) INTERFACE_ENTRY(PluginHost::IWebSocket) + INTERFACE_ENTRY(Exchange::IMessageControl) END_INTERFACE_MAP public: @@ -227,8 +315,8 @@ namespace Plugin { Core::ProxyType Inbound(const uint32_t ID, const Core::ProxyType& element) override; private: - void Announce(Publishers::IPublish* output) { - + void Announce(Publishers::IPublish* output) + { _outputLock.Lock(); ASSERT(std::find(_outputDirector.begin(), _outputDirector.end(), output) == _outputDirector.end()); @@ -237,50 +325,145 @@ namespace Plugin { _outputLock.Unlock(); } - void Message(const Core::Messaging::Metadata::type type, - const string & module, const string& category, const string & fileName, - const uint16_t lineNumber, const string & className, - const uint64_t timestamp, const string & message) { + void Message(const Core::Messaging::MessageInfo& metadata, const string& message) + { // Time to start sending it to all interested parties... _outputLock.Lock(); for (auto& entry : _outputDirector) { - entry->Message(type, module, category, fileName, lineNumber, className, timestamp, message); + entry->Message(metadata, message); } - _webSocketExporter.Message(type, module, category, fileName, lineNumber, className, timestamp, message); + _webSocketExporter.Message(metadata, message); _outputLock.Unlock(); } - void Attach(const uint32_t id) { + + public: + uint32_t Callback(Plugin::MessageControl::ICollect::ICallback* callback) + { + _adminLock.Lock(); + + ASSERT((_callback != nullptr) ^ (callback != nullptr)); + + if (_callback != nullptr) { + _worker.Block(); + _client.SkipWaiting(); + _adminLock.Unlock(); + _worker.Wait(Core::Thread::BLOCKED, Core::infinite); + _adminLock.Lock(); + } + + _callback = callback; + + if (_callback != nullptr) { + _worker.Run(); + } + + _adminLock.Unlock(); + + return (Core::ERROR_NONE); + } + + void Attach(const uint32_t id) + { _adminLock.Lock(); - _collect->Attach(id); + + _client.AddInstance(id); + Cleanup(); + _adminLock.Unlock(); } - void Detach(const uint32_t id) { + + void Detach(const uint32_t id) + { _adminLock.Lock(); - _collect->Detach(id); + + _client.RemoveInstance(id); + _cleaning.emplace_back(id); + Cleanup(); + _adminLock.Unlock(); + } + + public: + void Cleanup() + { + // Also have a list through the cleanup we should do, just to make sure + Cleanups::iterator index = _cleaning.begin(); + + while (index != _cleaning.end()) { + bool destructed = true; + string filter (_dispatcherIdentifier + '.' + Core::NumberType(*index).Text() + _T(".*")); + Core::Directory directory (_dispatcherBasePath.c_str(), filter.c_str()); + + while ((destructed == true) && (directory.Next() == true)) { + Core::File file (directory.Current()); + destructed = destructed && (Core::File(directory.Current()).Destroy()); + } - if (id == _connectionId) { - ASSERT(_service != nullptr); - Core::IWorkerPool::Instance().Submit(PluginHost::IShell::Job::Create(_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE)); + if (destructed == true) { + index = _cleaning.erase(index); + } + else { + index++; + } } } + uint32_t Enable(const messagetype type, const string& category, const string& module, const bool enabled) override + { + _client.Enable({static_cast(type), category, module}, enabled); + + return (Core::ERROR_NONE); + } + + uint32_t Controls(Exchange::IMessageControl::IControlIterator*& controls) const override + { + std::list list; + Messaging::MessageUnit::Iterator index; + _client.Controls(index); + + while (index.Next() == true) { + list.push_back( { static_cast(index.Type()), index.Category(), index.Module(), index.Enabled() } ); + } + + using Implementation = RPC::IteratorType; + controls = Core::Service::Create(list); + + return (Core::ERROR_NONE); + } + + private: + void Dispatch() + { + _client.WaitForUpdates(Core::infinite); + + _client.PopMessagesAndCall([this](const Core::ProxyType& metadata, const Core::ProxyType& message) { + // Turn data into piecies to trasfer over the wire + Message(*metadata, message->Data()); + }); + } + private: Core::CriticalSection _adminLock; Core::CriticalSection _outputLock; Config _config; OutputList _outputDirector; Publishers::WebSocketOutput _webSocketExporter; - Exchange::IMessageControl* _control; - Exchange::IMessageControl::ICollect* _collect; + MessageControl::ICollect::ICallback* _callback; Core::Sink _observer; - uint32_t _connectionId; PluginHost::IShell* _service; + const string _dispatcherIdentifier; + const string _dispatcherBasePath; + Messaging::MessageClient _client; + WorkerThread _worker; + Messaging::TraceFactoryType _tracingFactory; + Messaging::TraceFactoryType _loggingFactory; + Messaging::TraceFactoryType _warningReportingFactory; + Cleanups _cleaning; }; } // namespace Plugin -} // namespace WPEFramework +} diff --git a/MessageControl/MessageControl.vcxproj b/MessageControl/MessageControl.vcxproj index df9fc1ab6c..78f5ed0375 100644 --- a/MessageControl/MessageControl.vcxproj +++ b/MessageControl/MessageControl.vcxproj @@ -176,7 +176,6 @@ - diff --git a/MessageControl/MessageControl.vcxproj.filters b/MessageControl/MessageControl.vcxproj.filters index bd6cea52d3..75e3e0df66 100644 --- a/MessageControl/MessageControl.vcxproj.filters +++ b/MessageControl/MessageControl.vcxproj.filters @@ -7,9 +7,6 @@ Source Files - - Source Files - Source Files diff --git a/MessageControl/MessageOutput.cpp b/MessageControl/MessageOutput.cpp index 75611d291f..e7da39b49d 100644 --- a/MessageControl/MessageOutput.cpp +++ b/MessageControl/MessageOutput.cpp @@ -20,102 +20,109 @@ #include "MessageOutput.h" namespace WPEFramework { + namespace Publishers { - string Text::Convert(const Core::Messaging::Metadata::type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) /* override */ + string Text::Convert(const Core::Messaging::MessageInfo& metadata, const string& text) /* override */ { - string output; - - const Core::Time now(timeStamp); - - if (_abbreviated == true) { - const string time(now.ToTimeOnly(true)); - output = Core::Format("[%s]:[%s]:[%s]: %s\n", - time.c_str(), - module.c_str(), - category.c_str(), - text.c_str()); - } else { - const string time(now.ToRFC1123(true)); - output = Core::Format("[%s]:[%s:%u]:[%s]:[%s]: %s\n", - time.c_str(), - Core::FileNameOnly(fileName.c_str()), - lineNumber, - className.c_str(), - category.c_str(), - text.c_str()); - } + ASSERT(metadata.Type() != Core::Messaging::Metadata::type::INVALID); + + string output = metadata.ToString(_abbreviated).c_str() + + Core::Format("%s\n", text.c_str()); return (output); } - void ConsoleOutput::Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) /* override */ + void ConsoleOutput::Message(const Core::Messaging::MessageInfo& metadata, const string& text) /* override */ { - std::cout << _convertor.Convert(type, category,module,fileName, lineNumber, className, timeStamp, text); + std::cout << _convertor.Convert(metadata, text); } - void SyslogOutput::Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) /* override */ + void SyslogOutput::Message(const Core::Messaging::MessageInfo& metadata, const string& text) /* override */ { #ifndef __WINDOWS__ - syslog(LOG_NOTICE, _T("%s"), _convertor.Convert(type, module, category, fileName, lineNumber, className, timeStamp, text).c_str()); + syslog(LOG_NOTICE, _T("%s"), _convertor.Convert(metadata, text).c_str()); #else - printf(_T("%s"), _convertor.Convert(type, module, category, fileName, lineNumber, className, timeStamp, text).c_str()); + printf(_T("%s"), _convertor.Convert(metadata, text).c_str()); #endif } - void FileOutput::Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) /* override */ + void FileOutput::Message(const Core::Messaging::MessageInfo& metadata, const string& text) /* override */ { if (_file.IsOpen()) { - string line = _convertor.Convert(type, module, category, fileName, lineNumber, className, timeStamp, text); + const string line = _convertor.Convert(metadata, text); _file.Write(reinterpret_cast(line.c_str()), static_cast(line.length())); } } - void JSON::Convert(const Core::Messaging::Metadata::type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t, const string& text, Data& data) + void JSON::Convert(const Core::Messaging::MessageInfo& metadata, const string& text, Data& data) { ExtraOutputOptions options = _outputOptions; if ((AsNumber(options) & AsNumber(ExtraOutputOptions::PAUSED)) == 0) { - if ((AsNumber(options) & AsNumber(ExtraOutputOptions::INCLUDINGDATE)) != 0) { - data.Time = Core::Time::Now().ToRFC1123(true); - } else { - data.Time = Core::Time::Now().ToTimeOnly(true); + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::CATEGORY)) != 0) { + data.Category = metadata.Category(); } - if ((AsNumber(options) & AsNumber(ExtraOutputOptions::FILENAME)) != 0) { - data.FileName = fileName; + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::MODULE)) != 0) { + data.Module = metadata.Module(); } - if ((AsNumber(options) & AsNumber(ExtraOutputOptions::LINENUMBER)) != 0) { - data.LineNumber = lineNumber; + if (metadata.Type() == Core::Messaging::Metadata::type::TRACING) { + ASSERT(dynamic_cast(&metadata) != nullptr); + const Core::Messaging::IStore::Tracing& trace = static_cast(metadata); + const Core::Time now(trace.TimeStamp()); + + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::INCLUDINGDATE)) != 0) { + data.Time = now.ToRFC1123(true); + } + else { + data.Time = now.ToTimeOnly(true); + } + + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::FILENAME)) != 0) { + data.FileName = trace.FileName(); + } + + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::LINENUMBER)) != 0) { + data.LineNumber = trace.LineNumber(); + } + + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::CLASSNAME)) != 0) { + data.ClassName = trace.ClassName(); + } } - - if( (AsNumber(options) & AsNumber(ExtraOutputOptions::CLASSNAME) ) != 0 ) { - data.ClassName = className; + else if (metadata.Type() == Core::Messaging::Metadata::type::LOGGING) { + ASSERT(dynamic_cast(&metadata) != nullptr); + const Core::Messaging::IStore::Logging& log = static_cast(metadata); + const Core::Time now(log.TimeStamp()); + + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::INCLUDINGDATE)) != 0) { + data.Time = now.ToRFC1123(true); + } + else { + data.Time = now.ToTimeOnly(true); + } } - - if ((AsNumber(options) & AsNumber(ExtraOutputOptions::MODULE)) != 0) { - data.Module = module; + else if (metadata.Type() == Core::Messaging::Metadata::type::REPORTING) { + ASSERT(dynamic_cast(&metadata) != nullptr); + const Core::Messaging::IStore::WarningReporting& report = static_cast(metadata); + const Core::Time now(report.TimeStamp()); + + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::INCLUDINGDATE)) != 0) { + data.Time = now.ToRFC1123(true); + } + else { + data.Time = now.ToTimeOnly(true); + } + + if ((AsNumber(options) & AsNumber(ExtraOutputOptions::CALLSIGN)) != 0) { + data.Callsign = report.Callsign(); + } } - - if ((AsNumber(options) & AsNumber(ExtraOutputOptions::CATEGORY)) != 0) { - data.Category = category; + else { + ASSERT(metadata.Type() != Core::Messaging::Metadata::type::INVALID); } data.Message = text; @@ -128,8 +135,7 @@ namespace Publishers { , _loaded(0) { } - UDPOutput::Channel::~Channel() - { + UDPOutput::Channel::~Channel() { Close(Core::infinite); } @@ -142,24 +148,27 @@ namespace Publishers { _loaded = 0; _adminLock.Unlock(); + return (actualByteCount); } //unused - uint16_t UDPOutput::Channel::ReceiveData(uint8_t*, const uint16_t) - { + uint16_t UDPOutput::Channel::ReceiveData(uint8_t*, const uint16_t) { return 0; } + void UDPOutput::Channel::StateChange() { } - void UDPOutput::Channel::Output(const Core::Messaging::IStore::Information& info, const Core::Messaging::IEvent* message) + void UDPOutput::Channel::Output(const Core::Messaging::Metadata& metadata, const Core::Messaging::IEvent* message) { _adminLock.Lock(); uint16_t length = 0; - length += info.Serialize(_sendBuffer + length, sizeof(_sendBuffer) - length); + ASSERT(metadata.Type() != Core::Messaging::Metadata::INVALID); + + length += metadata.Serialize(_sendBuffer + length, sizeof(_sendBuffer) - length); length += message->Serialize(_sendBuffer + length, sizeof(_sendBuffer) - length); _loaded = length; @@ -169,21 +178,16 @@ namespace Publishers { } UDPOutput::UDPOutput(const Core::NodeId& nodeId) - : _output(nodeId) - { + : _output(nodeId) { _output.Open(0); } - void UDPOutput::Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) /* override */ + void UDPOutput::Message(const Core::Messaging::MessageInfo& metadata, const string& text) /* override */ { //yikes, recreating stuff from received pieces Messaging::TextMessage textMessage(text); - Core::Messaging::IStore::Information info(Core::Messaging::Metadata(type, category, module), fileName, lineNumber, className, timeStamp); - - _output.Output(info, &textMessage); + _output.Output(metadata, &textMessage); } -} + +} // namespace Publishers } diff --git a/MessageControl/MessageOutput.h b/MessageControl/MessageOutput.h index 0154155b71..de9def246b 100644 --- a/MessageControl/MessageOutput.h +++ b/MessageControl/MessageOutput.h @@ -27,10 +27,7 @@ namespace Publishers { struct IPublish { virtual ~IPublish() = default; - virtual void Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, - const string& fileName, const uint16_t lineNumber, - const string& className, const uint64_t timeStamp, const string& text) = 0; + virtual void Message(const Core::Messaging::MessageInfo& metadata, const string& text) = 0; }; class Text { @@ -39,19 +36,17 @@ namespace Publishers { Text(const Text&) = delete; Text& operator=(const Text&) = delete; - explicit Text(const bool abbreviated) - : _abbreviated(abbreviated) { + explicit Text(const Core::Messaging::MessageInfo::abbreviate abbreviated) + : _abbreviated(abbreviated) + { } ~Text() = default; public: - string Convert (const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text); + string Convert (const Core::Messaging::MessageInfo& metadata, const string& text); private: - bool _abbreviated; + Core::Messaging::MessageInfo::abbreviate _abbreviated; }; class ConsoleOutput : public IPublish { @@ -60,16 +55,14 @@ namespace Publishers { ConsoleOutput(const ConsoleOutput&) = delete; ConsoleOutput& operator=(const ConsoleOutput&) = delete; - explicit ConsoleOutput(const bool abbreviate) - : _convertor(abbreviate) { + explicit ConsoleOutput(const Core::Messaging::MessageInfo::abbreviate abbreviate) + : _convertor(abbreviate) + { } ~ConsoleOutput() override = default; public: - void Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) override; + void Message(const Core::Messaging::MessageInfo& metadata, const string& text); private: Text _convertor; @@ -81,16 +74,14 @@ namespace Publishers { SyslogOutput(const SyslogOutput&) = delete; SyslogOutput& operator=(const SyslogOutput&) = delete; - explicit SyslogOutput(const bool abbreviate) - : _convertor(abbreviate) { + explicit SyslogOutput(const Core::Messaging::MessageInfo::abbreviate abbreviate) + : _convertor(abbreviate) + { } ~SyslogOutput() override = default; public: - void Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) override; + void Message(const Core::Messaging::MessageInfo& metadata, const string& text); private: Text _convertor; @@ -102,26 +93,25 @@ namespace Publishers { FileOutput(const FileOutput&) = delete; FileOutput& operator=(const FileOutput&) = delete; - explicit FileOutput(const bool abbreviate, const string& filepath) + explicit FileOutput(const Core::Messaging::MessageInfo::abbreviate abbreviate, const string& filepath) : _convertor(abbreviate) - , _file(filepath) { + , _file(filepath) + { _file.Create(); if (!_file.IsOpen()) { TRACE(Trace::Error, (_T("Could not open file <%s>. Outputting warnings to file unavailable."), filepath)); } } - ~FileOutput() override { + ~FileOutput() override + { if (_file.IsOpen()) { _file.Close(); } } public: - void Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) override; + void Message(const Core::Messaging::MessageInfo& metadata, const string& text); private: Text _convertor; @@ -137,9 +127,10 @@ namespace Publishers { CLASSNAME = 0x04, MODULE = 0x08, CATEGORY = 0x10, - INCLUDINGDATE = 0x20, - ALL = 0x3F, - PAUSED = 0x40 + CALLSIGN = 0x20, + INCLUDINGDATE = 0x40, + ALL = 0x7F, + PAUSED = 0x80 }; public: @@ -156,6 +147,7 @@ namespace Publishers { , ClassName() , Category() , Module() + , Callsign() , Message() { Add(_T("time"), &Time); @@ -164,6 +156,7 @@ namespace Publishers { Add(_T("classname"), &ClassName); Add(_T("category"), &Category); Add(_T("module"), &Module); + Add(_T("callsign"), &Callsign); Add(_T("message"), &Message); } ~Data() override = default; @@ -175,6 +168,7 @@ namespace Publishers { Core::JSON::String ClassName; Core::JSON::String Category; Core::JSON::String Module; + Core::JSON::String Callsign; Core::JSON::String Message; }; @@ -183,16 +177,18 @@ namespace Publishers { JSON& operator=(const JSON&) = delete; JSON() - : _outputOptions(ExtraOutputOptions::ALL) { + : _outputOptions(ExtraOutputOptions::ALL) + { } - ~JSON() = default; public: bool FileName() const { return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::FILENAME)) != 0); } - void FileName(const bool enabled) { + + void FileName(const bool enabled) + { if (enabled == true) { _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::FILENAME)); } @@ -200,10 +196,13 @@ namespace Publishers { _outputOptions = static_cast(AsNumber(_outputOptions) & ~AsNumber(ExtraOutputOptions::FILENAME)); } } + bool LineNumber() const { return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::LINENUMBER)) != 0); } - void LineNumber(const bool enabled) { + + void LineNumber(const bool enabled) + { if (enabled == true) { _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::LINENUMBER)); } @@ -211,10 +210,13 @@ namespace Publishers { _outputOptions = static_cast(AsNumber(_outputOptions) & ~AsNumber(ExtraOutputOptions::LINENUMBER)); } } + bool ClassName() const { return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::CLASSNAME)) != 0); } - void ClassName(const bool enabled) { + + void ClassName(const bool enabled) + { if (enabled == true) { _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::CLASSNAME)); } @@ -222,10 +224,13 @@ namespace Publishers { _outputOptions = static_cast(AsNumber(_outputOptions) & ~AsNumber(ExtraOutputOptions::CLASSNAME)); } } + bool Module() const { return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::MODULE)) != 0); } - void Module(const bool enabled) { + + void Module(const bool enabled) + { if (enabled == true) { _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::MODULE)); } @@ -233,10 +238,13 @@ namespace Publishers { _outputOptions = static_cast(AsNumber(_outputOptions) & ~AsNumber(ExtraOutputOptions::MODULE)); } } + bool Category() const { return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::CATEGORY)) != 0); } - void Category(const bool enabled) { + + void Category(const bool enabled) + { if (enabled == true) { _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::CATEGORY)); } @@ -244,10 +252,27 @@ namespace Publishers { _outputOptions = static_cast(AsNumber(_outputOptions) & ~AsNumber(ExtraOutputOptions::CATEGORY)); } } + + bool Callsign() const { + return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::CALLSIGN)) != 0); + } + + void Callsign(const bool enabled) + { + if (enabled == true) { + _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::CALLSIGN)); + } + else { + _outputOptions = static_cast(AsNumber(_outputOptions) & ~AsNumber(ExtraOutputOptions::CALLSIGN)); + } + } + bool Date() const { return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::INCLUDINGDATE)) != 0); } - void Date(const bool enabled) { + + void Date(const bool enabled) + { if (enabled == true) { _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::INCLUDINGDATE)); } @@ -255,10 +280,13 @@ namespace Publishers { _outputOptions = static_cast(AsNumber(_outputOptions) & ~AsNumber(ExtraOutputOptions::INCLUDINGDATE)); } } + bool Paused() const { return ((AsNumber(_outputOptions) & AsNumber(ExtraOutputOptions::PAUSED)) != 0); } - void Paused(const bool enabled) { + + void Paused(const bool enabled) + { if (enabled == true) { _outputOptions = static_cast(AsNumber(_outputOptions) | AsNumber(ExtraOutputOptions::PAUSED)); } @@ -267,16 +295,12 @@ namespace Publishers { } } - void Convert(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text, Data& info); + void Convert(const Core::Messaging::MessageInfo& metadata, const string& text, Data& info); private: template - static inline auto AsNumber(E t) -> typename std::underlying_type::type - { - return static_cast::type>(t); + static inline auto AsNumber(E t) -> typename std::underlying_type::type { + return (static_cast::type>(t)); } private: @@ -294,7 +318,7 @@ namespace Publishers { explicit Channel(const Core::NodeId& nodeId); ~Channel() override; - void Output(const Core::Messaging::IStore::Information& info, const Core::Messaging::IEvent* message); + void Output(const Core::Messaging::Metadata& metadata, const Core::Messaging::IEvent* message); private: uint16_t SendData(uint8_t* dataFrame, const uint16_t maxSendSize) override; @@ -315,10 +339,7 @@ namespace Publishers { explicit UDPOutput(const Core::NodeId& nodeId); ~UDPOutput() = default; - void Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) override; + void Message(const Core::Messaging::MessageInfo& metadata, const string& text); private: Channel _output; @@ -337,6 +358,7 @@ namespace Publishers { , LineNumber() , Category() , Module() + , Callsign() , IncludingDate() , Paused() { @@ -345,10 +367,10 @@ namespace Publishers { Add(_T("classname"), &ClassName); Add(_T("category"), &Category); Add(_T("module"), &Module); + Add(_T("callsign"), &Callsign); Add(_T("includingdate"), &IncludingDate); Add(_T("paused"), &Paused); } - ~ExportCommand() override = default; public: @@ -357,6 +379,7 @@ namespace Publishers { Core::JSON::Boolean ClassName; Core::JSON::Boolean Category; Core::JSON::Boolean Module; + Core::JSON::Boolean Callsign; Core::JSON::Boolean IncludingDate; Core::JSON::Boolean Paused; }; @@ -382,21 +405,29 @@ namespace Publishers { ~WebSocketOutput() override = default; public: - void Initialize(PluginHost::IShell* service, const uint32_t maxConnections = DefaultMaxConnections) { + void Initialize(PluginHost::IShell* service, const uint32_t maxConnections = DefaultMaxConnections) + { _lock.Lock(); + _server = service; _server->AddRef(); _maxExportConnections = maxConnections; + _lock.Unlock(); } - void Deinitialize() { + + void Deinitialize() + { _lock.Lock(); + _server->Release(); _server = nullptr; _channels.clear(); _maxExportConnections = 0; + _lock.Unlock(); } + bool Attach(const uint32_t id) { bool accepted = false; @@ -415,10 +446,11 @@ namespace Publishers { _lock.Unlock(); - return accepted; + return (accepted); } - bool Detach(const uint32_t id) { + bool Detach(const uint32_t id) + { bool deactivated = false; _lock.Lock(); @@ -432,14 +464,15 @@ namespace Publishers { _lock.Unlock(); - return deactivated; + return (deactivated); } uint32_t MaxConnections() const { return (_maxExportConnections); } - Core::ProxyType Received(const uint32_t id, const Core::ProxyType& element) { + Core::ProxyType Received(const uint32_t id, const Core::ProxyType& element) + { Core::ProxyType info = Core::ProxyType(element); if (info.IsValid() == false) { @@ -466,6 +499,9 @@ namespace Publishers { if (info->Module.IsSet() == true) { index->second.Module(info->Module == true); } + if (info->Callsign.IsSet() == true) { + index->second.Callsign(info->Callsign == true); + } if (info->IncludingDate.IsSet() == true) { index->second.Date(info->IncludingDate == true); } @@ -479,6 +515,7 @@ namespace Publishers { info->ClassName = index->second.ClassName(); info->Category = index->second.Category(); info->Module = index->second.Module(); + info->Callsign = index->second.Callsign(); info->IncludingDate = index->second.Date(); info->Paused = index->second.Paused(); } @@ -489,26 +526,21 @@ namespace Publishers { return (element); } - void Message(const Core::Messaging::Metadata::type type, - const string& module, const string& category, const string& fileName, - const uint16_t lineNumber, const string& className, - const uint64_t timeStamp, const string& text) override { - + void Message(const Core::Messaging::MessageInfo& metadata, const string& text) override + { std::list>> cachedList; PluginHost::IShell* server = nullptr; _lock.Lock(); if (_server != nullptr) { - for (auto& item : _channels) { if (item.second.Paused() == false) { Core::ProxyType data = _jsonExportDataFactory.Element(); - item.second.Convert(type, category, module, fileName, lineNumber, className, timeStamp, text, *data); + item.second.Convert(metadata, text, *data); cachedList.emplace_back(item.first, Core::ProxyType(data)); } } - if (cachedList.empty() == false) { server = _server; server->AddRef(); @@ -539,5 +571,5 @@ namespace Publishers { Core::ProxyPoolType _jsonExportCommandFactory; }; -} +} // namespace Publishers } diff --git a/MessageControl/Module.h b/MessageControl/Module.h index 920e56d58e..0623a8c20a 100644 --- a/MessageControl/Module.h +++ b/MessageControl/Module.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/Messenger/Messenger.cpp b/Messenger/Messenger.cpp index 24711ad653..08cbb0c8bc 100644 --- a/Messenger/Messenger.cpp +++ b/Messenger/Messenger.cpp @@ -70,64 +70,70 @@ namespace Plugin { message = _T("RoomMaintainer couldnt be instantiated"); } else { + RegisterAll(); _roomAdmin->Register(this); - } - if(message.length() != 0) { +#ifndef USE_THUNDER_R4 + if (message.length() != 0) { Deinitialize(service); } +#endif + return message; } /* virtual */ void Messenger::Deinitialize(PluginHost::IShell* service) { - ASSERT(service == _service); + if (_service != nullptr) { + ASSERT(service == _service); #ifdef USE_THUNDER_R4 - _service->Unregister(&_notification); + _service->Unregister(&_notification); #endif - if(_roomAdmin != nullptr) { - // Exit all the rooms (if any) that were joined by this client - for (auto& room : _roomIds) { - room.second->Release(); - } + if (_roomAdmin != nullptr) { + // Exit all the rooms (if any) that were joined by this client + for (auto& room : _roomIds) { + room.second->Release(); + } - _roomIds.clear(); - _roomAdmin->Unregister(this); - _rooms.clear(); + _roomIds.clear(); + _roomAdmin->Unregister(this); + _rooms.clear(); + UnregisterAll(); #ifdef USE_THUNDER_R4 - RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); #endif - VARIABLE_IS_NOT_USED uint32_t result = _roomAdmin->Release(); - _roomAdmin = nullptr; + VARIABLE_IS_NOT_USED uint32_t result = _roomAdmin->Release(); + _roomAdmin = nullptr; #ifdef USE_THUNDER_R4 - // It should have been the last reference we are releasing, - // so it should end up in a DESCRUCTION_SUCCEEDED, if not we - // are leaking... - ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); - - // If this was running in a (container) proccess... - if (connection != nullptr) { - - // Lets trigger the cleanup sequence for - // out-of-process code. Which will guard - // that unwilling processes, get shot if - // not stopped friendly :~) - connection->Terminate(); - connection->Release(); - } + // It should have been the last reference we are releasing, + // so it should end up in a DESCRUCTION_SUCCEEDED, if not we + // are leaking... + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + + // If this was running in a (container) proccess... + if (connection != nullptr) { + + // Lets trigger the cleanup sequence for + // out-of-process code. Which will guard + // that unwilling processes, get shot if + // not stopped friendly :~) + connection->Terminate(); + connection->Release(); + } #endif - } - _service->Release(); - _service = nullptr; + } + _service->Release(); + _service = nullptr; #ifdef USE_THUNDER_R4 - _connectionId = 0; + _connectionId = 0; #endif - _roomACL.clear(); + _roomACL.clear(); + } } // Web request handlers diff --git a/Messenger/Messenger.h b/Messenger/Messenger.h index 5f033ae1fa..0644e8cf34 100644 --- a/Messenger/Messenger.h +++ b/Messenger/Messenger.h @@ -49,10 +49,10 @@ namespace Plugin { ~Notification() override = default; public: - virtual void Activated(RPC::IRemoteConnection*) + void Activated(RPC::IRemoteConnection*) override { } - virtual void Deactivated(RPC::IRemoteConnection* connection) + void Deactivated(RPC::IRemoteConnection* connection) override { _parent.Deactivated(connection); } @@ -82,13 +82,9 @@ namespace Plugin { , _notification(this) #endif { - RegisterAll(); } - ~Messenger() - { - UnregisterAll(); - } + ~Messenger() override = default; // IPlugin methods const string Initialize(PluginHost::IShell* service) override; diff --git a/Monitor/Monitor.cpp b/Monitor/Monitor.cpp index c042010ba6..ad8b32575f 100644 --- a/Monitor/Monitor.cpp +++ b/Monitor/Monitor.cpp @@ -57,10 +57,12 @@ namespace Plugin { Core::JSON::ArrayType::Iterator index(_config.Observables.Elements()); // Create a list of plugins to monitor.. - _monitor->Open(service, index); + _monitor.Open(service, index); // During the registartion, all Plugins, currently active are reported to the sink. - service->Register(_monitor); + service->Register(&_monitor); + + RegisterAll(); // On succes return a name as a Callsign to be used in the URL, after the "service"prefix return (_T("")); @@ -68,10 +70,11 @@ namespace Plugin { /* virtual */ void Monitor::Deinitialize(PluginHost::IShell* service) { + UnregisterAll(); - _monitor->Close(); + service->Unregister(&_monitor); - service->Unregister(_monitor); + _monitor.Close(); } /* virtual */ string Monitor::Information() const @@ -106,10 +109,10 @@ namespace Plugin { if (request.Verb == Web::Request::HTTP_GET) { // Let's list them all.... if (index.Next() == false) { - if (_monitor->Length() > 0) { + if (_monitor.Length() > 0) { Core::ProxyType>> response(jsonBodyDataFactory.Element()); - _monitor->Snapshot(*response); + _monitor.Snapshot(*response); #ifndef USE_THUNDER_R4 result->Body(Core::proxy_cast(response)); #else @@ -118,12 +121,13 @@ namespace Plugin { } } else { MetaData memoryInfo; + bool operational = false; // Seems we only want 1 name - if (_monitor->Snapshot(index.Current().Text(), memoryInfo) == true) { + if (_monitor.Snapshot(index.Current().Text(), memoryInfo, operational) == true) { Core::ProxyType> response(jsonMemoryBodyDataFactory.Element()); - *response = memoryInfo; + *response = Monitor::Data::MetaData(memoryInfo, operational); #ifndef USE_THUNDER_R4 result->Body(Core::proxy_cast(response)); #else @@ -135,12 +139,13 @@ namespace Plugin { result->ContentType = Web::MIME_JSON; } else if ((request.Verb == Web::Request::HTTP_PUT) && (index.Next() == true)) { MetaData memoryInfo; + bool operational = false; // Seems we only want 1 name - if (_monitor->Reset(index.Current().Text(), memoryInfo) == true) { + if (_monitor.Reset(index.Current().Text(), memoryInfo, operational) == true) { Core::ProxyType> response(jsonMemoryBodyDataFactory.Element()); - *response = memoryInfo; + *response = Monitor::Data::MetaData(memoryInfo, operational); #ifndef USE_THUNDER_R4 result->Body(Core::proxy_cast(response)); #else @@ -161,7 +166,7 @@ namespace Plugin { restartLimit = body->Restart.Limit; } TRACE(Trace::Information, (_T("Sets Restart Limits:[LIMIT:%d, WINDOW:%d]"), restartLimit, restartWindow)); - _monitor->Update(observable, restartWindow, restartLimit); + _monitor.Update(observable, restartWindow, restartLimit); } else { result->ErrorCode = Web::STATUS_BAD_REQUEST; result->Message = _T(" could not handle your request."); diff --git a/Monitor/Monitor.h b/Monitor/Monitor.h index 2912f070b2..1d2ba53b86 100644 --- a/Monitor/Monitor.h +++ b/Monitor/Monitor.h @@ -70,7 +70,6 @@ namespace Plugin { , _allocated() , _shared() , _process() - , _operational(false) { } MetaData(const MetaData& copy) @@ -78,7 +77,6 @@ namespace Plugin { , _allocated(copy._allocated) , _shared(copy._shared) , _process(copy._process) - , _operational(copy._operational) { } ~MetaData() @@ -91,12 +89,22 @@ namespace Plugin { _allocated = rhs._allocated; _shared = rhs._shared; _process = rhs._process; - _operational = rhs._operational; return (*this); } public: + bool HasMeasurements() const { + return ((_resident.Measurements() != 0) || (_allocated.Measurements() != 0) || (_shared.Measurements() != 0) || (_process.Measurements() != 0)); + } + + void AddMeasurements(const uint64_t resident, const uint64_t allocated, const uint64_t shared, const uint64_t process) { + _resident.Set(resident); + _allocated.Set(allocated); + _shared.Set(shared); + _process.Set(process); + } + void Measure(Exchange::IMemory* memInterface) { _resident.Set(memInterface->Resident()); @@ -104,10 +112,6 @@ namespace Plugin { _shared.Set(memInterface->Shared()); _process.Set(memInterface->Processes()); } - void Operational(const bool operational) - { - _operational = operational; - } void Reset() { _resident.Reset(); @@ -133,17 +137,11 @@ namespace Plugin { { return (_process); } - inline bool Operational() const - { - return (_operational); - } - private: Core::MeasurementType _resident; Core::MeasurementType _allocated; Core::MeasurementType _shared; Core::MeasurementType _process; - bool _operational; }; class Data : public Core::JSON::Container { @@ -259,7 +257,7 @@ namespace Plugin { Add(_T("operational"), &Operational); Add(_T("count"), &Count); } - MetaData(const Monitor::MetaData& input) + MetaData(const Monitor::MetaData& input, const bool operational) : Core::JSON::Container() { Add(_T("allocated"), &Allocated); @@ -273,7 +271,7 @@ namespace Plugin { Resident = input.Resident(); Shared = input.Shared(); Process = input.Process(); - Operational = input.Operational(); + Operational = operational; Count = input.Allocated().Measurements(); } MetaData(const MetaData& copy) @@ -307,17 +305,6 @@ namespace Plugin { return (*this); } - MetaData& operator=(const Monitor::MetaData& RHS) - { - Allocated = RHS.Allocated(); - Resident = RHS.Resident(); - Shared = RHS.Shared(); - Process = RHS.Process(); - Operational = RHS.Operational(); - Count = RHS.Allocated().Measurements(); - - return (*this); - } public: Measurement Allocated; @@ -344,10 +331,10 @@ namespace Plugin { Add(_T("observable"), &Observable); Add(_T("restart"), &Restart); } - Data(const string& name, const Monitor::MetaData& info) + Data(const string& name, const Monitor::MetaData& info, const bool operational) : Core::JSON::Container() , Name() - , Measurement() + , Measurement(info, operational) , Observable() , Restart() { @@ -357,7 +344,6 @@ namespace Plugin { Add(_T("restart"), &Restart); Name = name; - Measurement = info; } Data(const Data& copy) : Core::JSON::Container() @@ -486,33 +472,14 @@ namespace Plugin { , _restartCount(0) , _restartLimit(restartLimit) , _measurement() + , _operational(false) , _operationalEvaluate(actOnOperational) , _source(nullptr) + , _interval( ((operationalInterval != 0) || (_memoryInterval != 0)) ? gcd(_operationalInterval, _memoryInterval) : 0 ) , _active{ false } + , _adminLock() { ASSERT((_operationalInterval != 0) || (_memoryInterval != 0)); - _interval = gcd(_operationalInterval, _memoryInterval); - } - MonitorObject(const MonitorObject& copy) - : _operationalInterval(copy._operationalInterval) - , _memoryInterval(copy._memoryInterval) - , _memoryThreshold(copy._memoryThreshold) - , _operationalSlots(copy._operationalSlots) - , _memorySlots(copy._memorySlots) - , _nextSlot(copy._nextSlot) - , _restartWindow(copy._restartWindow) - , _restartWindowStart(copy._restartWindowStart) - , _restartCount(copy._restartCount) - , _restartLimit(copy._restartLimit) - , _measurement(copy._measurement) - , _operationalEvaluate(copy._operationalEvaluate) - , _source(copy._source) - , _interval(copy._interval) - , _active{ copy._active } - { - if (_source != nullptr) { - _source->AddRef(); - } } ~MonitorObject() { @@ -522,6 +489,11 @@ namespace Plugin { } } + MonitorObject(MonitorObject&) = delete; + MonitorObject& operator=(MonitorObject&) = delete; + MonitorObject(MonitorObject&&) = delete; + MonitorObject& operator=(MonitorObject&&) = delete; + public: inline bool RegisterRestart(PluginHost::IShell::reason why VARIABLE_IS_NOT_USED) { @@ -543,11 +515,11 @@ namespace Plugin { return result; } - inline uint8_t RestartLimit() + inline uint8_t RestartLimit() const { return _restartLimit; } - inline uint16_t RestartWindow() + inline uint16_t RestartWindow() const { return _restartWindow; } @@ -566,14 +538,14 @@ namespace Plugin { { return (_interval); } - inline const MetaData& Measurement() const + inline uint32_t Operational() const { - return (_measurement); + return (_operational); } - inline bool HasMeasurement() const + inline const MetaData& Measurement() const { - return (((_measurement.Allocated().Min() == Core::NumberType::Max()) && - (_measurement.Allocated().Max() == Core::NumberType::Min())) ? false : true); + Core::SafeSyncType guard(_adminLock); + return (_measurement); } inline uint64_t TimeSlot() const { @@ -581,6 +553,7 @@ namespace Plugin { } inline void Reset() { + Core::SafeSyncType guard(_adminLock); _measurement.Reset(); } inline void Retrigger(uint64_t currentSlot) @@ -591,6 +564,7 @@ namespace Plugin { } inline void Set(Exchange::IMemory* memory) { + _adminLock.Lock(); if (_source != nullptr) { _source->Release(); _source = nullptr; @@ -600,29 +574,51 @@ namespace Plugin { _source = memory; _source->AddRef(); } + _adminLock.Unlock(); - _measurement.Operational(_source != nullptr); + _operational = (memory != nullptr); } + + Core::ProxyType Source() const + { + Core::ProxyType source; + _adminLock.Lock(); + if(_source != nullptr) { + source = Core::ProxyType(*_source, *_source); + } + _adminLock.Unlock(); + return source; + } + inline uint32_t Evaluate() { + Core::ProxyType source = Source(); + uint32_t status(SUCCESFULL); - if (_source != nullptr) { + if (source.IsValid() == true) { _operationalSlots -= _interval; _memorySlots -= _interval; if ((_operationalInterval != 0) && (_operationalSlots == 0)) { - bool operational = _source->IsOperational(); - _measurement.Operational(operational); - if (operational == false) { + _operational = source->IsOperational(); + if (_operational == false) { status |= NOT_OPERATIONAL; TRACE(Trace::Error, (_T("Status not operational. %d"), __LINE__)); } _operationalSlots = _operationalInterval; } if ((_memoryInterval != 0) && (_memorySlots == 0)) { - _measurement.Measure(_source); - if ((_memoryThreshold != 0) && (_measurement.Resident().Last() > _memoryThreshold)) { + uint64_t resident = source->Resident(); + uint64_t allocated = source->Allocated(); + uint64_t shared = source->Shared(); + uint64_t process = source->Processes(); + + _adminLock.Lock(); + _measurement.AddMeasurements(resident, allocated, shared, process); + _adminLock.Unlock(); + + if ((_memoryThreshold != 0) && (resident > _memoryThreshold)) { status |= EXCEEDED_MEMORY; TRACE(Trace::Error, (_T("Status MetaData Exceeded. %d"), __LINE__)); } @@ -639,18 +635,20 @@ namespace Plugin { const uint32_t _operationalInterval; //!< Interval (s) to check the monitored processes const uint32_t _memoryInterval; //!< Interval (s) for a memory measurement. const uint64_t _memoryThreshold; //!< MetaData threshold in bytes for all processes. - uint32_t _operationalSlots; - uint32_t _memorySlots; - uint64_t _nextSlot; - uint16_t _restartWindow; - Core::Time _restartWindowStart; - uint32_t _restartCount; - uint8_t _restartLimit; + uint32_t _operationalSlots; // does not need protection, only touched in job evaluate + uint32_t _memorySlots; // does not need protection, only touched in job evaluate + std::atomic _nextSlot; // no ordering needed, atomic should suffice + std::atomic _restartWindow; // no ordering needed, atomic should suffice + Core::Time _restartWindowStart; // only used in job (indirectly), no protection needed + uint32_t _restartCount; // only used in job (indirectly), no protection needed + std::atomic _restartLimit; // no ordering needed, atomic should suffice MetaData _measurement; - bool _operationalEvaluate; + std::atomic _operational; // no ordering needed, atomic should suffice + const bool _operationalEvaluate; Exchange::IMemory* _source; - uint32_t _interval; //!< The greatest possible interval to check both memory and processes. - bool _active; + const uint32_t _interval; //!< The greatest possible interval to check both memory and processes. + std::atomic _active; + mutable Core::CriticalSection _adminLock; }; public: @@ -661,8 +659,7 @@ namespace Plugin { #pragma warning(disable : 4355) #endif MonitorObjects(Monitor* parent) - : _adminLock() - , _monitor() + : _monitor() , _job(*this) , _service(nullptr) , _parent(*parent) @@ -671,7 +668,7 @@ namespace Plugin { #ifdef __WINDOWS__ #pragma warning(default : 4355) #endif - virtual ~MonitorObjects() + ~MonitorObjects() override { ASSERT(_monitor.size() == 0); } @@ -686,16 +683,12 @@ namespace Plugin { const uint16_t restartWindow, const uint8_t restartLimit) { - _adminLock.Lock(); - - std::map::iterator index(_monitor.find(observable)); + MonitorObjectContainer::iterator index(_monitor.find(observable)); if (index != _monitor.end()) { index->second.UpdateRestartLimits( restartWindow, restartLimit); } - - _adminLock.Unlock(); } inline void Open(PluginHost::IShell* service, Core::JSON::ArrayType::Iterator& index) { @@ -706,8 +699,6 @@ namespace Plugin { _service = service; _service->AddRef(); - _adminLock.Lock(); - while (index.Next() == true) { Config::Entry& element(index.Current()); string callSign(element.Callsign.Value()); @@ -724,20 +715,21 @@ namespace Plugin { } SYSLOG(Logging::Startup, (_T("Monitoring: %s (%d,%d)."), callSign.c_str(), (interval / 1000000), (memory / 1000000))); if ((interval != 0) || (memory != 0)) { - _monitor.insert( - std::pair(callSign, MonitorObject( - element.Operational.Value() >= 0, - interval, - memory, - memoryThreshold, - baseTime, - restartWindow, - restartLimit))); + + _monitor.emplace(std::piecewise_construct, + std::forward_as_tuple(callSign), + std::forward_as_tuple( + element.Operational.Value() >= 0, + interval, + memory, + memoryThreshold, + baseTime, + restartWindow, + restartLimit) + ); } } - _adminLock.Unlock(); - _job.Submit(); } inline void Close() @@ -746,17 +738,65 @@ namespace Plugin { _job.Revoke(); - _adminLock.Lock(); _monitor.clear(); - _adminLock.Unlock(); _service->Release(); _service = nullptr; } + void Activated (const string& callsign, PluginHost::IShell* service) override + { + MonitorObjectContainer::iterator index(_monitor.find(callsign)); + + if (index != _monitor.end()) { + + index->second.Active(true); + + // Get the MetaData interface + Exchange::IMemory* memory = service->QueryInterface(); + + if (memory != nullptr) { + index->second.Set(memory); + memory->Release(); + } + + if (_job.Submit() == true) { + TRACE(Trace::Information, (_T("Starting to probe as active observee appeared."))); + } + } + } + void Deactivated (const string& callsign, PluginHost::IShell* service) override + { + + MonitorObjectContainer::iterator index(_monitor.find(callsign)); + + if (index != _monitor.end()) { + + index->second.Set(nullptr); + index->second.Active(false); + + PluginHost::IShell::reason reason = service->Reason(); + + if ((index->second.HasRestartAllowed() == true) && ((reason == PluginHost::IShell::MEMORY_EXCEEDED) || (reason == PluginHost::IShell::FAILURE))) { + if (index->second.RegisterRestart(reason) == false) { + uint8_t restartlimit = index->second.RestartLimit(); + uint16_t restartwindow = index->second.RestartWindow(); + TRACE(Trace::Fatal, (_T("Giving up restarting of %s: Failed more than %d times within %d seconds."), callsign.c_str(), restartlimit, restartwindow)); + const string message("{\"callsign\": \"" + callsign + "\", \"action\": \"Restart\", \"reason\":\"" + (std::to_string(restartlimit)).c_str() + " Attempts Failed within the restart window\"}"); + _service->Notify(message); + _parent.event_action(callsign, "StoppedRestaring", std::to_string(index->second.RestartLimit()) + " attempts failed within the restart window"); + } else { + const string message("{\"callsign\": \"" + callsign + "\", \"action\": \"Activate\", \"reason\": \"Automatic\" }"); + _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().Submit(PluginHost::IShell::Job::Create(service, PluginHost::IShell::ACTIVATED, PluginHost::IShell::AUTOMATIC)); + } + } + } + } virtual void StateChange(PluginHost::IShell* service) { - _adminLock.Lock(); - std::map::iterator index(_monitor.find(service->Callsign())); + MonitorObjectContainer::iterator index(_monitor.find(service->Callsign())); if (index != _monitor.end()) { @@ -817,7 +857,6 @@ namespace Plugin { } } - _adminLock.Unlock(); } #if (THUNDER_VERSION_MAJOR >= 4) @@ -827,115 +866,108 @@ namespace Plugin { StateChange(service); } - void Deactivation(const string& name, PluginHost::IShell* service) override - { - StateChange(service); - } -#endif - void Activated (const string& callsign, PluginHost::IShell* service) override - { - StateChange(service); - } - void Deactivated (const string& callsign, PluginHost::IShell* service) override - { + void Deactivation(const string& name, PluginHost::IShell* service) override + { StateChange(service); - } - void Unavailable(const string&, PluginHost::IShell*) override - { - } + } #endif - void Snapshot(Core::JSON::ArrayType& snapshot) + void Activated (const string& callsign, PluginHost::IShell* service) override { - _adminLock.Lock(); - - std::map::iterator element(_monitor.begin()); + StateChange(service); + } + void Deactivated (const string& callsign, PluginHost::IShell* service) override + { + StateChange(service); + } + void Unavailable(const string&, PluginHost::IShell*) override + { + } +#endif + void Snapshot(Core::JSON::ArrayType& snapshot) const + { + MonitorObjectContainer::const_iterator element(_monitor.cbegin()); // Go through the list of observations... - while (element != _monitor.end()) { - if (element->second.HasMeasurement() == true) { - snapshot.Add(Monitor::Data(element->first, element->second.Measurement())); + while (element != _monitor.cend()) { + MetaData data = element->second.Measurement(); + if (data.HasMeasurements() == true) { + snapshot.Add(Monitor::Data(element->first, data, element->second.Operational())); } element++; } - _adminLock.Unlock(); } - bool Snapshot(const string& name, Monitor::MetaData& result) + bool Snapshot(const string& name, Monitor::MetaData& result, bool& operational) const { bool found = false; - _adminLock.Lock(); - std::map::iterator index(_monitor.find(name)); + MonitorObjectContainer::const_iterator index(_monitor.find(name)); - if (index != _monitor.end()) { - if (index->second.HasMeasurement() == true) { - result = index->second.Measurement(); + if (index != _monitor.cend()) { + MetaData data = index->second.Measurement(); + if (data.HasMeasurements() == true) { + result = data; + operational = index->second.Operational(); found = true; } } - _adminLock.Unlock(); - return (found); } - void Snapshot(const string& callsign, Core::JSON::ArrayType* response) - { - _adminLock.Lock(); + void AddElementToResponse( Core::JSON::ArrayType& response, const string& callsign, const MonitorObject& object) const { + const MetaData& metaData = object.Measurement(); + JsonData::Monitor::InfoInfo info; + info.Observable = callsign; - auto AddElement = [this, &response](const string& callsign, MonitorObject& object) { - const MetaData& metaData = object.Measurement(); - JsonData::Monitor::InfoInfo info; - info.Observable = callsign; + if (object.HasRestartAllowed()) { + info.Restart.Limit = object.RestartLimit(); + info.Restart.Window = object.RestartWindow(); + } - if (object.HasRestartAllowed()) { - info.Restart.Limit = object.RestartLimit(); - info.Restart.Window = object.RestartWindow(); - } + if (metaData.HasMeasurements() == true) { + translate(metaData.Allocated(), &info.Measurements.Allocated); + translate(metaData.Resident(), &info.Measurements.Resident); + translate(metaData.Shared(), &info.Measurements.Shared); + translate(metaData.Process(), &info.Measurements.Process); + } + info.Measurements.Operational = object.Operational(); + info.Measurements.Count = metaData.Allocated().Measurements(); - if (object.HasMeasurement()) { - translate(metaData.Allocated(), &info.Measurements.Allocated); - translate(metaData.Resident(), &info.Measurements.Resident); - translate(metaData.Shared(), &info.Measurements.Shared); - translate(metaData.Process(), &info.Measurements.Process); - } - info.Measurements.Operational = metaData.Operational(); - info.Measurements.Count = metaData.Allocated().Measurements(); + response.Add(info); + }; - response->Add(info); - }; + void Snapshot(const string& callsign, Core::JSON::ArrayType* response) const + { + + ASSERT(response != nullptr); if (callsign.empty() == false) { auto element = _monitor.find(callsign); if (element != _monitor.end()) { - AddElement(element->first, element->second); + AddElementToResponse(*response, element->first, element->second); } } else { for (auto& element : _monitor) { - AddElement(element.first, element.second); + AddElementToResponse(*response, element.first, element.second); } } - - _adminLock.Unlock(); } - bool Reset(const string& name, Monitor::MetaData& result) + bool Reset(const string& name, Monitor::MetaData& result, bool& operational) { bool found = false; - _adminLock.Lock(); - - std::map::iterator index(_monitor.find(name)); + MonitorObjectContainer::iterator index(_monitor.find(name)); if (index != _monitor.end()) { result = index->second.Measurement(); + operational = index->second.Operational(); index->second.Reset(); found = true; } - _adminLock.Unlock(); - return (found); } @@ -943,17 +975,13 @@ namespace Plugin { { bool found = false; - _adminLock.Lock(); - - std::map::iterator index(_monitor.find(name)); + MonitorObjectContainer::iterator index(_monitor.find(name)); if (index != _monitor.end()) { index->second.Reset(); found = true; } - _adminLock.Unlock(); - return (found); } @@ -969,10 +997,7 @@ namespace Plugin { uint64_t scheduledTime(Core::Time::Now().Ticks()); uint64_t nextSlot(static_cast(~0)); - // Other methods (like StateChange()) can modify internals of MonitorObjects elements that is not thread safe - _adminLock.Lock(); - - std::map::iterator index(_monitor.begin()); + MonitorObjectContainer::iterator index(_monitor.begin()); // Go through the list of pending observations... while (index != _monitor.end()) { @@ -993,6 +1018,7 @@ namespace Plugin { const string message("{\"callsign\": \"" + plugin->Callsign() + "\", \"action\": \"Deactivate\", \"reason\": \"" + why.Data() + "\" }"); SYSLOG(Logging::Fatal, (_T("FORCED Shutdown: %s by reason: %s."), plugin->Callsign().c_str(), why.Data())); + _service->Notify(message); _parent.event_action(plugin->Callsign(), "Deactivate", why.Data()); @@ -1012,8 +1038,6 @@ namespace Plugin { index++; } - _adminLock.Unlock(); - if (nextSlot != static_cast(~0)) { if (nextSlot < Core::Time::Now().Ticks()) { _job.Submit(); @@ -1032,7 +1056,7 @@ namespace Plugin { private: template - void translate(const Core::MeasurementType& from, JsonData::Monitor::MeasurementInfo* to) + void translate(const Core::MeasurementType& from, JsonData::Monitor::MeasurementInfo* to) const { to->Min = from.Min(); to->Max = from.Max(); @@ -1040,8 +1064,11 @@ namespace Plugin { to->Last = from.Last(); } - Core::CriticalSection _adminLock; - std::map _monitor; + private: + + using MonitorObjectContainer = std::unordered_map; + + MonitorObjectContainer _monitor; Core::WorkerPool::JobType _job; PluginHost::IShell* _service; Monitor& _parent; @@ -1053,18 +1080,13 @@ namespace Plugin { #endif Monitor() : _skipURL(0) - , _monitor(Core::Service::Create(this)) + , _monitor(this) { - RegisterAll(); } #ifdef __WINDOWS__ #pragma warning(default : 4355) #endif - virtual ~Monitor() - { - UnregisterAll(); - _monitor->Release(); - } + ~Monitor() = default; BEGIN_INTERFACE_MAP(Monitor) INTERFACE_ENTRY(PluginHost::IPlugin) @@ -1082,38 +1104,34 @@ namespace Plugin { // If there is an error, return a string describing the issue why the initialisation failed. // The Service object is *NOT* reference counted, lifetime ends if the plugin is deactivated. // The lifetime of the Service object is guaranteed till the deinitialize method is called. - virtual const string Initialize(PluginHost::IShell* service); + const string Initialize(PluginHost::IShell* service) override; // The plugin is unloaded from WPEFramework. This is call allows the module to notify clients // or to persist information if needed. After this call the plugin will unlink from the service path // and be deactivated. The Service object is the same as passed in during the Initialize. // After theis call, the lifetime of the Service object ends. - virtual void Deinitialize(PluginHost::IShell* service); + void Deinitialize(PluginHost::IShell* service) override; // Returns an interface to a JSON struct that can be used to return specific metadata information with respect // to this plugin. This Metadata can be used by the MetData plugin to publish this information to the ouside world. - virtual string Information() const; + string Information() const override; // IWeb methods // ------------------------------------------------------------------------------------------------------- // Whenever a request is received, it might carry some additional data in the body. This method allows // the plugin to attach a deserializable data object (ref counted) to be loaded with any potential found // in the body of the request. - virtual void Inbound(Web::Request& request); + void Inbound(Web::Request& request) override; // If everything is received correctly, the request is passed on to us, through a thread from the thread pool, to // do our thing and to return the result in the response object. Here the actual specific module work, // based on a a request is handled. - virtual Core::ProxyType Process(const Web::Request& request); - - private: - bool Activated(const string& className, const string& callSign, IPlugin* plugin); - bool Deactivated(const string& className, const string& callSign, IPlugin* plugin); + Core::ProxyType Process(const Web::Request& request) override; private: uint8_t _skipURL; Config _config; - MonitorObjects* _monitor; + Core::Sink _monitor; private: void RegisterAll(); diff --git a/Monitor/MonitorJsonRpc.cpp b/Monitor/MonitorJsonRpc.cpp index a269e2fae0..7ab40aa381 100644 --- a/Monitor/MonitorJsonRpc.cpp +++ b/Monitor/MonitorJsonRpc.cpp @@ -53,7 +53,7 @@ namespace Plugin { uint32_t Monitor::endpoint_restartlimits(const RestartlimitsParamsData& params) { const string& callsign = params.Callsign.Value(); - _monitor->Update( + _monitor.Update( callsign, params.Restart.Window.Value(), params.Restart.Limit.Value()); return Core::ERROR_NONE; @@ -67,9 +67,9 @@ namespace Plugin { const string& callsign = params.Callsign.Value(); Core::JSON::ArrayType info; - _monitor->Snapshot(callsign, &info); + _monitor.Snapshot(callsign, &info); if (info.Length() == 1) { - _monitor->Reset(callsign); + _monitor.Reset(callsign); response = info[0]; } return Core::ERROR_NONE; @@ -81,7 +81,7 @@ namespace Plugin { uint32_t Monitor::get_status(const string& index, Core::JSON::ArrayType& response) const { const string& callsign = index; - _monitor->Snapshot(callsign, &response); + _monitor.Snapshot(callsign, &response); return Core::ERROR_NONE; } diff --git a/Packager/CMakeLists.txt b/Packager/CMakeLists.txt index af6b46253a..17aaa7cb7a 100644 --- a/Packager/CMakeLists.txt +++ b/Packager/CMakeLists.txt @@ -30,6 +30,8 @@ if(PLUGIN_PACKAGER_OUTOFPROCESS STREQUAL "false") unset(PLUGIN_PACKAGER_OUTOFPROCESS CACHE) endif() +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + find_package(${NAMESPACE}Plugins REQUIRED) find_package(libprovision QUIET) find_package(LibOPKG REQUIRED) @@ -40,34 +42,24 @@ add_library(${MODULE_NAME} SHARED Packager.cpp PackagerImplementation.cpp) -if (libprovision_FOUND) - target_link_libraries(${MODULE_NAME} - PRIVATE - CompileSettingsDebug::CompileSettingsDebug - ${NAMESPACE}Plugins::${NAMESPACE}Plugins - libprovision::libprovision - LibOPKG::LibOPKG - ) -else (libprovision_FOUND) - target_include_directories(${MODULE_NAME} - PRIVATE - ${LIBOPKG_INCLUDE_DIRS} - ) +target_include_directories(${MODULE_NAME} PRIVATE + $) - target_link_libraries(${MODULE_NAME} - PRIVATE - CompileSettingsDebug::CompileSettingsDebug - ${NAMESPACE}Plugins::${NAMESPACE}Plugins - ${LIBOPKG_LIBRARIES} - ) +target_link_libraries(${MODULE_NAME} PRIVATE + CompileSettingsDebug::CompileSettingsDebug + ${NAMESPACE}Plugins::${NAMESPACE}Plugins + LibOPKG::LibOPKG) + +if (libprovision_FOUND) + target_link_libraries(${MODULE_NAME} PRIVATE libprovision::libprovision) endif (libprovision_FOUND) string(TOLOWER ${NAMESPACE} STORAGENAME) -install(TARGETS ${MODULE_NAME} +install(TARGETS ${MODULE_NAME} DESTINATION lib/${STORAGENAME}/plugins) configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/opkg.conf.in" + "${CMAKE_CURRENT_LIST_DIR}/opkg.conf.in" "${CMAKE_CURRENT_BINARY_DIR}/opkg.conf" @ONLY) diff --git a/Packager/Packager.conf.in b/Packager/Packager.conf.in index b2368efb6b..067a5df51d 100644 --- a/Packager/Packager.conf.in +++ b/Packager/Packager.conf.in @@ -5,4 +5,3 @@ configuration = JSON() rootobject = JSON() rootobject.add("mode", "@PLUGIN_PACKAGER_MODE@") configuration.add("root", rootobject) - diff --git a/Packager/Packager.cpp b/Packager/Packager.cpp index 029218c0b4..9e907cff62 100644 --- a/Packager/Packager.cpp +++ b/Packager/Packager.cpp @@ -53,45 +53,73 @@ namespace { ASSERT (service != nullptr); _service = service; + _service->AddRef(); _skipURL = static_cast(service->WebPrefix().length()); _service->Register(&_notification); - string result; + string result; _implementation = _service->Root(_connectionId, 2000, _T("PackagerImplementation")); if (_implementation == nullptr) { - result = _T("Couldn't create package instance"); - _service->Unregister(&_notification); - } else if (_implementation->Configure(_service) != Core::ERROR_NONE) { - result = _T("Couldn't initialize package instance"); + result = _T("Couldn't create PACKAGER instance "); _service->Unregister(&_notification); + } else { + Register(kInstallMethodName, [this](const Params& params) -> uint32_t { + return this->_implementation->Install(params.Package.Value(), params.Version.Value(), + params.Architecture.Value()); + }); + Register(kSynchronizeMethodName, [this]() -> uint32_t { + return this->_implementation->SynchronizeRepository(); + }); + + if (_implementation->Configure(_service) != Core::ERROR_NONE) { + result = _T("Couldn't initialize package instance"); + _service->Unregister(&_notification); + } + } + +#ifndef USE_THUNDER_R4 + if (result.length() != 0) { + Deinitialize(service); } +#endif return (result); } void Packager::Deinitialize(PluginHost::IShell* service) { - ASSERT(_service == service); - - _service->Unregister(&_notification); - - if (_implementation->Release() != Core::ERROR_DESTRUCTION_SUCCEEDED) { + if (_service != nullptr) { + ASSERT(_service == service); - ASSERT(_connectionId != 0); - - RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); - - // The process can disappear in the meantime... - if (connection != nullptr) { + _service->Unregister(&_notification); - // But if it did not dissapear in the meantime, forcefully terminate it. Shoot to kill :-) - connection->Terminate(); - connection->Release(); + if (_implementation != nullptr) { + Unregister(kInstallMethodName); + Unregister(kSynchronizeMethodName); + + RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + + uint32_t result = _implementation->Release(); + _implementation = nullptr; + // It should have been the last reference we are releasing, + // so it should end up in a DESCRUCTION_SUCCEEDED, if not we + // are leaking ... + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + + // If this was running in a (container) process ... + if (connection != nullptr) { + // Lets trigger the cleanup sequence for + // out-of-process code. Will will guard + // that unwilling processes, get shot if + // not stopped friendly :~) + connection->Terminate(); + connection->Release(); + } } + _service->Release(); + _service = nullptr; + _connectionId = 0; } - - _service = nullptr; - _implementation = nullptr; } string Packager::Information() const @@ -99,7 +127,7 @@ namespace { return (string()); } - void Packager::Inbound(Web::Request& request) + void Packager::Inbound(Web::Request&) { } diff --git a/Packager/Packager.h b/Packager/Packager.h index 951b71e258..91416d3160 100644 --- a/Packager/Packager.h +++ b/Packager/Packager.h @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + #pragma once #include "Module.h" @@ -29,7 +29,9 @@ namespace { constexpr auto* kSynchronizeMethodName = _T("synchronize"); } - class Packager : public PluginHost::IPlugin, public PluginHost::IWeb, public PluginHost::JSONRPC { + class Packager : public PluginHost::IPlugin, + public PluginHost::IWeb, + public PluginHost::JSONRPC { public: struct Params : public Core::JSON::Container { Params& operator=(const Params& other) = delete; @@ -51,8 +53,10 @@ namespace { Core::JSON::String Version; }; + // We do not allow this plugin to be copied !! Packager(const Packager&) = delete; Packager& operator=(const Packager&) = delete; + Packager() : _skipURL(0) , _connectionId(0) @@ -60,20 +64,9 @@ namespace { , _implementation(nullptr) , _notification(this) { - Register(kInstallMethodName, [this](const Params& params) -> uint32_t { - return this->_implementation->Install(params.Package.Value(), params.Version.Value(), - params.Architecture.Value()); - }); - Register(kSynchronizeMethodName, [this]() -> uint32_t { - return this->_implementation->SynchronizeRepository(); - }); } - ~Packager() override - { - Unregister(kInstallMethodName); - Unregister(kSynchronizeMethodName); - } + ~Packager() override = default; BEGIN_INTERFACE_MAP(Packager) INTERFACE_ENTRY(PluginHost::IPlugin) @@ -100,10 +93,7 @@ namespace { ASSERT(parent != nullptr); } - ~Notification() override - { - } - + ~Notification() override = default; Notification() = delete; Notification(const Notification&) = delete; Notification& operator=(const Notification&) = delete; diff --git a/Packager/PackagerImplementation.cpp b/Packager/PackagerImplementation.cpp index b515b98529..9c80e7b7cc 100644 --- a/Packager/PackagerImplementation.cpp +++ b/Packager/PackagerImplementation.cpp @@ -58,9 +58,9 @@ namespace Plugin { uint32_t result = Core::ERROR_NONE; Config config; - ASSERT (_servicePI == nullptr); - _servicePI = service; - _servicePI->AddRef(); + ASSERT(_service == nullptr); + _service = service; + _service->AddRef(); config.FromString(service->ConfigLine()); @@ -122,8 +122,8 @@ namespace Plugin { PackagerImplementation::~PackagerImplementation() { FreeOPKG(); - _servicePI->Release(); - _servicePI = nullptr; + _service->Release(); + _service = nullptr; } void PackagerImplementation::Register(Exchange::IPackager::INotification* notification) @@ -281,135 +281,80 @@ namespace Plugin { self->_inProgress.Install->SetState(Exchange::IPackager::INSTALLED); self->NotifyStateChange(); self->_inProgress.Install->SetAppName(progress->pkg->local_filename); - string mfilename = self->GetMetadataFile(self->_inProgress.Install->AppName()); - string callsign = self->GetCallsign(mfilename); - if(!callsign.empty()) { - self->DeactivatePlugin(callsign, self->_inProgress.Install->AppName()); + string callsign = self->GetCallsignFromMetaDataFile(self->_inProgress.Install->AppName()); + if (!callsign.empty()) { + self->DeactivatePlugin(callsign); } } } #endif - string PackagerImplementation::GetMetadataFile(const string& appName) - { - char *dnld_loc = opkg_config->cache_dir; - string mfilename = string(dnld_loc) + "/" + appName + "/etc/apps/" + appName + "_package.json"; - return mfilename; - } - - string PackagerImplementation::GetCallsign(const string& mfilename) + string PackagerImplementation::GetCallsignFromMetaDataFile(const string& appName) { string callsign = ""; - TRACE(Trace::Information, (_T("[Packager]: Metadata is %s"),mfilename.c_str())); - Core::File file(mfilename); - if(file.Open()) { - JsonObject parameters; - if(parameters.IElement::FromFile(file)) { - if(parameters.HasLabel("type")) { - string type = parameters["type"].String(); - if( 0 == type.compare("plugin")) { - if(parameters.HasLabel("callsign")) { - callsign = parameters["callsign"].String(); - } - else { - TRACE(Trace::Information, (_T("[Packager]: callsign missing in metadata"))); + string metaDataFileName = (string(opkg_config->cache_dir) + "/" + appName + string(AppPath) + appName + string(PackageJSONFile)); + TRACE(Trace::Information, (_T("[RDM]: Metadata is %s"), metaDataFileName.c_str())); + Core::File metaDataFile(metaDataFileName); + if (metaDataFile.Open()) { + MetaData metaData; + Core::OptionalType error; + if (metaData.IElement::FromFile(metaDataFile, error)) { + if (error.IsSet() == true) { + TRACE(Trace::Error, (_T("Parsing failed with %s"), ErrorDisplayMessage(error.Value()).c_str())); + } else { + if ((metaData.Type.IsSet() == true) && (metaData.Type.Value() == PackagerImplementation::PackageType::PLUGIN)) { + if (metaData.Callsign.IsSet() == true) { + callsign = metaData.Callsign.Value(); + } else { + TRACE(Trace::Information, (_T("[RDM]: callsign missing in metadata"))); } + } else { + TRACE(Trace::Information, (_T("[RDM]: MetaData file does not contain plugin type"))); } - else { - TRACE(Trace::Information, (_T("[Packager]: Package does not contain thunder plugin"))); - } - } - else { - TRACE(Trace::Information, (_T("[Packager]: Metadata type not found"))); } } - else { - TRACE(Trace::Error, (_T("[Packager]: Error in reading the file"))); - } - } - else { - TRACE(Trace::Error, (_T("[Packager]: Error in opening the file"))); + } else { + TRACE(Trace::Error, (_T("[RDM]: Error in opening the file"))); } return callsign; } - string PackagerImplementation::GetInstallationPath(const string& appname) + void PackagerImplementation::DeactivatePlugin(const string& callsign) { - char *dnld_loc = opkg_config->cache_dir; - string instPath = string(dnld_loc) + "/" + appname; - return instPath; - } - - uint32_t PackagerImplementation::UpdateConfiguration(const string& callsign, const string& installPath) - { - uint32_t result = Core::ERROR_GENERAL; + ASSERT(_service != nullptr); ASSERT(callsign.empty() == false); - ASSERT(_servicePI != nullptr); - - PluginConfig pluginconfig; - PluginHost::IShell* shell = _servicePI->QueryInterfaceByCallsign(callsign); - if (shell != nullptr) { - if (shell->SystemRootPath(installPath) == Core::ERROR_NONE) { - TRACE(Trace::Information, (_T("[Packager]: SystemRootPath for %s is %s"), callsign.c_str(), shell->SystemRootPath().c_str())); + TRACE(Trace::Information, (_T("[RDM]: callsign from metadata is %s"), callsign.c_str())); + PluginHost::IShell* plugin = _service->QueryInterfaceByCallsign(callsign); - PluginHost::IController* controller = _servicePI->QueryInterfaceByCallsign(EMPTY_STRING); - if (controller != nullptr) { - if (controller->Persist() == Core::ERROR_NONE) { - result = Core::ERROR_NONE; - TRACE(Trace::Information, (_T("[Packager]: Successfully stored %s plugin's config in peristent path"), callsign.c_str())); - } + if (plugin != nullptr) { + PluginHost::IShell::state currentState(plugin->State()); + if ((currentState == PluginHost::IShell::ACTIVATED) || (currentState == PluginHost::IShell::ACTIVATION) || (currentState == PluginHost::IShell::PRECONDITION)) { + TRACE(Trace::Information, (_T("[RDM]: Plugin %s is activated state, so deactivating"), callsign.c_str())); + uint32_t result = plugin->Deactivate(PluginHost::IShell::REQUESTED); + if (result == Core::ERROR_NONE) { + TRACE(Trace::Information, (_T("[RDM]: %s moved to Deactivated state"), callsign.c_str())); } else { - TRACE(Trace::Error, (_T("[Packager]: Failed to find Controller interface"))); + TRACE(Trace::Error, (_T("[RDM]: Failed to move %s to Deactivated state"), callsign.c_str())); } - controller->Release(); - } - } - else { - TRACE(Trace::Error, (_T("[Packager]: Failed to find Shell interface"))); - } - shell->Release(); - return result; - } - - void PackagerImplementation::DeactivatePlugin(const string& callsign, const string& appName) - { - ASSERT(callsign.empty() == false); - ASSERT(_servicePI != nullptr); - TRACE(Trace::Information, (_T("[Packager]: callsign from metadata is %s"), callsign.c_str())); - PluginHost::IShell* dlPlugin = _servicePI->QueryInterfaceByCallsign(callsign); - - if (dlPlugin == nullptr) { - TRACE(Trace::Error, (_T("[Packager]: Plugin %s is not configured in this setup"), callsign.c_str())); - } - else { - PluginHost::IShell::state currentState(dlPlugin->State()); - if (currentState != PluginHost::IShell::UNAVAILABLE) { - TRACE(Trace::Information, (_T("[Packager]: Plugin %s is not in Unavailable state. Hence, not deactivating it"),callsign.c_str())); + } else if (currentState == PluginHost::IShell::UNAVAILABLE) { + TRACE(Trace::Information, (_T("[RDM]: Plugin %s is unavailable"), callsign.c_str())); } else { - TRACE(Trace::Information, (_T("[Packager]: Plugin %s is in Unavailable state"), callsign.c_str())); - uint32_t result = dlPlugin->Deactivate(PluginHost::IShell::REQUESTED); - if (result == Core::ERROR_NONE) { - TRACE(Trace::Information, (_T("[Packager]: %s moved to Deactivated state"), callsign.c_str())); - string appInstallPath = GetInstallationPath(appName); - if (UpdateConfiguration(callsign, appInstallPath) != Core::ERROR_NONE) { - TRACE(Trace::Error, (_T("[Packager]: Failed to update SystemRootPath for %s"), callsign.c_str())); - } - } - else { - TRACE(Trace::Error, (_T("[Packager]: Failed to move %s to Deactivated state"), callsign.c_str())); - } + TRACE(Trace::Information, (_T("[RDM]: Plugin %s is already in deactivated state"), callsign.c_str())); } + + plugin->Release(); + } else { + TRACE(Trace::Error, (_T("[RDM]: Plugin %s is not configured in this setup"), callsign.c_str())); } - dlPlugin->Release(); } void PackagerImplementation::NotifyStateChange() { _adminLock.Lock(); - TRACE_L1("State for %s changed to %d (%d %%, %d)", _inProgress.Package->Name().c_str(), _inProgress.Install->State(), _inProgress.Install->Progress(), _inProgress.Install->ErrorCode()); + TRACE(Trace::Information, (_T("State for %s changed to %d (%d %%, %d)"), _inProgress.Package->Name().c_str(), _inProgress.Install->State(), _inProgress.Install->Progress(), _inProgress.Install->ErrorCode())); for (auto* notification : _notifications) { notification->StateChange(_inProgress.Package, _inProgress.Install); } @@ -470,7 +415,7 @@ namespace Plugin { if (opkg_update_package_lists(nullptr, nullptr) != 0) #endif { - TRACE_L1("Failed to set up local repo. Installing might not work"); + TRACE(Trace::Error, (_T("Failed to set up local repo. Installing might not work"))); result = Core::ERROR_GENERAL; } NotifyRepoSynced(result); @@ -478,4 +423,8 @@ namespace Plugin { } } // namespace Plugin +ENUM_CONVERSION_BEGIN(Plugin::PackagerImplementation::PackageType) + { Plugin::PackagerImplementation::PackageType::NONE, _TXT("none") }, + { Plugin::PackagerImplementation::PackageType::PLUGIN, _TXT("plugin") }, +ENUM_CONVERSION_END(Plugin::PackagerImplementation::PackageType); } // namespace WPEFramework diff --git a/Packager/PackagerImplementation.h b/Packager/PackagerImplementation.h index 2ba0545db4..f3462f1627 100644 --- a/Packager/PackagerImplementation.h +++ b/Packager/PackagerImplementation.h @@ -33,9 +33,15 @@ namespace WPEFramework { namespace Plugin { class PackagerImplementation : public Exchange::IPackager { + private: + static constexpr const TCHAR* AppPath = _T("/etc/apps/"); + static constexpr const TCHAR* PackageJSONFile = _T("_package.json"); + public: - PackagerImplementation(const PackagerImplementation&) = delete; - PackagerImplementation& operator=(const PackagerImplementation&) = delete; + enum PackageType { + NONE, + PLUGIN + }; class EXTERNAL Config : public Core::JSON::Container { public: @@ -66,6 +72,7 @@ namespace Plugin { Config(const Config&) = delete; Config& operator=(const Config&) = delete; + public: Core::JSON::String ConfigFile; Core::JSON::String TempDir; Core::JSON::String CacheDir; @@ -76,6 +83,35 @@ namespace Plugin { Core::JSON::Boolean AlwaysUpdateFirst; }; + class MetaData : public Core::JSON::Container { + public: + MetaData() + : Core::JSON::Container() + , Callsign() + , Type(NONE) + { + Add(_T("callsign"), &Callsign); + Add(_T("type"), &Type); + } + MetaData(const MetaData& copy) + : Core::JSON::Container() + , Callsign(copy.Callsign) + , Type(copy.Type) + { + Add(_T("callsign"), &Callsign); + Add(_T("type"), &Type); + } + ~MetaData() override = default; + + public: + Core::JSON::String Callsign; + Core::JSON::EnumType Type; + }; + + public: + PackagerImplementation(const PackagerImplementation&) = delete; + PackagerImplementation& operator=(const PackagerImplementation&) = delete; + PackagerImplementation() : _adminLock() , _configFile() @@ -87,7 +123,7 @@ namespace Plugin { , _alwaysUpdateFirst(false) , _volatileCache(false) , _opkgInitialized(false) - , _servicePI(nullptr) + , _service(nullptr) , _worker(this) , _isUpgrade(false) , _isSyncing(false) @@ -96,24 +132,6 @@ namespace Plugin { ~PackagerImplementation() override; - class PluginConfig : public Core::JSON::Container { - public: - PluginConfig(const PluginConfig&) = delete; - PluginConfig& operator=(const PluginConfig&) = delete; - - PluginConfig() - : SystemRootPath() - { - Add(_T("systemrootpath"), &SystemRootPath); - } - - Core::JSON::String SystemRootPath; - - ~PluginConfig() override - { - } - }; - BEGIN_INTERFACE_MAP(PackagerImplementation) INTERFACE_ENTRY(Exchange::IPackager) END_INTERFACE_MAP @@ -213,26 +231,27 @@ namespace Plugin { void SetState(Exchange::IPackager::state state) { - TRACE_L1("Setting state to %d", state); + TRACE(Trace::Information, (_T("Setting state to %d"), state)); _state = state; } void SetProgress(uint8_t progress) { - TRACE_L1("Setting progress to %d", progress); + TRACE(Trace::Information, (_T("Setting progress to %d"), progress)); _progress = progress; } void SetAppName(const TCHAR path[]) { - string _pathname = Core::File::PathName(string(path)); - string _dirname = _pathname.substr(0,_pathname.size()-1); - _appname = Core::File::FileName(_dirname); + string pathName = Core::File::PathName(string(path)); + if (pathName.empty() == false) { + _appname = Core::File::FileName(string(pathName.c_str(), pathName.size() - 1)); + } } void SetError(uint32_t err) { - TRACE_L1("Setting error to %d", err); + TRACE(Trace::Information, (_T("Setting error to %d"), err)); _error = err; } @@ -310,11 +329,8 @@ namespace Plugin { #if !defined (DO_NOT_USE_DEPRECATED_API) static void InstallationProgessNoLock(const _opkg_progress_data_t* progress, void* data); #endif - string GetMetadataFile(const string& appName); - string GetCallsign(const string& mfilename); - string GetInstallationPath(const string& appName); - void DeactivatePlugin(const string& callsign, const string& appName); - uint32_t UpdateConfiguration(const string& callsign, const string& appName); + string GetCallsignFromMetaDataFile(const string& appName); + void DeactivatePlugin(const string& callsign); void NotifyStateChange(); void NotifyRepoSynced(uint32_t status); void BlockingInstallUntilCompletionNoLock(); @@ -332,7 +348,7 @@ namespace Plugin { bool _alwaysUpdateFirst; bool _volatileCache; bool _opkgInitialized; - PluginHost::IShell* _servicePI; + PluginHost::IShell* _service; std::vector _notifications; InstallationData _inProgress; InstallThread _worker; diff --git a/PerformanceMetrics/PerformanceMetrics.cpp b/PerformanceMetrics/PerformanceMetrics.cpp index 51b49b6a97..96948d4069 100644 --- a/PerformanceMetrics/PerformanceMetrics.cpp +++ b/PerformanceMetrics/PerformanceMetrics.cpp @@ -62,7 +62,9 @@ namespace Plugin { _handler->Initialize(); service->Register(&_notification); } else { +#ifndef USE_THUNDER_R4 Deinitialize(service); +#endif } return result; @@ -70,7 +72,7 @@ namespace Plugin { void PerformanceMetrics::Deinitialize(PluginHost::IShell* service) { - if( _handler ) { + if (_handler) { service->Unregister(&_notification); // as we do this after the unregister the call to Deinitialize should be threadsafe, no more notifications can be received // if the deactivate of the observable did not happen we must clean up here diff --git a/PerformanceMetrics/SyslogOutput.cpp b/PerformanceMetrics/SyslogOutput.cpp index b4c6b1c0c7..ed558c2a02 100644 --- a/PerformanceMetrics/SyslogOutput.cpp +++ b/PerformanceMetrics/SyslogOutput.cpp @@ -77,7 +77,7 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { URLLoadedMetrics& operator=(const URLLoadedMetrics& copy) { - if( this != © ) { + if (this != ©) { _total = copy._total; _free = copy._free; _swapped = copy._swapped; @@ -277,14 +277,14 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { _service = &service; _service->AddRef(); _memory = service.QueryInterface(); - if( _memory != nullptr ) { + if (_memory != nullptr) { Exchange::IMemoryExtended* extended = _memory->QueryInterface(); - if( extended != nullptr ) { + if (extended != nullptr) { Exchange::IMemoryExtended::IStringIterator* iterator = nullptr; - if( ( extended->Processes(iterator) == Core::ERROR_NONE ) && ( iterator != nullptr ) ) { + if ((extended->Processes(iterator) == Core::ERROR_NONE ) && ( iterator != nullptr)) { string processname; - while( iterator->Next(processname) == true ) { - if( processname == webProcessName ) { + while (iterator->Next(processname) == true) { + if (processname == webProcessName) { VARIABLE_IS_NOT_USED uint32_t result = extended->Process(webProcessName, _processmemory); ASSERT( ( result == Core::ERROR_NONE ) && (_processmemory != nullptr )); break; @@ -299,15 +299,15 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { void Disable() override { - if(_service != nullptr) { + if (_service != nullptr) { _service->Release(); _service = nullptr; } - if(_memory != nullptr) { + if (_memory != nullptr) { _memory->Release(); _memory = nullptr; } - if(_processmemory != nullptr) { + if (_processmemory != nullptr) { _processmemory->Release(); _processmemory = nullptr; } @@ -322,8 +322,7 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { void Deactivated(const uint32_t) override { PluginHost::IShell::reason reason = _service->Reason(); - if(reason == PluginHost::IShell::FAILURE || reason == PluginHost::IShell::MEMORY_EXCEEDED) - { + if (reason == PluginHost::IShell::FAILURE || reason == PluginHost::IShell::MEMORY_EXCEEDED) { SYSLOG(Logging::Notification, (_T("Browser::Deactivated ( \"URL\": %s , \"Reason\": %d )"), getHostName(_lastURL).c_str(), reason)); string eventName("BrowserDeactivation_accum"); string eventValue; @@ -347,29 +346,33 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { string getHostName(string _URL){ std::size_t startIdx = _URL.find("://"); - if(startIdx == std::string::npos) + if (startIdx == std::string::npos) { return _URL; + } else { startIdx += 3; // skip "://" size_t endIdx = _URL.find("/",startIdx); - if(endIdx == std::string::npos) + if (endIdx == std::string::npos) { return _URL.substr(startIdx); - else + } + else { return _URL.substr(startIdx, endIdx - startIdx); + } } } void LoadFinished(const string& URL, const int32_t, const bool success, const uint32_t totalsuccess, const uint32_t totalfailed) override { - if( URL != startURL ) { + if (URL != startURL) { _adminLock.Lock(); URLLoadedMetrics metrics(_urloadmetrics); _adminLock.Unlock(); uint64_t urllaunchtime_ms = ( ( Core::Time::Now().Ticks() - metrics.StartLoad() ) / Core::Time::TicksPerMillisecond); - if(strcmp(getHostName(URL).c_str(), _lastLoggedApp.c_str())) - _didLogLaunchMetrics = false; + if (strcmp(getHostName(URL).c_str(), _lastLoggedApp.c_str())) { + _didLogLaunchMetrics = false; + } OutputLoadFinishedMetrics(metrics, getHostName(URL), urllaunchtime_ms, success, totalsuccess + totalfailed); @@ -379,7 +382,7 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { void URLChange(const string& URL, const bool) override { - if( URL != startURL ) { + if (URL != startURL) { URLLoadedMetrics metrics; Core::SystemInfo::MemorySnapshot snapshot = Core::SystemInfo::Instance().TakeMemorySnapshot(); metrics.Total(snapshot.Total()); @@ -391,13 +394,13 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { metrics.AverageLoad()[2] = Core::SystemInfo::Instance().GetCpuLoadAvg()[2]; uint64_t resident = 0; - if( _processmemory != nullptr ) { + if (_processmemory != nullptr) { resident = _processmemory->Resident(); uint32_t pid = _processmemory->Identifier(); - if( pid != 0 ) { + if (pid != 0) { metrics.StatmLine(GetProcessStatmLine(pid)); } - } else if ( _memory != nullptr ) { + } else if (_memory != nullptr) { resident = _memory->Resident(); } @@ -407,8 +410,9 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { uint64_t timeLaunched = 0; timeLaunched = (Core::Time::Now().Ticks() - _timePluginStart) / Core::Time::MicroSecondsPerSecond; - if(timeLaunched < 2) + if (timeLaunched < 2) { metrics.SetColdLaunch(true); + } _adminLock.Lock(); _urloadmetrics = std::move(metrics); @@ -430,8 +434,9 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { const bool success, const uint32_t totalloaded) { - if(_didLogLaunchMetrics) + if (_didLogLaunchMetrics) { return; + } MetricsAsJson output; @@ -453,7 +458,7 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { output.ProcessRSS = urloadedmetrics.RSSMemProcess(); uint32_t pid = 0; - if( _processmemory != nullptr ) { + if (_processmemory != nullptr) { pid = _processmemory->Identifier(); } output.ProcessPID = pid; @@ -481,7 +486,7 @@ class SysLogOuput : public PerformanceMetrics::IBrowserMetricsLogger { Utils::Telemetry::sendMessage((char *)eventName.c_str(), (char *)eventValue.c_str()); - SYSLOG(Logging::Notification, (_T( "%s Launch Metrics: %s "), _callsign.c_str(), outputstring.c_str())); + SYSLOG(Logging::Notification, (_T( "%s Launch Metrics: %s "), _callsign.c_str(), outputstring.c_str())); _didLogLaunchMetrics = true; _lastLoggedApp = URL; } diff --git a/PerformanceMetrics/TraceOutput.cpp b/PerformanceMetrics/TraceOutput.cpp index a396d1e2c0..87b7d01df5 100644 --- a/PerformanceMetrics/TraceOutput.cpp +++ b/PerformanceMetrics/TraceOutput.cpp @@ -164,7 +164,7 @@ class MetricsTraceOuputBrowser : public PerformanceMetrics::IBrowserMetricsLogge void Deactivated(const uint32_t uptime) override { - TRACE(Trace::Metric, (_T("Plugin %s deactivated, uptime(s): %u"), _callsign.c_str(), (uptime/1000))); + TRACE(Trace::Metric, (_T("Plugin %s deactivated, uptime(s): %u"), _callsign.c_str(), uptime)); } void Resumed() override diff --git a/PlayerInfo/CMakeLists.txt b/PlayerInfo/CMakeLists.txt index e2c0263ba8..5230a1573b 100644 --- a/PlayerInfo/CMakeLists.txt +++ b/PlayerInfo/CMakeLists.txt @@ -81,28 +81,28 @@ if (GSTREAMER_FOUND) target_sources(${MODULE_NAME} PRIVATE GStreamer/PlatformImplementation.cpp) + endif () +endif () - if (DOLBY_SUPPORT) - target_sources(${MODULE_NAME} - PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/Dolby/DolbyOutput.cpp) +if (DOLBY_SUPPORT) + target_sources(${MODULE_NAME} + PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/Dolby/DolbyOutput.cpp) - target_include_directories(${MODULE_NAME} - PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/Dolby/include) + target_include_directories(${MODULE_NAME} + PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/Dolby/include) - target_compile_definitions(${MODULE_NAME} - PRIVATE - DOLBY_SUPPORT=1) + target_compile_definitions(${MODULE_NAME} + PRIVATE + DOLBY_SUPPORT=1) - add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/Dolby) + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/Dolby) - target_link_libraries(${MODULE_NAME} - PRIVATE - PlayerInfoDolby) - endif() - endif () -endif () + target_link_libraries(${MODULE_NAME} + PRIVATE + PlayerInfoDolby) +endif() install(TARGETS ${MODULE_NAME} DESTINATION lib/${STORAGE_DIRECTORY}/plugins) diff --git a/PlayerInfo/DeviceSettings/PlatformImplementation.cpp b/PlayerInfo/DeviceSettings/PlatformImplementation.cpp index 282af9914c..28a00d97ea 100644 --- a/PlayerInfo/DeviceSettings/PlatformImplementation.cpp +++ b/PlayerInfo/DeviceSettings/PlatformImplementation.cpp @@ -529,6 +529,6 @@ class PlayerInfoImplementation : public Exchange::IPlayerProperties, public Exch static PlayerInfoImplementation* _instance; }; PlayerInfoImplementation* PlayerInfoImplementation::_instance = nullptr; - SERVICE_REGISTRATION(PlayerInfoImplementation, 1, 0); + SERVICE_REGISTRATION(PlayerInfoImplementation, 1, 0) } } diff --git a/PlayerInfo/PlayerInfo.conf.in b/PlayerInfo/PlayerInfo.conf.in index dfbabb8f33..a3b4334644 100644 --- a/PlayerInfo/PlayerInfo.conf.in +++ b/PlayerInfo/PlayerInfo.conf.in @@ -4,5 +4,9 @@ startuporder = "@PLUGIN_PLAYERINFO_STARTUPORDER@" configuration = JSON() rootobject = JSON() -rootobject.add("mode", "@PLUGIN_PLAYERINFO_MODE@") +if "@PLUGIN_IMPLEMENTATION_GSTREAMER@" == "ON": + rootobject.add("mode", "Local") +else: + rootobject.add("mode", "@PLUGIN_PLAYERINFO_MODE@") + configuration.add("root", rootobject) diff --git a/PlayerInfo/PlayerInfo.cpp b/PlayerInfo/PlayerInfo.cpp index aa2c4036d4..c9bdbf5ad3 100644 --- a/PlayerInfo/PlayerInfo.cpp +++ b/PlayerInfo/PlayerInfo.cpp @@ -76,7 +76,7 @@ namespace Plugin { // The relevant JSONRPC endpoints will return ERROR_UNAVAILABLE, // if it hasn't been initialized. _dolbyOut = _player->QueryInterface(); - if(_dolbyOut == nullptr){ + if (_dolbyOut == nullptr) { SYSLOG(Logging::Startup, (_T("Dolby output switching service is unavailable."))); } else { _dolbyNotification.Initialize(_dolbyOut); @@ -93,56 +93,60 @@ namespace Plugin { message = _T("PlayerInfo could not be instantiated."); } - if(message.length() != 0){ +#ifndef USE_THUNDER_R4 + if (message.length() != 0) { Deinitialize(service); } +#endif + return message; } /* virtual */ void PlayerInfo::Deinitialize(PluginHost::IShell* service VARIABLE_IS_NOT_USED) { - ASSERT(service == _service); + if (_service != nullptr) { + ASSERT(service == _service); - _service->Unregister(&_notification); + _service->Unregister(&_notification); - if (_player != nullptr) { - if(_audioCodecs != nullptr && _videoCodecs != nullptr) { - Exchange::JPlayerProperties::Unregister(*this); - } - if (_audioCodecs != nullptr) { - _audioCodecs->Release(); - _audioCodecs = nullptr; - } - if (_videoCodecs != nullptr) { - _videoCodecs->Release(); - _videoCodecs = nullptr; - } - if (_dolbyOut != nullptr) { - _dolbyNotification.Deinitialize(); - Exchange::Dolby::JOutput::Unregister(*this); - _dolbyOut->Release(); - _dolbyOut = nullptr; - } + if (_player != nullptr) { + if (_audioCodecs != nullptr && _videoCodecs != nullptr) { + Exchange::JPlayerProperties::Unregister(*this); + } + if (_audioCodecs != nullptr) { + _audioCodecs->Release(); + _audioCodecs = nullptr; + } + if (_videoCodecs != nullptr) { + _videoCodecs->Release(); + _videoCodecs = nullptr; + } + if (_dolbyOut != nullptr) { + _dolbyNotification.Deinitialize(); + Exchange::Dolby::JOutput::Unregister(*this); + _dolbyOut->Release(); + _dolbyOut = nullptr; + } - RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); - VARIABLE_IS_NOT_USED uint32_t result = _player->Release(); - _player = nullptr; - ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + VARIABLE_IS_NOT_USED uint32_t result = _player->Release(); + _player = nullptr; + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); - // The connection can disappear in the meantime... - if (connection != nullptr) { - // But if it did not dissapear in the meantime, forcefully terminate it. Shoot to kill :-) - connection->Terminate(); - connection->Release(); + // The connection can disappear in the meantime... + if (connection != nullptr) { + // But if it did not dissapear in the meantime, forcefully terminate it. Shoot to kill :-) + connection->Terminate(); + connection->Release(); + } } - } - _service->Release(); - _service = nullptr; - _player = nullptr; + _service->Release(); + _service = nullptr; + _player = nullptr; - _connectionId = 0; - + _connectionId = 0; + } } /* virtual */ string PlayerInfo::Information() const @@ -198,7 +202,7 @@ namespace Plugin { Core::JSON::EnumType videoCodec; Exchange::IPlayerProperties::VideoCodec video; _videoCodecs->Reset(0); - while(_videoCodecs->Next(video) == true) { + while(_videoCodecs->Next(video) == true) { playerInfo.Video.Add(videoCodec = static_cast(video)); } } diff --git a/PlayerInfo/PlayerInfo.h b/PlayerInfo/PlayerInfo.h index 5d18787337..d5197509ca 100644 --- a/PlayerInfo/PlayerInfo.h +++ b/PlayerInfo/PlayerInfo.h @@ -43,13 +43,16 @@ namespace Plugin { ~Notification() override = default; public: - void Activated(RPC::IRemoteConnection*) override + void Activated(RPC::IRemoteConnection* /* connection */) override { } void Deactivated(RPC::IRemoteConnection* connection) override { _parent.Deactivated(connection); } + void Terminated(RPC::IRemoteConnection* /* connection */) override + { + } BEGIN_INTERFACE_MAP(Notification) INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) @@ -87,7 +90,7 @@ namespace Plugin { _client = nullptr; } } - void AudioModeChanged(Exchange::Dolby::IOutput::SoundModes mode, bool enabled) override + void AudioModeChanged(const Exchange::Dolby::IOutput::SoundModes mode, bool enabled) override { Exchange::Dolby::JOutput::Event::AudioModeChanged(_parent, mode, enabled); } diff --git a/SecurityAgent/AccessControlList.h b/SecurityAgent/AccessControlList.h index 9176a309df..7607fffa78 100644 --- a/SecurityAgent/AccessControlList.h +++ b/SecurityAgent/AccessControlList.h @@ -214,14 +214,16 @@ namespace Plugin { class Group : public Core::JSON::Container { public: Group() - : URL() + : Core::JSON::Container() + , URL() , Role() { Add(_T("url"), &URL); Add(_T("role"), &Role); } Group(const Group& copy) - : URL() + : Core::JSON::Container() + , URL() , Role() { Add(_T("url"), &URL); diff --git a/SecurityAgent/SecurityAgent.cpp b/SecurityAgent/SecurityAgent.cpp index 22158234df..519dded81c 100644 --- a/SecurityAgent/SecurityAgent.cpp +++ b/SecurityAgent/SecurityAgent.cpp @@ -85,6 +85,7 @@ namespace Plugin { : _acl() , _dispatcher(nullptr) , _engine() + , _testtoken() { RegisterAll(); } @@ -96,6 +97,7 @@ namespace Plugin { /* virtual */ const string SecurityAgent::Initialize(PluginHost::IShell* service) { + string message; Config config; config.FromString(service->ConfigLine()); string version = service->Version(); @@ -150,7 +152,7 @@ namespace Plugin { connector = service->VolatilePath() + _T("token"); } - SYSLOG(Logging::Notification,(_T("SecurityAgent TokenDispatcher connector path %s"),connector.c_str())); + TRACE(Security, (_T("SecurityAgent TokenDispatcher connector path %s"),connector.c_str())); _engine = Core::ProxyType::Create(&Core::IWorkerPool::Instance()); _dispatcher.reset(new TokenDispatcher(Core::NodeId(connector.c_str()), service->ProxyStubPath(), this, _engine)); @@ -174,9 +176,18 @@ namespace Plugin { } } } + else { + message = _T("SecurityAgent failed to create TokenDispatcher"); + } + +#ifndef USE_THUNDER_R4 + if (message.length() != 0) { + Deinitialize(service); + } +#endif // On success return empty, to indicate there is no error text. - return _T(""); + return message; } /* virtual */ void SecurityAgent::Deinitialize(PluginHost::IShell* service) @@ -189,11 +200,12 @@ namespace Plugin { subSystem->Set(PluginHost::ISubSystem::NOT_SECURITY, nullptr); subSystem->Release(); } - - _dispatcher.reset(); - _engine.Release(); - _acl.Clear(); + _dispatcher.reset(nullptr); + + if (_engine.IsValid()) { + _engine.Release(); + } if (_dacDirCallback.IsValid()) { Core::FileSystemMonitor::Instance().Unregister(&(*_dacDirCallback), _dacDir); @@ -210,7 +222,7 @@ namespace Plugin { /* virtual */ uint32_t SecurityAgent::CreateToken(const uint16_t length, const uint8_t buffer[], string& token) { - SYSLOG(Logging::Notification, (_T("Creating Token for %.*s"), length, buffer)); + TRACE(Security, (_T("Creating Token for %.*s"), length, buffer)); // Generate the token from the buffer coming in... auto newToken = JWTFactory::Instance().Element(); @@ -222,27 +234,37 @@ namespace Plugin { { PluginHost::ISecurity* result = nullptr; - auto webToken = JWTFactory::Instance().Element(); - uint16_t load = webToken->PayloadLength(token); + if (token.empty() == false) { + if (token != _testtoken) { + + auto webToken = JWTFactory::Instance().Element(); + uint16_t load = webToken->PayloadLength(token); - // Validate the token - if (load != static_cast(~0)) { - // It is potentially a valid token, extract the payload. - uint8_t* payload = reinterpret_cast(ALLOCA(load)); + // Validate the token + if (load != static_cast(~0)) { + // It is potentially a valid token, extract the payload. + uint8_t* payload = reinterpret_cast(ALLOCA(load)); - load = webToken->Decode(token, load, payload); + load = webToken->Decode(token, load, payload); - if (load != static_cast(~0)) { - // Seems like we extracted a valid payload, time to create an security context - Payload payloadJson; - payloadJson.FromString(string(reinterpret_cast(payload), load)); + if (load != static_cast(~0)) { + // Seems like we extracted a valid payload, time to create an security context + Payload payloadJson; + payloadJson.FromString(string(reinterpret_cast(payload), load)); - if (payloadJson.Type.IsSet() && (payloadJson.Type == tokentype::DAC)) { - result = Core::Service::Create(&_dac, load, payload, _servicePrefix); - } else { - result = Core::Service::Create(&_acl, load, payload, _servicePrefix); + if (payloadJson.Type.IsSet() && (payloadJson.Type == tokentype::DAC)) { + result = Core::Service::Create(&_dac, load, payload, _servicePrefix); + } else { + result = Core::Service::Create(&_acl, load, payload, _servicePrefix); + } + } } } +#ifdef SECURITY_TESTING_MODE + else { + result = Core::Service::Create(&_acl, static_cast(sizeof(SecurityAgent::TestTokenContent) - 1), reinterpret_cast(SecurityAgent::TestTokenContent), _servicePrefix); + } +#endif } return (result); } @@ -262,9 +284,9 @@ namespace Plugin { index.Next(); - if (index.Next() == true) { + if (index.Next() == true) { // We might be receiving a plugin download request. - #ifdef SECURITY_TESTING_MODE +#ifdef SECURITY_TESTING_MODE if ((request.Verb == Web::Request::HTTP_PUT) && (request.HasBody() == true)) { if (index.Current() == _T("Token")) { Core::ProxyType data(request.Body()); @@ -284,7 +306,7 @@ namespace Plugin { } } } else - #endif +#endif if ( (request.Verb == Web::Request::HTTP_GET) && (index.Current() == _T("Valid")) ) { result->ErrorCode = Web::STATUS_FORBIDDEN; @@ -308,14 +330,13 @@ namespace Plugin { } else { result->ErrorCode = Web::STATUS_OK; result->Message = _T("Valid token"); - TRACE(Trace::Information, (_T("Token contents: %s"), reinterpret_cast(payload))); + TRACE(Security, (_T("Token contents: %s"), reinterpret_cast(payload))); } } - - } + } } } - return (result); + return (result); } } // namespace Plugin diff --git a/SecurityAgent/SecurityAgent.h b/SecurityAgent/SecurityAgent.h index d4d023d7f0..7ffba80f3f 100644 --- a/SecurityAgent/SecurityAgent.h +++ b/SecurityAgent/SecurityAgent.h @@ -78,7 +78,7 @@ namespace Plugin { _parentInterface->AddRef(); - TRACE(Trace::Information, ("SecurityAgent interface(IAuthenticate) aquired => %p", this)); + TRACE(Security, ("SecurityAgent interface(IAuthenticate) acquired => %p", this)); result = _parentInterface; } return (result); @@ -96,12 +96,14 @@ namespace Plugin { public: Config() : Core::JSON::Container() - , ACL() + , ACL(_T("acl.json")) , Connector() + , TestToken() , DAC() { Add(_T("acl"), &ACL); Add(_T("connector"), &Connector); + Add(_T("testtoken"), &TestToken); Add(_T("dac"), &DAC); } ~Config() @@ -111,6 +113,7 @@ namespace Plugin { public: Core::JSON::String ACL; Core::JSON::String Connector; + Core::JSON::String TestToken; Core::JSON::String DAC; }; @@ -210,21 +213,25 @@ namespace Plugin { // ------------------------------------------------------------------------------------------------------- void RegisterAll(); void UnregisterAll(); - #ifdef SECURITY_TESTING_MODE +#ifdef SECURITY_TESTING_MODE uint32_t endpoint_createtoken(const JsonData::SecurityAgent::CreatetokenParamsData& params, JsonData::SecurityAgent::CreatetokenResultInfo& response); - #endif // DEBUG +#endif // DEBUG uint32_t endpoint_validate(const JsonData::SecurityAgent::CreatetokenResultInfo& params, JsonData::SecurityAgent::ValidateResultData& response); - private: AccessControlList _acl; uint8_t _skipURL; std::unique_ptr _dispatcher; Core::ProxyType _engine; + string _testtoken; string _servicePrefix; string _dacDir; AccessControlList _dac; Core::ProxyType _dacDirCallback; + +#ifdef SECURITY_TESTING_MODE + static constexpr const TCHAR* TestTokenContent = _T(R"--({ "url": "https://test.url.com", "user":"Test" })--"); +#endif // DEBUG }; } // namespace Plugin diff --git a/SecurityAgent/SecurityContext.cpp b/SecurityAgent/SecurityContext.cpp index 994fea79a1..9dcb8edd24 100644 --- a/SecurityAgent/SecurityContext.cpp +++ b/SecurityAgent/SecurityContext.cpp @@ -54,12 +54,14 @@ namespace Plugin { SecurityContext::SecurityContext(const AccessControlList* acl, const uint16_t length, const uint8_t payload[], const string& servicePrefix) : _token(string(reinterpret_cast(payload), length)) - , _accessControlList(acl) + , _accessControlList(nullptr) , _servicePrefix(servicePrefix) { if (_context.FromString(_token) == false) { _context.URL = _token; } + + } /* virtual */ SecurityContext::~SecurityContext() @@ -67,13 +69,13 @@ namespace Plugin { } //! Allow a websocket upgrade to be checked if it is allowed to be opened. - bool SecurityContext::Allowed(const string& path) const /* override */ + bool SecurityContext::Allowed(const string&) const /* override */ { return (true); } //! Allow a request to be checked before it is offered for processing. - bool SecurityContext::Allowed(const Web::Request& request) const /* override */ + bool SecurityContext::Allowed(const Web::Request& request) const /* override */ { string callsign = ""; string method = ""; @@ -98,9 +100,8 @@ namespace Plugin { bool SecurityContext::Allowed(const Core::JSONRPC::Message& message) const /* override */ { bool bAllowed = ((_accessControlList != nullptr) && (_accessControlList->Allowed(_context.URL.Value(), message.Callsign(), message.Method()))); - if(!bAllowed) - SYSLOG(Logging::Notification, ("Thunder Access Blocked:%s,%s,%s", _context.URL.Value().c_str(),message.Callsign().c_str(),message.Method().c_str())); - + if (!bAllowed) + TRACE(Security, ("Thunder Access Blocked:%s,%s,%s", _context.URL.Value().c_str(),message.Callsign().c_str(),message.Method().c_str())); return bAllowed; } diff --git a/SecurityAgent/Tracing.h b/SecurityAgent/Tracing.h new file mode 100644 index 0000000000..c654f31faf --- /dev/null +++ b/SecurityAgent/Tracing.h @@ -0,0 +1,33 @@ +#pragma once + +namespace WPEFramework { +namespace Plugin { + class Security { + public: + Security() = delete; + Security(const Security& a_Copy) = delete; + Security& operator=(const Security& a_RHS) = delete; + + public: + Security(const TCHAR formatter[], ...) + { + va_list ap; + va_start(ap, formatter); + Core::Format(_text, formatter, ap); + va_end(ap); + } + explicit Security(const string& text) + : _text(Core::ToString(text)) + { + } + ~Security() = default; + + public: + inline const char* Data() const { return (_text.c_str()); } + inline uint16_t Length() const { return (static_cast(_text.length())); } + + private: + std::string _text; + }; +} // namespace Plugin +} // namespace WPEFramework diff --git a/WebBridge/WebBridge.cpp b/WebBridge/WebBridge.cpp index 7166be425d..b8a5764ad3 100644 --- a/WebBridge/WebBridge.cpp +++ b/WebBridge/WebBridge.cpp @@ -25,324 +25,522 @@ namespace WPEFramework { -namespace { - - static Plugin::Metadata metadata( - // Version (Major, Minor, Patch) - API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH, - // Preconditions - {}, - // Terminations - {}, - // Controls - {} - ); -} - -namespace Plugin { - - SERVICE_REGISTRATION(WebBridge, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); - - class EXTERNAL Registration : public Core::JSON::Container { - private: - Registration(const Registration&) = delete; - Registration& operator=(const Registration&) = delete; - - public: - Registration() - : Core::JSON::Container() - , Event() - , Callsign() - { - Add(_T("event"), &Event); - Add(_T("id"), &Callsign); +ENUM_CONVERSION_BEGIN(Plugin::WebBridge::context) + + { Plugin::WebBridge::context::NONE, _TXT("none") }, + { Plugin::WebBridge::context::ADDED, _TXT("added") }, + { Plugin::WebBridge::context::WRAPPED, _TXT("wrapped") }, + +ENUM_CONVERSION_END(Plugin::WebBridge::context); + + namespace Plugin { + + namespace { + + static Metadata metadata( + // Version (Major, Minor, Patch) + API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH, + // Preconditions + {}, + // Terminations + {}, + // Controls + {} + ); } - ~Registration() + + SERVICE_REGISTRATION(WebBridge, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH) + + class EXTERNAL Registration : public Core::JSON::Container { + public: + Registration(Registration&&) = delete; + Registration(const Registration&) = delete; + Registration& operator=(const Registration&) = delete; + + Registration() + : Core::JSON::Container() + , Event() + , Callsign() + { + Add(_T("event"), &Event); + Add(_T("id"), &Callsign); + } + ~Registration() override = default; + + public: + Core::JSON::String Event; + Core::JSON::String Callsign; + }; + class Message : public Core::JSONRPC::Message { + public: + class CallContext : public Core::JSON::Container { + public: + CallContext(CallContext&&) = delete; + CallContext(const CallContext&) = delete; + CallContext& operator= (const CallContext&) = delete; + + CallContext() + : Core::JSON::Container() + , Callsign() + , ChannelId(0) + , Token() + , OriginalId(0) { + Add(_T("callsign"), &Callsign); + Add(_T("channel"), &ChannelId); + Add(_T("token"), &Token); + Add(_T("id"), &OriginalId); + } + ~CallContext() override = default; + + void Clear() { + Callsign.Clear(); + ChannelId.Clear(); + Token.Clear(); + OriginalId.Clear(); + } + + public: + Core::JSON::String Callsign; + Core::JSON::DecUInt32 ChannelId; + Core::JSON::String Token; + Core::JSON::DecUInt32 OriginalId; + }; + + public: + Message(Message&&) = delete; + Message(const Message&) = delete; + Message& operator= (const Message&) = delete; + + Message() + : Core::JSONRPC::Message() { + Add(_T("context"), &Context); + Add(_T("request"), &Request); + Add(_T("response"), &Response); + + Core::JSONRPC::Message::JSONRPC.Clear(); + Request.JSONRPC.Clear(); + Response.JSONRPC.Clear(); + } + ~Message() override = default; + + void Clear() + { + Request.Id.Clear(); + Request.Designator.Clear(); + Request.Parameters.Clear(); + Request.Result.Clear(); + Request.Error.Clear(); + Request.JSONRPC.Clear(); + + Response.Id.Clear(); + Response.Designator.Clear(); + Response.Parameters.Clear(); + Response.Result.Clear(); + Response.Error.Clear(); + Response.JSONRPC.Clear(); + + Context.Clear(); + + Core::JSONRPC::Message::Id.Clear(); + Core::JSONRPC::Message::Designator.Clear(); + Core::JSONRPC::Message::Parameters.Clear(); + Core::JSONRPC::Message::Result.Clear(); + Core::JSONRPC::Message::Error.Clear(); + Core::JSONRPC::Message::JSONRPC.Clear(); + } + + public: + CallContext Context; + Core::JSONRPC::Message Request; + Core::JSONRPC::Message Response; + }; + + static Core::ProxyPoolType g_BridgeMessages(8); + + // ------------------------------------------------------------------------------------------------------- + // IPluginExtended methods + // ------------------------------------------------------------------------------------------------------- + const string WebBridge::Initialize(PluginHost::IShell* service) /* override */ { - } + ASSERT(_service == nullptr); + ASSERT(service != nullptr); - public: - Core::JSON::String Event; - Core::JSON::String Callsign; - }; - - // ------------------------------------------------------------------------------------------------------- - // IPluginExtended methods - // ------------------------------------------------------------------------------------------------------- - const string WebBridge::Initialize(PluginHost::IShell* service) /* override */ - { - ASSERT(_service == nullptr); - ASSERT(service != nullptr); - - string message; - - Config config; - config.FromString(service->ConfigLine()); - _skipURL = static_cast(service->WebPrefix().length()); - _callsign = service->Callsign(); - _service = service; - _timeOut = (config.TimeOut.Value() * Core::Time::TicksPerMillisecond); - - // On success return empty, to indicate there is no error text. - return (message); - } - - void WebBridge::Deinitialize(PluginHost::IShell* service) /* override */ - { - ASSERT(_service == service); - - _service = nullptr; - } - - string WebBridge::Information() const /* override */ - { - // No additional info to report. - return (string()); - } - - bool WebBridge::Attach(PluginHost::Channel& channel) /* override */ { - bool assigned = false; - - // The expectation is that the JavaScript service opens up a connection to us, so we can forward the - // incomming requests, to be handled by the Service. - if ((channel.Protocol() == _T("json")) && (_javascriptService == 0)) { - _javascriptService = channel.Id(); - assigned = true; - } - return(assigned); - } - - void WebBridge::Detach(PluginHost::Channel& channel) /* override */ { - // Hopefull this does not happen as than we are loosing the actual service :-) We could do proper error handling - // if this happens :-) - _javascriptService = 0; - } - - // ------------------------------------------------------------------------------------------------------- - // IDispatcher methods - // ------------------------------------------------------------------------------------------------------- - Core::ProxyType WebBridge::Invoke(const string& token, const uint32_t channelId, const Core::JSONRPC::Message& inbound) /* override */ - { - string method; - Registration info; - - Core::ProxyType message(PluginHost::IFactories::Instance().JSONRPC()); - string designator(inbound.Designator.Value()); - - if (inbound.Id.IsSet() == true) { - message->JSONRPC = Core::JSONRPC::Message::DefaultVersion; - message->Id = inbound.Id.Value(); - } + string message; - switch (Destination(designator, method)) { - case state::STATE_INCORRECT_HANDLER: - message->Error.SetError(Core::ERROR_INVALID_DESIGNATOR); - message->Error.Text = _T("Destined invoke failed."); - break; - case state::STATE_INCORRECT_VERSION: - message->Error.SetError(Core::ERROR_INVALID_SIGNATURE); - message->Error.Text = _T("Requested version is not supported."); - break; - case state::STATE_UNKNOWN_METHOD: - message->Error.SetError(Core::ERROR_UNKNOWN_KEY); - message->Error.Text = _T("Unknown method."); - break; - case state::STATE_REGISTRATION: - info.FromString(inbound.Parameters.Value()); - Subscribe(channelId, info.Event.Value(), info.Callsign.Value(), *message); - break; - case state::STATE_UNREGISTRATION: - info.FromString(inbound.Parameters.Value()); - Unsubscribe(channelId, info.Event.Value(), info.Callsign.Value(), *message); - break; - case state::STATE_EXISTS: - message->Result = Core::NumberType(Core::ERROR_UNKNOWN_KEY).Text(); - break; - case state::STATE_NONE_EXISTING: - message->Result = Core::NumberType(Core::ERROR_NONE).Text(); - break; - case state::STATE_CUSTOM: - // Let's on behalf of the request forward it and update - uint32_t newId = Core::InterlockedIncrement(_sequenceId); - Core::Time waitTill = Core::Time::Now() + _timeOut; - - _pendingRequests.emplace(std::piecewise_construct, - std::forward_as_tuple(newId), - std::forward_as_tuple(channelId, message->Id.Value(), waitTill)); - - message->Id = newId; - message->Parameters = inbound.Parameters; - message->Designator = inbound.Designator; - - TRACE(Trace::Information, (_T("Request: [%d] from [%d], method: [%s]"), message->Id.Value(), channelId, method.c_str())); - - _service->Submit(_javascriptService, Core::ProxyType(message)); - - // Wait for ID to return, we can not report anything back yet... - message.Release(); - - if (_timeOut != 0) { - _cleaner.Schedule(waitTill); + Config config; + config.FromString(service->ConfigLine()); + _skipURL = static_cast(service->WebPrefix().length()); + _callsign = service->Callsign(); + _service = service; + _service->AddRef(); + + _mode = config.Context.Value(); + _timeOut = (config.TimeOut.Value() * Core::Time::TicksPerMillisecond); + +#ifndef USE_THUNDER_R4 + if (message.length() != 0) { + Deinitialize(service); } +#endif - break; + // On success return empty, to indicate there is no error text. + return (message); } - return message; - } - - void WebBridge::Activate(PluginHost::IShell* /* service */) /* override */ { - // We did what we needed to do in the Intialize. - } + void WebBridge::Deinitialize(PluginHost::IShell* service) /* override */ + { + if (_service != nullptr) { + ASSERT(_service == service); - void WebBridge::Deactivate() /* override */ { - // We did what we needed to do in the Deintialize. - } + _service->Release(); + _service = nullptr; + } + } - // ------------------------------------------------------------------------------------------------------- - // IWebSocket methods - // ------------------------------------------------------------------------------------------------------- - Core::ProxyType WebBridge::Inbound(const string& /* identifier */) /* override */{ - // There is a message coming in over the JSON WebSocket path!, give it storage space.. - return (Core::ProxyType(PluginHost::IFactories::Instance().JSONRPC())); - } + string WebBridge::Information() const /* override */ + { + // No additional info to report. + return (string()); + } - Core::ProxyType WebBridge::Inbound(const uint32_t ID, const Core::ProxyType& element) /* override */ { + bool WebBridge::Attach(PluginHost::Channel& channel) /* override */ { + bool assigned = false; - Core::ProxyType message(element); + // The expectation is that the JavaScript service opens up a connection to us, so we can forward the + // incomming requests, to be handled by the Service. + if (_javascriptService == 0) { + Web::ProtocolsArray protocols = channel.Protocols(); + if (std::find(protocols.begin(), protocols.end(), string(_T("json"))) != protocols.end()) { + _javascriptService = channel.Id(); + assigned = true; + } + } + return(assigned); + } - ASSERT(message.IsValid() == true); + void WebBridge::Detach(PluginHost::Channel& channel) /* override */ { + // Hopefull this does not happen as than we are loosing the actual service :-) We could do proper error handling + // if this happens :-) + _javascriptService = 0; + } - if (message.IsValid()) { + // ------------------------------------------------------------------------------------------------------- + // IDispatcher methods + // ------------------------------------------------------------------------------------------------------- +#ifndef USE_THUNDER_R4 + Core::ProxyType WebBridge::Invoke(const string& token, const uint32_t channelId, const Core::JSONRPC::Message& inbound) /* override */ + { + string method; + Registration info; - if (message->Id.IsSet() == false) { + Core::ProxyType message(PluginHost::IFactories::Instance().JSONRPC()); + string designator(inbound.Designator.Value()); - string eventName(message->Method()); + if (inbound.Id.IsSet() == true) { + message->JSONRPC = Core::JSONRPC::Message::DefaultVersion; + message->Id = inbound.Id.Value(); + } - // Check for control messages between server and us.. - if (InternalMessage(message) == false) { + switch (Destination(designator, method)) { + case state::STATE_INCORRECT_HANDLER: + message->Error.SetError(Core::ERROR_INVALID_DESIGNATOR); + message->Error.Text = _T("Destined invoke failed."); + break; + case state::STATE_INCORRECT_VERSION: + message->Error.SetError(Core::ERROR_INVALID_SIGNATURE); + message->Error.Text = _T("Requested version is not supported."); + break; + case state::STATE_UNKNOWN_METHOD: + message->Error.SetError(Core::ERROR_UNKNOWN_KEY); + message->Error.Text = _T("Unknown method."); + break; + case state::STATE_REGISTRATION: + info.FromString(inbound.Parameters.Value()); + Subscribe(channelId, info.Event.Value(), info.Callsign.Value(), *message); + break; + case state::STATE_UNREGISTRATION: + info.FromString(inbound.Parameters.Value()); + Unsubscribe(channelId, info.Event.Value(), info.Callsign.Value(), *message); + break; + case state::STATE_EXISTS: + message->Result = Core::NumberType(Core::ERROR_UNKNOWN_KEY).Text(); + break; + case state::STATE_NONE_EXISTING: + message->Result = Core::NumberType(Core::ERROR_NONE).Text(); + break; + case state::STATE_CUSTOM: + // Let's on behalf of the request forward it and update + uint32_t newId = Core::InterlockedIncrement(_sequenceId); + Core::Time waitTill = Core::Time::Now() + _timeOut; + + _pendingRequests.emplace(std::piecewise_construct, + std::forward_as_tuple(newId), + std::forward_as_tuple(channelId, message->Id.Value(), waitTill)); + + message->Id = newId; + message->Parameters = inbound.Parameters; + message->Designator = inbound.Designator; + + TRACE(Trace::Information, (_T("Request: [%d] from [%d], method: [%s]"), message->Id.Value(), channelId, method.c_str())); + + _service->Submit(_javascriptService, Core::ProxyType(message)); + + // Wait for ID to return, we can not report anything back yet... + message.Release(); + + if (_timeOut != 0) { + _cleaner.Schedule(waitTill); + } - // This is an event, we need event handling.. - _adminLock.Lock(); + break; + } - ObserverMap::iterator index = _observers.find(eventName); + return message; + } - if (index != _observers.end()) { - for (const Observer& entry : index->second) { - Core::ProxyType outbound(PluginHost::IFactories::Instance().JSONRPC()); - outbound->Designator = (entry.Designator().empty() == false ? entry.Designator() + '.' + eventName : eventName); - outbound->Parameters = message->Parameters.Value(); + void WebBridge::Activate(PluginHost::IShell* /* service */) /* override */ { + // We did what we needed to do in the Intialize. + } - _service->Submit(entry.Id(), Core::ProxyType(outbound)); - } - } + void WebBridge::Deactivate() /* override */ { + // We did what we needed to do in the Deintialize. + } +#else + Core::hresult + WebBridge::Invoke( + IDispatcher::ICallback* callback, + const uint32_t channelId, + const uint32_t id, + const string& token, + const string& method, + const string& parameters, + string& response) /* override */ + { + uint32_t result(Core::ERROR_BAD_REQUEST); + Core::JSONRPC::Handler* handler(PluginHost::JSONRPC::Handler(method)); + string realMethod(Core::JSONRPC::Message::Method(method)); - _adminLock.Unlock(); - } + if (handler == nullptr) { + result = Core::ERROR_INVALID_RANGE; + } + else if (realMethod == _T("exists")) { + result = Core::ERROR_NONE; + if (handler->Exists(realMethod) == Core::ERROR_NONE) { + response = _T("1"); + } + else { + response = _T("0"); + } } - else { - uint32_t requestId, channelId = 0; - - // This is the response to an invoked method, Let's see who should get this repsonse :-) - _adminLock.Lock(); - PendingMap::iterator index = _pendingRequests.find(message->Id.Value()); - if (index != _pendingRequests.end()) { - channelId = index->second.ChannelId(); - requestId = index->second.SequenceId(); - _pendingRequests.erase(index); + else if (handler->Exists(realMethod) == Core::ERROR_NONE) { + + // Let's on behalf of the request forward it and update + string messageToSend(parameters); + Core::ProxyType message(g_BridgeMessages.Element()); + uint32_t newId = Core::_InterlockedIncrement(_sequenceId); + Core::Time waitTill = Core::Time::Now() + _timeOut; + + _pendingRequests.emplace(std::piecewise_construct, + std::forward_as_tuple(newId), + std::forward_as_tuple(callback, channelId, id, waitTill)); + + switch (_mode) { + case WebBridge::context::ADDED: { + message->Context.ChannelId = channelId; + message->Context.OriginalId = id; + message->Context.Token = token; + message->Context.Callsign = _callsign; + } + case WebBridge::context::NONE: { + break; } - _adminLock.Unlock(); + case WebBridge::context::WRAPPED: { + Message wrapper; + + wrapper.Context.ChannelId = channelId; + wrapper.Context.OriginalId = id; + wrapper.Context.Token = token; + wrapper.Parameters = parameters; + wrapper.ToString(messageToSend); + break; + } + } + + message->Id = newId; + message->Parameters = messageToSend; + message->Designator = method; + + TRACE(Trace::Information, (_T("Request: [%d] from [%d], method: [%s]"), newId, channelId, method.c_str())); - if (channelId != 0) { - TRACE(Trace::Information, (_T("Response: [%d] to [%d]"), requestId, channelId)); + _service->Submit(_javascriptService, Core::ProxyType(message)); - // Oke, there is someone waiting for a response! - message->Id = requestId; + // Wait for ID to return, we can not report anything back yet... + message.Release(); + + if (_timeOut != 0) { #ifndef USE_THUNDER_R4 - _service->Submit(channelId, Core::proxy_cast(message)); + _cleaner.Schedule(waitTill); #else - _service->Submit(channelId, Core::ProxyType(message)); -#endif /* USE_THUNDER_R4 */ + _cleaner.Reschedule(waitTill); +#endif } + + result = ~0; // No resposne to report yet.... } + + return (result); } + Core::hresult WebBridge::Revoke(ICallback* callback) /* override*/ { + // Remove the interface from the pendings.. + _adminLock.Lock(); - // We will never report anything back here :-) - return (Core::ProxyType()); - } - - // ------------------------------------------------------------------------------------------------------- - // Private methods - // ------------------------------------------------------------------------------------------------------- - void WebBridge::Cleanup() { - // Lets see if there are still any pending request we should report Missing In Action :-) - Core::Time now (Core::Time::Now()); - Core::Time nextSlot; - - _adminLock.Lock(); - PendingMap::iterator index(_pendingRequests.begin()); - while (index != _pendingRequests.end()) { - if (now >= index->second.Issued()) { - // Send and Error to the requester.. - Core::ProxyType message(PluginHost::IFactories::Instance().JSONRPC()); - message->Error.SetError(Core::ERROR_TIMEDOUT); - message->Error.Text = _T("There is no response form the server within time!!!"); - message->Id = index->second.SequenceId(); - - TRACE(Trace::Warning, (_T("Got a timeout on channelId [%d] for request [%d]"), index->second.ChannelId(), message->Id.Value())); - - _service->Submit(index->second.ChannelId(), Core::ProxyType(message)); - index = _pendingRequests.erase(index); - } - else { - if ((nextSlot.IsValid() == false) || (nextSlot > index->second.Issued())) { - nextSlot = index->second.Issued(); + PendingMap::iterator index = _pendingRequests.begin(); + + while (index != _pendingRequests.end()) { + if (index->second != callback) { + index++; + } + else { + index = _pendingRequests.erase(index); } - index++; } + + _adminLock.Lock(); + + return (PluginHost::JSONRPC::Revoke(callback)); } - _adminLock.Unlock(); - if (nextSlot.IsValid()) { - _cleaner.Schedule(nextSlot); +#endif + // ------------------------------------------------------------------------------------------------------- + // IWebSocket methods + // ------------------------------------------------------------------------------------------------------- + Core::ProxyType WebBridge::Inbound(const string& /* identifier */) /* override */ { + // There is a message coming in over the JSON WebSocket path!, give it storage space.. + return (Core::ProxyType(PluginHost::IFactories::Instance().JSONRPC())); } - } - bool WebBridge::InternalMessage(const Core::ProxyType& message) { - bool result = false; + Core::ProxyType WebBridge::Inbound(const uint32_t ID, const Core::ProxyType& element) /* override */ { + + Core::ProxyType message(element); + + ASSERT(message.IsValid() == true); + + if (message.IsValid()) { + + if (message->Id.IsSet() == false) { + + string eventName(message->Method()); + + // Check for control messages between server and us.. + if (InternalMessage(message) == false) { + + // This is an event, we need event handling.. + PluginHost::JSONRPC::Event(eventName, message->Parameters.Value()); + } + } + else { + // This is the response to an invoked method, Let's see who should get this repsonse :-) + _adminLock.Lock(); + PendingMap::iterator index = _pendingRequests.find(message->Id.Value()); + if (index != _pendingRequests.end()) { + uint32_t requestId, channelId; + IDispatcher::ICallback* callback; + + channelId = index->second.ChannelId(); + requestId = index->second.SequenceId(); + callback = index->second.Callback(); + + ASSERT(callback != nullptr); - string eventName(message->Method()); + TRACE(Trace::Information, (_T("Response: [%d] to [%d]"), requestId, channelId)); - if (eventName == "registerjsonrpcmethods") { - result = true; - Core::JSON::ArrayType parameter; - parameter.FromString(message->Parameters.Value()); - Core::JSON::ArrayType::Iterator index(parameter.Elements()); +#ifndef USE_THUNDER_R4 - _supportedVersions.clear(); + // Oke, there is someone waiting for a response! + message->Id = requestId; + _service->Submit(channelId, Core::proxy_cast(message)); +#else + if (callback != nullptr) { + // Oke, there is someone waiting for a response! + callback->Response(channelId, requestId, message->Result.Value()); + callback->Release(); + } - while (index.Next() == true) { - string entry = index.Current().Value(); - uint8_t version = Core::JSONRPC::Message::Version(entry); - string method = Core::JSONRPC::Message::Method(entry); - VersionMap::iterator placement = _supportedVersions.find(version); +#endif /* USE_THUNDER_R4 */ + _pendingRequests.erase(index); + } + _adminLock.Unlock(); + } + } + + // We will never report anything back here :-) + return (Core::ProxyType()); + } - if (placement == _supportedVersions.end()) { - auto newEntry = _supportedVersions.emplace(std::piecewise_construct, - std::forward_as_tuple(version), - std::forward_as_tuple()); + // ------------------------------------------------------------------------------------------------------- + // Private methods + // ------------------------------------------------------------------------------------------------------- + void WebBridge::Dispatch() { + // Lets see if there are still any pending request we should report Missing In Action :-) + Core::Time now(Core::Time::Now()); + Core::Time nextSlot; + + _adminLock.Lock(); + PendingMap::iterator index(_pendingRequests.begin()); + while (index != _pendingRequests.end()) { + if (now >= index->second.Issued()) { + // Send and Error to the requester.. + IDispatcher::ICallback* callback = index->second.Callback(); + + ASSERT(callback != nullptr); + + if (callback != nullptr) { + callback->Error(index->second.ChannelId(), index->second.SequenceId(), Core::ERROR_TIMEDOUT, _T("There is no response form the server within time!!!")); + callback->Release(); + } + + TRACE(Trace::Warning, (_T("Got a timeout on channelId [%d] for request [%d]"), index->second.ChannelId(), index->second.SequenceId())); - newEntry.first->second.push_back(method); + index = _pendingRequests.erase(index); } - else if (std::find(placement->second.begin(), placement->second.end(), method) == placement->second.end()) { - // Check if this label does not already exist - placement->second.push_back(method); + else { + if ((nextSlot.IsValid() == false) || (nextSlot > index->second.Issued())) { + nextSlot = index->second.Issued(); + } + index++; } } + _adminLock.Unlock(); + + if (nextSlot.IsValid()) { +#ifndef USE_THUNDER_R4 + _cleaner.Schedule(nextSlot); +#else + _cleaner.Reschedule(nextSlot); +#endif + } } - return (result); - } + bool WebBridge::InternalMessage(const Core::ProxyType& message) { + bool result = false; + + string eventName(message->Method()); + + if (eventName == "registerjsonrpcmethods") { + result = true; + Core::JSON::ArrayType parameter; + parameter.FromString(message->Parameters.Value()); + Core::JSON::ArrayType::Iterator index(parameter.Elements()); + + while (index.Next() == true) { + string entry = index.Current().Value(); + + PluginHost::JSONRPC::RegisterMethod(Core::JSONRPC::Message::Version(entry), Core::JSONRPC::Message::Method(entry)); + } + } + + return (result); + } -} // namespace Plugin + } // namespace Plugin } // namespace WPEFramework diff --git a/WebBridge/WebBridge.h b/WebBridge/WebBridge.h index 51a5fa15ec..9af52ff772 100644 --- a/WebBridge/WebBridge.h +++ b/WebBridge/WebBridge.h @@ -22,328 +22,188 @@ #include "Module.h" namespace WPEFramework { -namespace Plugin { + namespace Plugin { - class WebBridge : - public PluginHost::IPluginExtended, - public PluginHost::IDispatcher, - public PluginHost::IWebSocket - { - private: - enum class state { - STATE_INCORRECT_HANDLER, - STATE_INCORRECT_VERSION, - STATE_UNKNOWN_METHOD, - STATE_REGISTRATION, - STATE_UNREGISTRATION, - STATE_EXISTS, - STATE_NONE_EXISTING, - STATE_CUSTOM - }; - class Observer { - public: - Observer(const Observer&) = delete; - Observer& operator=(const Observer&) = delete; - - Observer(const uint32_t id, const string& designator) - : _id(id) - , _designator(designator) - { - } - ~Observer() = default; - - public: - bool operator==(const Observer& rhs) const - { - return ((rhs._id == _id) && (rhs._designator == _designator)); - } - bool operator!=(const Observer& rhs) const - { - return (!operator==(rhs)); - } - - uint32_t Id() const - { - return (_id); - } - const string& Designator() const - { - return (_designator); - } - - private: - uint32_t _id; - string _designator; - }; - class Request { - public: - Request() = delete; - Request(const Request&) = delete; - Request& operator=(const Request&) = delete; - - Request(const uint32_t channelId, const uint32_t sequenceId, const Core::Time& timeOut) - : _channelId(channelId) - , _sequenceId(sequenceId) - , _issued(timeOut) { - } - ~Request() = default; - - public: - uint32_t ChannelId() const { - return (_channelId); - } - uint32_t SequenceId() const { - return (_sequenceId); - } - const Core::Time& Issued() const { - return (_issued); - } - - private: - uint32_t _channelId; - uint32_t _sequenceId; - Core::Time _issued; - }; - class Cleaner { + class WebBridge : + public PluginHost::IPluginExtended, + public PluginHost::IDispatcher, + public PluginHost::IWebSocket, + { private: - using BaseClass = Core::IWorkerPool::JobType; + enum class state { + STATE_INCORRECT_HANDLER, + STATE_INCORRECT_VERSION, + STATE_UNKNOWN_METHOD, + STATE_REGISTRATION, + STATE_UNREGISTRATION, + STATE_EXISTS, + STATE_NONE_EXISTING, + STATE_CUSTOM + }; + class Request { + public: + Request() = delete; + Request(Request&&) = delete; + Request(const Request&) = delete; + Request& operator=(const Request&) = delete; + + Request(IDispatcher::ICallback* callback, const uint32_t channelId, const uint32_t sequenceId, const Core::Time& timeOut) + : _callback(callback) + , _channelId(channelId) + , _sequenceId(sequenceId) + , _issued(timeOut) { + _callback->AddRef(); + } + ~Request() { + ASSERT(_callback != nullptr); + _callback->Release(); + _callback = nullptr; + } + bool operator== (const IDispatcher::ICallback* callback) const { + return (_callback == callback); + } + bool operator!= (const IDispatcher::ICallback* callback) const { + return (!operator==(callback)); + } - public: - Cleaner(const Cleaner&) = delete; - Cleaner& operator=(const Cleaner&) = delete; + public: + IDispatcher::ICallback* Callback() { + _callback->AddRef(); + return (_callback); + } + uint32_t ChannelId() const { + return (_channelId); + } + uint32_t SequenceId() const { + return (_sequenceId); + } + const Core::Time& Issued() const { + return (_issued); + } - Cleaner(WebBridge& parent) : _parent(parent) { - } - ~Cleaner() = default; + private: + IDispatcher::ICallback* _callback; + uint32_t _channelId; + uint32_t _sequenceId; + Core::Time _issued; + }; + using PendingMap = std::unordered_map; public: - void Dispatch() { - _parent.Cleanup(); - } - - private: - WebBridge& _parent; - }; + enum context : uint8_t { + NONE, + ADDED, + WRAPPED + }; + class Config : public Core::JSON::Container { + public: + Config(Config&&) = delete; + Config(const Config&) = delete; + Config& operator= (const Config&) = delete; + + Config() + : Core::JSON::Container() + , TimeOut(3000) + , Context(context::NONE) + { + Add(_T("timeout"), &TimeOut); + Add(_T("context"), &Context); + } + ~Config() override = default; - using ObserverList = std::list; - using ObserverMap = std::map; - using MethodList = std::vector; - using VersionMap = std::map; - using PendingMap = std::map; + public: + Core::JSON::DecUInt16 TimeOut; + Core::JSON::EnumType Context; + }; - public: - class Config : public Core::JSON::Container { public: - Config() - : Core::JSON::Container() - , TimeOut(3000) + WebBridge(WebBridge&&) = delete; + WebBridge(const WebBridge&) = delete; + WebBridge& operator=(const WebBridge&) = delete; + + #ifdef __WINDOWS__ + #pragma warning(disable: 4355) + #endif + WebBridge() + : _adminLock() + , _skipURL(0) + , _mode(context::NONE) + , _service(nullptr) + , _callsign() + , _pendingRequests() + , _javascriptService(0) + , _sequenceId(1) + , _timeOut(0) + , _cleaner(*this) { - Add(_T("timeout"), &TimeOut); - } - ~Config() override = default; + } + #ifdef __WINDOWS__ + #pragma warning(default: 4355) + #endif + ~WebBridge() override = default; + + BEGIN_INTERFACE_MAP(WebBridge) + INTERFACE_ENTRY(PluginHost::IPlugin) + INTERFACE_ENTRY(PluginHost::IPluginExtended) + INTERFACE_ENTRY(PluginHost::IWebSocket) + INTERFACE_ENTRY(PluginHost::IDispatcher) + END_INTERFACE_MAP public: - Core::JSON::String Bind; - Core::JSON::DecUInt16 TimeOut; - }; - - public: - WebBridge(const WebBridge&) = delete; - WebBridge& operator=(const WebBridge&) = delete; + // IPlugin methods + // ------------------------------------------------------------------------------------------------------- + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + const string Initialize(PluginHost::IShell* service) override; + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + void Deinitialize(PluginHost::IShell* service) override; + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + string Information() const override; + + // IDispatcher (override message) + // ------------------------------------------------------------------------------------------------------- +#fndef USE_THUNDER_R4 + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + Core::ProxyType Invoke(const string& token, const uint32_t channelId, const Core::JSONRPC::Message& message) override; + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + void Activate(PluginHost::IShell* service) override; + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + void Deactivate() override; +#else + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + Core::hresult Invoke(const uint32_t channelId, const uint32_t id, const string& token, const string& method, const string& parameters, string& response) override; + Core::hresult Revoke(ICallback* callback) override; +#endif + // IPluginExtended + // ------------------------------------------------------------------------------------------------------- + //! ================================== CALLED ON COMMUNICATION THREAD ===================================== + bool Attach(PluginHost::Channel& channel) override; + //! ================================== CALLED ON COMMUNICATION THREAD ===================================== + void Detach(PluginHost::Channel& channel) override; + + // IWebSocket + // ------------------------------------------------------------------------------------------------------- + //! ================================== CALLED ON COMMUNICATION THREAD ===================================== + Core::ProxyType Inbound(const string& identifier) override; + //! ==================================== CALLED ON THREADPOOL THREAD ====================================== + Core::ProxyType Inbound(const uint32_t ID, const Core::ProxyType& element) override; - #ifdef __WINDOWS__ - #pragma warning(disable: 4355) - #endif - WebBridge() - : _adminLock() - , _skipURL(0) - , _service(nullptr) - , _callsign() - , _supportedVersions() - , _observers() - , _pendingRequests() - , _javascriptService(0) - , _sequenceId(1) - , _timeOut(0) - , _cleaner(*this) - { - } - #ifdef __WINDOWS__ - #pragma warning(default: 4355) - #endif - ~WebBridge() override = default; - - BEGIN_INTERFACE_MAP(WebBridge) - INTERFACE_ENTRY(PluginHost::IPlugin) - INTERFACE_ENTRY(PluginHost::IPluginExtended) - INTERFACE_ENTRY(PluginHost::IWebSocket) - INTERFACE_ENTRY(PluginHost::IDispatcher) - END_INTERFACE_MAP - - public: - // IPlugin methods - // ------------------------------------------------------------------------------------------------------- - //! ==================================== CALLED ON THREADPOOL THREAD ====================================== - const string Initialize(PluginHost::IShell* service) override; - //! ==================================== CALLED ON THREADPOOL THREAD ====================================== - void Deinitialize(PluginHost::IShell* service) override; - //! ==================================== CALLED ON THREADPOOL THREAD ====================================== - string Information() const override; - - // IDispatcher - // ------------------------------------------------------------------------------------------------------- - //! ==================================== CALLED ON THREADPOOL THREAD ====================================== - Core::ProxyType Invoke(const string& token, const uint32_t channelId, const Core::JSONRPC::Message& message) override; - //! ==================================== CALLED ON THREADPOOL THREAD ====================================== - void Activate(PluginHost::IShell* service) override; - //! ==================================== CALLED ON THREADPOOL THREAD ====================================== - void Deactivate() override; - - // IPluginExtended - // ------------------------------------------------------------------------------------------------------- - //! ================================== CALLED ON COMMUNICATION THREAD ===================================== - bool Attach(PluginHost::Channel& channel) override; - //! ================================== CALLED ON COMMUNICATION THREAD ===================================== - void Detach(PluginHost::Channel& channel) override; - - // IWebSocket - // ------------------------------------------------------------------------------------------------------- - //! ================================== CALLED ON COMMUNICATION THREAD ===================================== - Core::ProxyType Inbound(const string& identifier) override; - //! ==================================== CALLED ON THREADPOOL THREAD ====================================== - Core::ProxyType Inbound(const uint32_t ID, const Core::ProxyType& element) override; - - - private: - void Cleanup(); - bool InternalMessage(const Core::ProxyType& message); - - bool HasMethodSupport(const VersionMap::const_iterator& index, const string& method) const { - bool result = false; - - if (index != _supportedVersions.cend()) { - result = (std::find(index->second.cbegin(), index->second.cend(), method) != index->second.cend()); - } - else { - VersionMap::const_iterator index = _supportedVersions.begin(); - - while ((result == false) && (index != _supportedVersions.end())) { - result = (std::find(index->second.cbegin(), index->second.cend(), method) != index->second.cend()); - index++; - } - } - - return (result); - } - state Destination(const string& designator, string& handler) const - { - state result = state::STATE_INCORRECT_HANDLER; - string callsign(Core::JSONRPC::Message::Callsign(designator)); - - // If the message is routed through the controlelr, the callsign is empty by now! - if ((callsign.empty()) || (callsign == _callsign)) { - // Seems we are on the right handler.. - // now see if someone supports this version - uint8_t version = Core::JSONRPC::Message::Version(designator); - VersionMap::const_iterator methods = _supportedVersions.cend(); - - // See if there was a version given.. - if (version != static_cast(~0)) { - methods = _supportedVersions.find(version); - if (methods == _supportedVersions.cend()) { - result = state::STATE_INCORRECT_VERSION; - } - } - - if (result == state::STATE_INCORRECT_HANDLER) { - string method = Core::JSONRPC::Message::Method(designator); - - if (method == _T("register")) { - result = state::STATE_REGISTRATION; - } - else if (method == _T("unregister")) { - result = state::STATE_UNREGISTRATION; - } - else if (method == _T("exists")) { - result = HasMethodSupport(methods, method) ? state::STATE_EXISTS : state::STATE_NONE_EXISTING; - } - else if (HasMethodSupport(methods, method) == true) { - result = state::STATE_CUSTOM; - handler = method; - } - else { - result = state::STATE_UNKNOWN_METHOD; - } - } - } - return (result); - } - void Subscribe(const uint32_t channelId, const string& eventName, const string& callsign, Core::JSONRPC::Message& response) - { - _adminLock.Lock(); - - ObserverMap::iterator index = _observers.find(eventName); - - if (index == _observers.end()) { - _observers[eventName].emplace_back(channelId, callsign); - response.Result = _T("0"); - } - else if (std::find(index->second.begin(), index->second.end(), Observer(channelId, callsign)) == index->second.end()) { - index->second.emplace_back(channelId, callsign); - response.Result = _T("0"); - } - else { - response.Error.SetError(Core::ERROR_DUPLICATE_KEY); - response.Error.Text = _T("Duplicate registration. Only 1 remains!!!"); - } - - _adminLock.Unlock(); - } - void Unsubscribe(const uint32_t channelId, const string& eventName, const string& callsign, Core::JSONRPC::Message& response) - { - _adminLock.Lock(); - - ObserverMap::iterator index = _observers.find(eventName); - - if (index != _observers.end()) { - ObserverList& clients = index->second; - ObserverList::iterator loop = clients.begin(); - Observer key(channelId, callsign); - - while ((loop != clients.end()) && (*loop != key)) { - loop++; - } - - if (loop != clients.end()) { - clients.erase(loop); - if (clients.empty() == true) { - _observers.erase(index); - } - response.Result = _T("0"); - } - } - - if (response.Result.IsSet() == false) { - response.Error.SetError(Core::ERROR_UNKNOWN_KEY); - response.Error.Text = _T("Registration not found!!!"); - } - - _adminLock.Unlock(); - } + private: + friend Core::ThreadPool::JobType; + void Dispatch(); + bool InternalMessage(const Core::ProxyType& message); - private: - Core::CriticalSection _adminLock; - uint8_t _skipURL; - PluginHost::IShell* _service; - string _callsign; - VersionMap _supportedVersions; - ObserverMap _observers; - PendingMap _pendingRequests; - uint32_t _javascriptService; - uint32_t _sequenceId; - uint32_t _timeOut; - Core::WorkerPool::JobType _cleaner; - }; + private: + Core::CriticalSection _adminLock; + uint8_t _skipURL; + context _mode; + PluginHost::IShell* _service; + string _callsign; + PendingMap _pendingRequests; + uint32_t _javascriptService; + uint32_t _sequenceId; + uint32_t _timeOut; + Core::WorkerPool::JobType _cleaner; + }; -} // namespace Plugin + } // namespace Plugin } // namespace WPEFramework diff --git a/WebKitBrowser/Amazon.conf.in b/WebKitBrowser/Amazon.conf.in new file mode 100644 index 0000000000..4be53c4f2e --- /dev/null +++ b/WebKitBrowser/Amazon.conf.in @@ -0,0 +1,181 @@ +precondition = ["Internet"] +autostart = "@PLUGIN_AMAZON_AUTOSTART@" +startuporder = "@PLUGIN_AMAZON_STARTUPORDER@" + +configuration = JSON() + +configuration.add("url", "@PLUGIN_AMAZON_STARTURL@") +configuration.add("useragent", "@PLUGIN_AMAZON_USERAGENT@") + +if not boolean("@WEBKIT_GLIB_API@"): + configuration.add("injectedbundle", "libWPEInjectedBundle@CMAKE_SHARED_LIBRARY_SUFFIX@") +else: + configuration.add("extensiondir", "@PLUGIN_WEBKITBROWSER_EXTENSION_DIRECTORY@") + +configuration.add("transparent", "@PLUGIN_AMAZON_TRANSPARENT@") +configuration.add("compositor", "noaa") +configuration.add("inspector", "@PLUGIN_AMAZON_WEBINSPECTOR_ADDRESS@") +configuration.add("fps", "true") +configuration.add("cursor", "false") + +bundle = JSON() +hawaii = JSON() + +hawaii.add("displayWidth", "1280") +hawaii.add("displayHeight", "720") +hawaii.add("panelWidth", "1280") +hawaii.add("panelHeight", "720") +hawaii.add("proxyHost", "None") +hawaii.add("proxyPort", "0") +hawaii.add("proxyUsername", "None") +hawaii.add("proxyPassword", "None") +hawaii.add("bandwidthEstimateFilePath", "/tmp/BandwidthEstimate.txt") + +if "@PLUGIN_AMAZON_CADIRECTORYPATH@" != "": + hawaii.add("CADirectoryPath", "@PLUGIN_AMAZON_CADIRECTORYPATH@") +else: + hawaii.add("CADirectoryPath", "/etc/ssl/certs/") + +if "@PLUGIN_AMAZON_CABUNDLEFILENAME@" != "": + hawaii.add("CABundleFileName", "@PLUGIN_AMAZON_CABUNDLEFILENAME@") +else: + hawaii.add("CABundleFileName", "ca-certificates.crt") + +hawaii.add("supportsSurroundSound", "true") +hawaii.add("supportsAudioCodecSwitching", "true") +hawaii.add("dolbyDigitalAudioPassthroughOnly", "false") +hawaii.add("supportsHEVC", "false") +hawaii.add("supportsHEVC10Bits", "false") +hawaii.add("supportsCVBR", "true") +hawaii.add("supportsIntraChunkSeeking", "false") +hawaii.add("hasExternalOutput", "true") +hawaii.add("hasPlatformVideoNode", "true") +hawaii.add("supportsCompressedContentEncoding", "true") +hawaii.add("supportsHexEncodedManifest", "true") +hawaii.add("hdcpMajorVersion", "2") +hawaii.add("hdcpMinorVersion", "2") +hawaii.add("supportsUHD", "false") +hawaii.add("supportsHDR", "false") +hawaii.add("hdrFlags", "0") +hawaii.add("supportsOLED", "true") + +if "@PLUGIN_AMAZON_MANUFACTURER@" != "": + hawaii.add("manufacturer", "@PLUGIN_AMAZON_MANUFACTURER@") +else: + hawaii.add("manufacturer", "Broadcom") + +if "@PLUGIN_AMAZON_MODELNAME@" != "": + hawaii.add("modelName", "@PLUGIN_AMAZON_MODELNAME@") +else: + hawaii.add("modelName", "2952") + +hawaii.add("platformPackageVersion", "None") +hawaii.add("deviceMode", "None") + +if "@PLUGIN_AMAZON_DEVICELANGUAGE@" != "": + hawaii.add("deviceLanguage", "@PLUGIN_AMAZON_DEVICELANGUAGE@") +else: + hawaii.add("deviceLanguage", "en-US") + +if "@PLUGIN_AMAZON_DEVICETYPEID@" != "": + hawaii.add("deviceTypeId", "@PLUGIN_AMAZON_DEVICETYPEID@") +else: + hawaii.add("deviceTypeId", "A71I8788P1ZV8") + +if "@PLUGIN_AMAZON_FIRMWAREVERSION@" != "": + hawaii.add("firmwareVersion", "@PLUGIN_AMAZON_FIRMWAREVERSION@") +else: + hawaii.add("firmwareVersion", "1.0") + +if "@PLUGIN_AMAZON_CHIPSETNAME@" != "": + hawaii.add("chipsetName", "@PLUGIN_AMAZON_CHIPSETNAME@") +else: + hawaii.add("chipsetName", "BCM2837") + +if "@PLUGIN_AMAZON_ETHERNETDEVICE@" != "": + hawaii.add("ethernetDevice", "@PLUGIN_AMAZON_ETHERNETDEVICE@") +else: + hawaii.add("ethernetDevice", "eth0") + +hawaii.add("wifiDevice", "wlan0") + +if "@PLUGIN_AMAZON_FRAGMENTCACHESIZE@" != "": + hawaii.add("fragmentCacheSizeMB", "@PLUGIN_AMAZON_FRAGMENTCACHESIZE@") +else: + hawaii.add("fragmentCacheSizeMB", "100") + +hawaii.add("updateFrequency", "30") +hawaii.add("fragmentCacheMountPoint", "/tmp/") + +overrideBySystem = JSON() + +if "@PLUGIN_AMAZON_FIRMWAREVERSION@" != "": + overrideBySystem.add("firmwareVersion", "false") +else: + overrideBySystem.add("firmwareVersion", "true") + +if "@PLUGIN_AMAZON_CHIPSETNAME@" != "": + overrideBySystem.add("chipsetName", "false") +else: + overrideBySystem.add("chipsetName", "true") + +overrideBySystem.add("displayResolution", "true") +overrideBySystem.add("panelResolution", "true") +overrideBySystem.add("supportsSurroundSound", "true") +overrideBySystem.add("dolbyDigitalAudioPassthroughOnly", "true") +overrideBySystem.add("supportsUHD", "true") +overrideBySystem.add("supportsHDR", "true") +overrideBySystem.add("supportsOLED", "true") +overrideBySystem.add("supportsHEVC", "true") +overrideBySystem.add("hdcpVersion", "true") + +hawaii.add("overrideBySystem", overrideBySystem) +bundle.add("hawaii", hawaii) +configuration.add("bundle", bundle) + +configuration.add("touch", "false") +configuration.add("msebuffers", "audio:2m,video:15m,text:1m") +configuration.add("thunderdecryptorpreference", "@PLUGIN_WEBKITBROWSER_THUNDER_DECRYPTOR_PREFERENCE@") +configuration.add("memoryprofile", "@PLUGIN_AMAZON_MEMORYPROFILE@") +configuration.add("mediacontenttypesrequiringhardwaresupport", "@PLUGIN_WEBKITBROWSER_MEDIA_CONTENT_TYPES_REQUIRING_HARDWARE_SUPPORT@") +configuration.add("mediadiskcache", "@PLUGIN_WEBKITBROWSER_MEDIADISKCACHE@") +configuration.add("diskcache", "@PLUGIN_WEBKITBROWSER_DISKCACHE@") +configuration.add("xhrcache", "@PLUGIN_WEBKITBROWSER_XHRCACHE@") +configuration.add("webgl", "false") +configuration.add("windowclose", "true") +configuration.add("threadedpainting", "@PLUGIN_WEBKITBROWSER_THREADEDPAINTING@") +configuration.add("clientidentifier", "@PLUGIN_WEBKITBROWSER_CLIENTIDENTIFIER@") +configuration.add("localstorageenabled", "@PLUGIN_AMAZON_LOCALSTORAGE_ENABLE@") +configuration.add("localstorage", "@PLUGIN_WEBKITBROWSER_LOCALSTORAGE@") +configuration.add("cookiestorage", "@PLUGIN_WEBKITBROWSER_COOKIESTORAGE@") +configuration.add("ptsoffset", "@PLUGIN_WEBKITBROWSER_PSTOFFSET@") +configuration.add("execpath", "@PLUGIN_WEBKITBROWSER_ALTERNATIVE_EXEC_PATH@") +configuration.add("proxy", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY@") +configuration.add("proxyexclusion", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY_EXCLUSION@") + +rootobject = JSON() +rootobject.add("mode", "@PLUGIN_AMAZON_MODE@") +rootobject.add("locator", "lib@PLUGIN_WEBKITBROWSER_IMPLEMENTATION@.so") +rootobject.add("user", "@PLUGIN_AMAZON_USER@") +rootobject.add("group", "@PLUGIN_AMAZON_GROUP@") +configuration.add("root", rootobject) + +javascript = JSON() +javascript.add("useJIT", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_JIT@") else "false") +javascript.add("useDFG", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_DFG@") else "false") +configuration.add("javascript", javascript) + +webprocesssettings = JSON() +webprocesssettings.add("limit", "@PLUGIN_AMAZON_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_AMAZON_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_AMAZON_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_AMAZON_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") + +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_AMAZON_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_AMAZON_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") + +memory = JSON() +memory.add("webprocesssettings", webprocesssettings) +memory.add("networkprocesssettings", networkprocesssettings) +configuration.add("memory", memory) diff --git a/WebKitBrowser/Apps.conf.in b/WebKitBrowser/Apps.conf.in new file mode 100644 index 0000000000..d68293d942 --- /dev/null +++ b/WebKitBrowser/Apps.conf.in @@ -0,0 +1,68 @@ +precondition = ["Internet"] +startmode = "@PLUGIN_APPS_STARTMODE@" +startuporder = "@PLUGIN_APPS_STARTUPORDER@" + +configuration = JSON() + +configuration.add("url", "about:blank") +configuration.add("useragent", "@PLUGIN_APPS_USERAGENT@") + +if not boolean("@WEBKIT_GLIB_API@"): + configuration.add("injectedbundle", "libWPEInjectedBundle@CMAKE_SHARED_LIBRARY_SUFFIX@") +else: + configuration.add("extensiondir", "@PLUGIN_WEBKITBROWSER_EXTENSION_DIRECTORY@") + + +configuration.add("transparent", "@PLUGIN_WEBKITBROWSER_TRANSPARENT@") +configuration.add("compositor", "noaa") +configuration.add("inspector", "@PLUGIN_APPS_WEBINSPECTOR_ADDRESS@") +configuration.add("fps", "true") +configuration.add("cursor", "false") +configuration.add("touch", "false") +configuration.add("msebuffers", "@PLUGIN_APPS_MSEBUFFERS@") +configuration.add("thunderdecryptorpreference", "@PLUGIN_WEBKITBROWSER_THUNDER_DECRYPTOR_PREFERENCE@") +configuration.add("memoryprofile", "@PLUGIN_WEBKITBROWSER_MEMORYPROFILE@") +configuration.add("mediacontenttypesrequiringhardwaresupport", "@PLUGIN_WEBKITBROWSER_MEDIA_CONTENT_TYPES_REQUIRING_HARDWARE_SUPPORT@") +configuration.add("mediadiskcache", "@PLUGIN_WEBKITBROWSER_MEDIADISKCACHE@") +configuration.add("diskcache", "@PLUGIN_WEBKITBROWSER_DISKCACHE@") +configuration.add("xhrcache", "@PLUGIN_WEBKITBROWSER_XHRCACHE@") +configuration.add("webgl", "@PLUGIN_APPS_WEBGL@") +configuration.add("threadedpainting", "@PLUGIN_WEBKITBROWSER_THREADEDPAINTING@") +configuration.add("height", "@PLUGIN_WEBKITBROWSER_HEIGHT@") +configuration.add("width", "@PLUGIN_WEBKITBROWSER_WIDTH@") +configuration.add("clientidentifier", "@PLUGIN_WEBKITBROWSER_CLIENTIDENTIFIER@") +configuration.add("localstorageenabled", "@PLUGIN_APPS_LOCALSTORAGE_ENABLE@") +configuration.add("localstorage", "@PLUGIN_WEBKITBROWSER_LOCALSTORAGE@") +configuration.add("cookiestorage", "@PLUGIN_WEBKITBROWSER_COOKIESTORAGE@") +if boolean("@PLUGIN_WEBKITBROWSER_WINDOWCLOSE@"): + configuration.add("windowclose", "@PLUGIN_WEBKITBROWSER_WINDOWCLOSE@") +configuration.add("execpath", "@PLUGIN_WEBKITBROWSER_ALTERNATIVE_EXEC_PATH@") +if "@PLUGIN_WEBKITBROWSER_PTSOFFSET@" != "0": + configuration.add("ptsoffset", "@PLUGIN_WEBKITBROWSER_PTSOFFSET@") +configuration.add("proxy", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY@") +configuration.add("proxyexclusion", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY_EXCLUSION@") + +rootobject = JSON() +rootobject.add("mode", "@PLUGIN_APPS_MODE@") +rootobject.add("locator", "lib@PLUGIN_WEBKITBROWSER_IMPLEMENTATION@.so") +configuration.add("root", rootobject) + +javascript = JSON() +javascript.add("useJIT", "true" if boolean("@PLUGIN_APPS_ENABLE_JIT@") else "false") +javascript.add("useDFG", "true" if boolean("@PLUGIN_APPS_ENABLE_DFG@") else "false") +configuration.add("javascript", javascript) + +webprocesssettings = JSON() +webprocesssettings.add("limit", "@PLUGIN_APPS_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_APPS_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_APPS_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_APPS_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") + +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_APPS_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_APPS_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") + +memory = JSON() +memory.add("webprocesssettings", webprocesssettings) +memory.add("networkprocesssettings", networkprocesssettings) +configuration.add("memory", memory) diff --git a/WebKitBrowser/CMakeLists.txt b/WebKitBrowser/CMakeLists.txt index 5788496e73..05a8b44fea 100644 --- a/WebKitBrowser/CMakeLists.txt +++ b/WebKitBrowser/CMakeLists.txt @@ -73,8 +73,8 @@ set(PLUGIN_WEBKITBROWSER_MSEBUFFERS "audio:2m,video:15m,text:1m" CACHE STRING "M set(PLUGIN_WEBKITBROWSER_DISKCACHE "0" CACHE STRING "Disk Cache") set(PLUGIN_WEBKITBROWSER_XHRCACHE "true" CACHE STRING "XHR Cache") set(PLUGIN_WEBKITBROWSER_EXTENSION_DIRECTORY "Extension" CACHE STRING "Directory to store extension libraries") -set(PLUGIN_WEBKITBROWSER_LOCALSTORAGE "" CACHE STRING "HTML5 local storage path") -set(PLUGIN_WEBKITBROWSER_COOKIESTORAGE "" CACHE STRING "Browser cookie storage path") +set(PLUGIN_WEBKITBROWSER_LOCALSTORAGE "%persistentpath%" CACHE STRING "HTML5 local storage path") +set(PLUGIN_WEBKITBROWSER_COOKIESTORAGE "%persistentpath%" CACHE STRING "Browser cookie storage path") set(PLUGIN_WEBKITBROWSER_WINDOWCLOSE "false" CACHE STRING "Allow window close") set(PLUGIN_WEBKITBROWSER_WEBGL "true" CACHE STRING "Enable WebGL") set(PLUGIN_WEBKITBROWSER_RESOLUTION "720p" CACHE STRING "Browser resolution") @@ -84,7 +84,7 @@ set(PLUGIN_WEBKITBROWSER_LOCALSTORAGE_ENABLE "true" CACHE STRING "Enable LocalSt set(PLUGIN_WEBKITBROWSER_THUNDER_DECRYPTOR_PREFERENCE "true" CACHE STRING "Enable Thunder decryptor preference in WebKit") set(PLUGIN_WEBKITBROWSER_PERSISTENTPATHPOSTFIX "" CACHE STRING "Specify callsign persistent path postfix") set(PLUGIN_WEBKITBROWSER_PTSOFFSET "0" CACHE STRING "Set ptsoffset for webkit") -set(PLUGIN_WEBKITBROWSER_USE_EXACT_PATHS "false" CACHE STRING "Use paths specified in configuration options without further modifying them") +set(PLUGIN_WEBKITBROWSER_USE_EXACT_PATHS "false" CACHE STRING "Use paths specified in configuration options without further modifying them") set(PLUGIN_YOUTUBE_AUTOSTART "false" CACHE STRING "Automatically start Youtube plugin") set(PLUGIN_YOUTUBE_STARTUPORDER "" CACHE STRING "To configure startup order of YouTube plugin") diff --git a/WebKitBrowser/Extension/CMakeLists.txt b/WebKitBrowser/Extension/CMakeLists.txt index 3af94589ca..2a07deccf7 100644 --- a/WebKitBrowser/Extension/CMakeLists.txt +++ b/WebKitBrowser/Extension/CMakeLists.txt @@ -23,6 +23,7 @@ find_package(securityagent QUIET) find_package(WPEWebKit REQUIRED) option(PLUGIN_SECURITYAGENT "Enable the Security Agent Features interface in javascript." OFF) +option(PLUGIN_WEBKITBROWSER_IIDENTIFIER "Enable IIDENTIFIER interface JS bindings." OFF) option(PLUGIN_WEBKITBROWSER_AAMP_JSBINDINGS "Enable AAMP JS bindings." OFF) option(PLUGIN_WEBKITBROWSER_BADGER_BRIDGE "Enable $badger support." OFF) option(PLUGIN_WEBKITBROWSER_UPDATE_TZ_FROM_FILE "Update TimeZone from given file" OFF) @@ -43,6 +44,11 @@ if(securityagent_FOUND) target_link_libraries(${MODULE_NAME} PRIVATE securityagent::securityagent) endif() +if(PLUGIN_WEBKITBROWSER_IIDENTIFIER) + target_sources(${MODULE_NAME} PRIVATE IIdentifier.cpp) + target_compile_definitions(${MODULE_NAME} PRIVATE ENABLE_IIDENTIFIER) +endif() + if(PLUGIN_WEBKITBROWSER_AAMP_JSBINDINGS) find_package(AampJSBindings REQUIRED) target_sources(${MODULE_NAME} PRIVATE AAMPJSBindings.cpp) @@ -59,13 +65,13 @@ if(PLUGIN_WEBKITBROWSER_UPDATE_TZ_FROM_FILE) target_sources(${MODULE_NAME} PRIVATE ../TimeZone/TimeZoneSupport.cpp) target_compile_definitions(${MODULE_NAME} PRIVATE UPDATE_TZ_FROM_FILE) target_include_directories(${MODULE_NAME} PRIVATE ../TimeZone) + target_include_directories(${MODULE_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) if(TZ_FILE) add_definitions(-DTZ_FILE="${TZ_FILE}") endif() endif() if(PLUGIN_WEBKITBROWSER_CUSTOM_PROCESS_INFO) - target_sources(${MODULE_NAME} PRIVATE ProcessInfo.cpp) target_compile_definitions(${MODULE_NAME} PRIVATE ENABLE_CUSTOM_PROCESS_INFO) endif() @@ -73,9 +79,11 @@ set_target_properties(${MODULE_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES) + target_link_libraries(${MODULE_NAME} PRIVATE ${NAMESPACE}Plugins::${NAMESPACE}Plugins + ${NAMESPACE}Core::${NAMESPACE}Core WPEWebKit::WPEWebKit) target_compile_definitions(${MODULE_NAME} PRIVATE WEBKIT_GLIB_API) diff --git a/WebKitBrowser/Extension/IIdentifier.cpp b/WebKitBrowser/Extension/IIdentifier.cpp new file mode 100644 index 0000000000..2a8c39a974 --- /dev/null +++ b/WebKitBrowser/Extension/IIdentifier.cpp @@ -0,0 +1,168 @@ +/* + * 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 "Module.h" +#include + +#include "IIdentifier.h" + +namespace WPEFramework { +namespace JavaScript { +namespace IIdentifier { + +void InjectJS(WebKitScriptWorld* world, WebKitFrame* frame, Core::ProxyType& _comClient) +{ + if (webkit_frame_is_main_frame(frame) == false) + return; + + JSCContext* jsContext = webkit_frame_get_js_context_for_script_world(frame, world); + + using IIdentifierData = std::tuple; + + // Register a custom class + JSCClass* jscClass = jsc_context_register_class( + jsContext, + "IIdentifier", + nullptr, + nullptr, + GDestroyNotify(+[](gpointer userData) -> void { + IIdentifierData& identifierData = *static_cast(userData); + + PluginHost::IShell* controller = std::get<0>(identifierData); + const PluginHost::ISubSystem* subsysInterface = std::get<1>(identifierData); + const PluginHost::ISubSystem::IIdentifier* identifierInterface = std::get<2>(identifierData); + + identifierInterface->Release(); + subsysInterface->Release(); + controller->Release(); + + delete static_cast(userData); + })); + + // Add constructor for the custom class + JSCValue* constructor = jsc_class_add_constructor( + jscClass, + nullptr, + GCallback(+[](gpointer userData) -> gpointer { + Core::ProxyType& comClient = *static_cast*>(userData); + + PluginHost::IShell* controller = comClient->Acquire(10000, _T("Controller"), ~0); + const PluginHost::ISubSystem* subsysInterface = controller->SubSystems(); + const PluginHost::ISubSystem::IIdentifier* identifierInterface = subsysInterface->Get(); + + auto* identifierData = new IIdentifierData(controller, subsysInterface, identifierInterface); + return identifierData; + }), + (gpointer)&_comClient, + nullptr, + G_TYPE_POINTER, + 0, + G_TYPE_NONE); + jsc_context_set_value(jsContext, jsc_class_get_name(jscClass), constructor); + g_object_unref(constructor); + + // Add methods for the custom class + jsc_class_add_method( + jscClass, + "Identifier", + G_CALLBACK(+[](gpointer userData) -> char* { + IIdentifierData& identifierData = *static_cast(userData); + const PluginHost::ISubSystem::IIdentifier* identifierInterface = std::get<2>(identifierData); + + uint8_t buffer[64] = {}; + buffer[0] = identifierInterface->Identifier(sizeof(buffer) - 1, &(buffer[1])); + string identifier = Core::SystemInfo::Instance().Id(buffer, ~0); + if (identifier.length() > 0) { + return g_strndup(reinterpret_cast(identifier.c_str()), identifier.length()); + } else { + return nullptr; + } + }), + (gpointer)&_comClient, + nullptr, + G_TYPE_STRING, + 0, + G_TYPE_NONE); + + jsc_class_add_method( + jscClass, + "Architecture", + G_CALLBACK(+[](gpointer userData) -> char* { + IIdentifierData& identifierData = *static_cast(userData); + const PluginHost::ISubSystem::IIdentifier* identifierInterface = std::get<2>(identifierData); + + string architecture = identifierInterface->Architecture(); + if (architecture.length() > 0) { + return g_strndup(reinterpret_cast(architecture.c_str()), architecture.length()); + } else { + return nullptr; + } + }), + (gpointer)&_comClient, + nullptr, + G_TYPE_STRING, + 0, + G_TYPE_NONE); + + jsc_class_add_method( + jscClass, + "Chipset", + G_CALLBACK(+[](gpointer userData) -> char* { + IIdentifierData& identifierData = *static_cast(userData); + const PluginHost::ISubSystem::IIdentifier* identifierInterface = std::get<2>(identifierData); + + string chipset = identifierInterface->Chipset(); + if (chipset.length() > 0) { + return g_strndup(reinterpret_cast(chipset.c_str()), chipset.length()); + } else { + return nullptr; + } + }), + (gpointer)&_comClient, + nullptr, + G_TYPE_STRING, + 0, + G_TYPE_NONE); + + jsc_class_add_method( + jscClass, + "FirmwareVersion", + G_CALLBACK(+[](gpointer userData) -> char* { + IIdentifierData& identifierData = *static_cast(userData); + const PluginHost::ISubSystem::IIdentifier* identifierInterface = std::get<2>(identifierData); + + string firmwareVersion = identifierInterface->FirmwareVersion(); + if (firmwareVersion.length() > 0) { + return g_strndup(reinterpret_cast(firmwareVersion.c_str()), firmwareVersion.length()); + } else { + return nullptr; + } + }), + (gpointer)&_comClient, + nullptr, + G_TYPE_STRING, + 0, + G_TYPE_NONE); + + g_object_unref(jsContext); +} + +} // IIdentifier +} // JavaScript +} // WPEFramework diff --git a/WebKitBrowser/Extension/IIdentifier.h b/WebKitBrowser/Extension/IIdentifier.h new file mode 100644 index 0000000000..97b21c6fab --- /dev/null +++ b/WebKitBrowser/Extension/IIdentifier.h @@ -0,0 +1,32 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace WPEFramework { +namespace JavaScript { +namespace IIdentifier { + +void InjectJS(WebKitScriptWorld* world, WebKitFrame* frame, Core::ProxyType& _comClient); + +} // IIdentifier +} // JavaScript +} // WPEFramework diff --git a/WebKitBrowser/Extension/main.cpp b/WebKitBrowser/Extension/main.cpp index 58d28d2b45..59c906f97b 100644 --- a/WebKitBrowser/Extension/main.cpp +++ b/WebKitBrowser/Extension/main.cpp @@ -37,6 +37,10 @@ #include "SecurityAgent.h" #endif +#if defined(ENABLE_IIDENTIFIER) +#include "IIdentifier.h" +#endif + #if defined(ENABLE_BADGER_BRIDGE) #include "BridgeObject.h" #endif @@ -49,10 +53,6 @@ #include "TimeZoneSupport.h" #endif -#if defined(ENABLE_CUSTOM_PROCESS_INFO) -#include "ProcessInfo.h" -#endif - using namespace WPEFramework; static Core::NodeId GetConnectionNode() @@ -102,8 +102,9 @@ static class PluginHost { g_variant_get((GVariant*) userData, "(&sm&sb)", &uid, &whitelist, &_logToSystemConsoleEnabled); - if (_logToSystemConsoleEnabled && Core::SystemInfo::GetEnvironment(string(_T("CLIENT_IDENTIFIER")), _consoleLogPrefix)) + if (_logToSystemConsoleEnabled && Core::SystemInfo::GetEnvironment(string(_T("CLIENT_IDENTIFIER")), _consoleLogPrefix)) { _consoleLogPrefix = _consoleLogPrefix.substr(0, _consoleLogPrefix.find(',')); + } g_signal_connect( webkit_script_world_get_default(), @@ -128,7 +129,11 @@ static class PluginHost { _tzSupport.Initialize(); #endif #ifdef ENABLE_CUSTOM_PROCESS_INFO - ProcessInfo::SetProcessName(); + std::string processName; + Core::SystemInfo::GetEnvironment(std::string(_T("PROCESS_NAME")), processName); + if (processName.empty() != true) { + Core::ProcessInfo().Name(processName); + } #endif } @@ -158,6 +163,10 @@ static class PluginHost { JavaScript::SecurityAgent::InjectJS(world, frame); #endif +#ifdef ENABLE_IIDENTIFIER + JavaScript::IIdentifier::InjectJS(world, frame, host->_comClient); +#endif + #ifdef ENABLE_BADGER_BRIDGE JavaScript::BridgeObject::InjectJS(world, page, frame); #endif @@ -200,7 +209,7 @@ static class PluginHost { } #if defined(ENABLE_BADGER_BRIDGE) else if ((g_strcmp0(name, Tags::BridgeObjectReply) == 0) - || (g_strcmp0(name, Tags::BridgeObjectEvent) == 0)) { + || (g_strcmp0(name, Tags::BridgeObjectEvent) == 0)) { JavaScript::BridgeObject::HandleMessageToPage(page, name, message); } #endif @@ -215,8 +224,9 @@ static class PluginHost { #ifdef ENABLE_AAMP_JSBINDINGS static gboolean didStartProvisionalLoadForFrame(WebKitWebPage* page, WebKitFrame* frame) { - if (webkit_frame_is_main_frame(frame)) + if (webkit_frame_is_main_frame(frame)) { JavaScript::AAMP::UnloadJSBindings(webkit_script_world_get_default(), frame); + } return FALSE; } #endif diff --git a/WebKitBrowser/HtmlApp.conf.in b/WebKitBrowser/HtmlApp.conf.in index abbffda7f7..f3761a4dc7 100644 --- a/WebKitBrowser/HtmlApp.conf.in +++ b/WebKitBrowser/HtmlApp.conf.in @@ -63,31 +63,17 @@ rootobject.add("user", "@PLUGIN_WEBKITBROWSER_USER@") rootobject.add("group", "@PLUGIN_WEBKITBROWSER_GROUP@") configuration.add("root", rootobject) -memory = JSON() - webprocesssettings = JSON() -networkprocesssettings = JSON() - -if ("@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@ OR (@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@) OR @PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - - if ("@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@"): - webprocesssettings.add("limit", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") - - if ("@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@"): - webprocesssettings.add("gpulimit", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") - webprocesssettings.add("gpufile", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("limit", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") - if ("@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - webprocesssettings.add("pollinterval", "@PLUGIN_HTML_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") +memory = JSON() memory.add("webprocesssettings", webprocesssettings) - -if ("@PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@ AND @PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - if ("@PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@"): - networkprocesssettings.add("limit", "@PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") - if ("@PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - networkprocesssettings.add("pollinterval", "@PLUGIN_HTML_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") memory.add("networkprocesssettings", networkprocesssettings) - configuration.add("memory", memory) - diff --git a/WebKitBrowser/InjectedBundle/WhiteListedOriginDomainsList.cpp b/WebKitBrowser/InjectedBundle/WhiteListedOriginDomainsList.cpp index 6d27974282..78550aedca 100644 --- a/WebKitBrowser/InjectedBundle/WhiteListedOriginDomainsList.cpp +++ b/WebKitBrowser/InjectedBundle/WhiteListedOriginDomainsList.cpp @@ -91,7 +91,7 @@ namespace WebKit { } // Gets white list from WPEFramework via synchronous message. - /* static */unique_ptr WhiteListedOriginDomainsList::RequestFromWPEFramework(const char* whitelist) + /* static */unique_ptr WhiteListedOriginDomainsList::RequestFromWPEFramework(const char* /* whitelist */) { string messageName(string(Tags::Config) + "Whitelist"); std::string utf8MessageName = Core::ToString(messageName.c_str()); diff --git a/WebKitBrowser/InjectedBundle/main.cpp b/WebKitBrowser/InjectedBundle/main.cpp index 14880435f3..bff6b11158 100644 --- a/WebKitBrowser/InjectedBundle/main.cpp +++ b/WebKitBrowser/InjectedBundle/main.cpp @@ -100,7 +100,8 @@ static class PluginHost { } public: - void Initialize(WKBundleRef bundle, const void* userData = nullptr) + void Initialize(WKBundleRef) + //void Initialize(WKBundleRef bundle, const void* userData = nullptr) { // We have something to report back, do so... uint32_t result = _comClient->Open(RPC::CommunicationTimeOut); @@ -108,7 +109,8 @@ static class PluginHost { TRACE(Trace::Error, (_T("Could not open connection to node %s. Error: %s"), _comClient->Source().RemoteId().c_str(), Core::NumberType(result).Text().c_str())); } else { // Due to the LXC container support all ID's get mapped. For the TraceBuffer, use the host given ID. - Trace::TraceUnit::Instance().Open(_comClient->ConnectionId()); + //Trace::TraceUnit::Instance().Open(_comClient->ConnectionId()); + Messaging::MessageUnit::Instance().Open(_comClient->ConnectionId()); } _whiteListedOriginDomainPairs = WhiteListedOriginDomainsList::RequestFromWPEFramework(); @@ -122,6 +124,9 @@ static class PluginHost { #if defined(UPDATE_TZ_FROM_FILE) _tzSupport.Deinitialize(); #endif + + Messaging::MessageUnit::Instance().Close(); + if (_comClient.IsValid() == true) { _comClient.Release(); } @@ -268,7 +273,7 @@ static WKBundlePageLoaderClientV6 s_pageLoaderClient = { nullptr, // didDisplayInsecureContentForFrame nullptr, // didRunInsecureContentForFrame // didClearWindowObjectForFrame - [](WKBundlePageRef page, WKBundleFrameRef frame, WKBundleScriptWorldRef scriptWorld, const void*) { + [](WKBundlePageRef /* page */, WKBundleFrameRef frame, WKBundleScriptWorldRef scriptWorld, const void*) { bool isMainCtx = (WKBundleFrameGetJavaScriptContext(frame) == WKBundleFrameGetJavaScriptContextForWorld(frame, scriptWorld)); if (isMainCtx) { #if defined(ENABLE_AAMP_JSBINDINGS) @@ -333,11 +338,12 @@ static WKBundlePageUIClientV4 s_pageUIClient = { nullptr, // unused5 nullptr, // didClickAutoFillButton //willAddDetailedMessageToConsole - [](WKBundlePageRef page, WKConsoleMessageSource source, WKConsoleMessageLevel level, WKStringRef message, uint32_t lineNumber, - uint32_t columnNumber, WKStringRef url, const void* clientInfo) { + [](WKBundlePageRef /* page */, WKConsoleMessageSource /* source */, WKConsoleMessageLevel /* level */, WKStringRef message, uint32_t /* lineNumber */, + uint32_t /* columnNumber */, WKStringRef /* url */, const void* /* clientInfo */) { auto prepareMessage = [&]() { string messageString = WebKit::Utils::WKStringToString(message); - const uint16_t maxStringLength = Trace::TRACINGBUFFERSIZE - 1; + //const uint16_t maxStringLength = Trace::TRACINGBUFFERSIZE - 1; + const uint16_t maxStringLength = Messaging::MessageUnit::DataSize - 1; if (messageString.length() > maxStringLength) { messageString = messageString.substr(0, maxStringLength); } @@ -346,7 +352,8 @@ static WKBundlePageUIClientV4 s_pageUIClient = { // TODO: use "Trace" classes for different levels. TRACE_GLOBAL(Trace::Information, (prepareMessage())); - } + }, + nullptr // didResignInputElementStrongPasswordAppearance }; static WKURLRequestRef willSendRequestForFrame( @@ -387,7 +394,7 @@ static WKBundlePageResourceLoadClientV0 s_resourceLoadClient = { static WKBundleClientV1 s_bundleClient = { { 1, nullptr }, // didCreatePage - [](WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo) { + [](WKBundleRef bundle, WKBundlePageRef page, const void* /* clientInfo */) { // Register page loader client, for javascript callbacks. WKBundlePageSetPageLoaderClient(page, &s_pageLoaderClient.base); diff --git a/WebKitBrowser/JSPP.conf.in b/WebKitBrowser/JSPP.conf.in index 58277c489a..0c81514dc0 100644 --- a/WebKitBrowser/JSPP.conf.in +++ b/WebKitBrowser/JSPP.conf.in @@ -115,30 +115,17 @@ rootobject.add("user", "@PLUGIN_WEBKITBROWSER_USER@") rootobject.add("group", "@PLUGIN_WEBKITBROWSER_GROUP@") configuration.add("root", rootobject) -memory = JSON() - webprocesssettings = JSON() -networkprocesssettings = JSON() - -if ("@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@ OR (@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@) OR @PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - - if ("@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@"): - webprocesssettings.add("limit", "@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("limit", "@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") - if ("@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@"): - webprocesssettings.add("gpulimit","@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") - webprocesssettings.add("gpufile", "@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") - - if ("@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - webprocesssettings.add("pollinterval", "@PLUGIN_JSPP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") +memory = JSON() memory.add("webprocesssettings", webprocesssettings) - -if ("@PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@ OR @PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - if ("@PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@"): - networkprocesssettings.add("limit", "@PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") - if ("@PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - networkprocesssettings.add("pollinterval", "@PLUGIN_JSPP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") memory.add("networkprocesssettings", networkprocesssettings) configuration.add("memory", memory) - diff --git a/WebKitBrowser/LightningApp.conf.in b/WebKitBrowser/LightningApp.conf.in index b7ee80352e..ac34a58041 100644 --- a/WebKitBrowser/LightningApp.conf.in +++ b/WebKitBrowser/LightningApp.conf.in @@ -63,29 +63,17 @@ rootobject.add("user", "@PLUGIN_WEBKITBROWSER_USER@") rootobject.add("group", "@PLUGIN_WEBKITBROWSER_GROUP@") configuration.add("root", rootobject) -memory = JSON() - webprocesssettings = JSON() -networkprocesssettings = JSON() - -if ("@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@ OR (@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@) OR @PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - - if ("@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@"): - webprocesssettings.add("limit", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("limit", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") - if ("@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@"): - webprocesssettings.add("gpulimit","@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") - webprocesssettings.add("gpufile", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") - - if ("@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - webprocesssettings.add("pollinterval", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") +memory = JSON() memory.add("webprocesssettings", webprocesssettings) - -if ("@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@ AND @PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - if ("@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@"): - networkprocesssettings.add("limit", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") - if ("@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - networkprocesssettings.add("pollinterval", "@PLUGIN_LIGHTNING_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") memory.add("networkprocesssettings", networkprocesssettings) configuration.add("memory", memory) diff --git a/WebKitBrowser/LoggingUtils.cpp b/WebKitBrowser/LoggingUtils.cpp index 65fa91eeaa..fddf76f275 100644 --- a/WebKitBrowser/LoggingUtils.cpp +++ b/WebKitBrowser/LoggingUtils.cpp @@ -55,8 +55,9 @@ bool RedirectAllLogsToService(const string& target_service) // Add all threads of current process to target systemd cgroup WPEFramework::Core::Directory taskDir("/proc/self/task"); while (taskDir.Next() == true) { - if (taskDir.Name() == "." || taskDir.Name() == "..") + if (taskDir.Name() == "." || taskDir.Name() == "..") { continue; + } FILE* f = fopen(kSystemdCgroupTargetTasksFilePath.c_str(), "a"); if (f) { fprintf(f, "%s", taskDir.Name().c_str()); diff --git a/WebKitBrowser/ResidentApp.conf.in b/WebKitBrowser/ResidentApp.conf.in index b10d6efa90..413caad790 100644 --- a/WebKitBrowser/ResidentApp.conf.in +++ b/WebKitBrowser/ResidentApp.conf.in @@ -58,29 +58,17 @@ rootobject.add("user", "@PLUGIN_WEBKITBROWSER_USER@") rootobject.add("group", "@PLUGIN_WEBKITBROWSER_GROUP@") configuration.add("root", rootobject) -memory = JSON() - webprocesssettings = JSON() -networkprocesssettings = JSON() - -if ("@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@ OR (@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@) OR @PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - - if ("@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@"): - webprocesssettings.add("limit", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("limit", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") - if ("@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@"): - webprocesssettings.add("gpulimit","@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") - webprocesssettings.add("gpufile", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") - - if ("@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - webprocesssettings.add("pollinterval", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") +memory = JSON() memory.add("webprocesssettings", webprocesssettings) - -if ("@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@ AND @PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - if ("@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@"): - networkprocesssettings.add("limit", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") - if ("@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - networkprocesssettings.add("pollinterval", "@PLUGIN_RESIDENT_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") memory.add("networkprocesssettings", networkprocesssettings) configuration.add("memory", memory) diff --git a/WebKitBrowser/SearchAndDiscoveryApp.conf.in b/WebKitBrowser/SearchAndDiscoveryApp.conf.in index e4e4e6fb75..af24018485 100644 --- a/WebKitBrowser/SearchAndDiscoveryApp.conf.in +++ b/WebKitBrowser/SearchAndDiscoveryApp.conf.in @@ -60,28 +60,18 @@ rootobject.add("user", "@PLUGIN_WEBKITBROWSER_USER@") rootobject.add("group", "@PLUGIN_WEBKITBROWSER_GROUP@") configuration.add("root", rootobject) -memory = JSON() - webprocesssettings = JSON() -networkprocesssettings = JSON() - -if ("@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@ OR (@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@) OR @PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - if ("@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@"): - webprocesssettings.add("limit", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("limit", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") - if ("@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@"): - webprocesssettings.add("gpulimit","@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") - webprocesssettings.add("gpufile", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") - if ("@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - webprocesssettings.add("pollinterval", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") +memory = JSON() memory.add("webprocesssettings", webprocesssettings) - -if ("@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@ AND @PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - if ("@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@"): - networkprocesssettings.add("limit", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") - if ("@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - networkprocesssettings.add("pollinterval", "@PLUGIN_SEARCH_AND_DISCOVERY_APP_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") memory.add("networkprocesssettings", networkprocesssettings) configuration.add("memory", memory) diff --git a/WebKitBrowser/Tags.cpp b/WebKitBrowser/Tags.cpp index 2bbeaa68c4..4569877f81 100644 --- a/WebKitBrowser/Tags.cpp +++ b/WebKitBrowser/Tags.cpp @@ -31,4 +31,4 @@ const char* const BridgeObjectReply = "BridgeObjectReply"; const char* const BridgeObjectEvent = "BridgeObjectEvent"; const char* const Headers = "Headers"; -} } ; +} } diff --git a/WebKitBrowser/Tags.h b/WebKitBrowser/Tags.h index a792981054..07711f0670 100644 --- a/WebKitBrowser/Tags.h +++ b/WebKitBrowser/Tags.h @@ -31,4 +31,4 @@ extern const char* const BridgeObjectReply; extern const char* const BridgeObjectEvent; extern const char* const Headers; -} } ; +} } diff --git a/WebKitBrowser/TimeZone/TimeZoneSupport.cpp b/WebKitBrowser/TimeZone/TimeZoneSupport.cpp index 90af3d09ab..461586f0e0 100644 --- a/WebKitBrowser/TimeZone/TimeZoneSupport.cpp +++ b/WebKitBrowser/TimeZone/TimeZoneSupport.cpp @@ -32,8 +32,9 @@ namespace WPEFramework { namespace TZ { void trim(std::string &str) { - if (str.empty()) + if (str.empty()) { return; + } gchar *tmp = g_strdup(str.c_str()); str = std::string(g_strstrip(tmp)); @@ -47,14 +48,14 @@ namespace TZ { gsize length = 0; auto result = g_file_load_contents(file, nullptr, &content, &length, nullptr, nullptr); - if(result && content && length > 0) { + if (result && content && length > 0) { std::string timeZone(content); trim(timeZone); if (timeZone != tzSupport->_previousTimeZone) { tzSupport->_previousTimeZone = timeZone; timeZone = ":" + timeZone; - SYSLOG(Trace::Information, (_T("TimeZone is updated to \"%s\" from \"%s\" file"), timeZone.c_str(), tzSupport->_tzFile.c_str())); + SYSLOG(Logging::Notification, (_T("TimeZone is updated to \"%s\" from \"%s\" file"), timeZone.c_str(), tzSupport->_tzFile.c_str())); Core::SystemInfo::SetEnvironment(_T("TZ"), _T(timeZone), true); tzset(); } @@ -75,8 +76,8 @@ namespace TZ { void TimeZoneSupport::Initialize() { - if(_tzFile.empty()) { - SYSLOG(Trace::Warning, (_T("Invalid file input for TZ update"))); + if (_tzFile.empty()) { + SYSLOG(Logging::Error, (_T("Invalid file input for TZ update"))); return; } @@ -84,12 +85,13 @@ namespace TZ { trim(_previousTimeZone); GFile *file = g_file_new_for_path(_tzFile.c_str()); - if(g_file_query_exists(file, nullptr)) + if (g_file_query_exists(file, nullptr)) { HandleTimeZoneFileUpdate(nullptr, file, nullptr, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, this); + } _timeZoneFileMonitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, nullptr, nullptr); _timeZoneFileMonitorId = g_signal_connect(_timeZoneFileMonitor, "changed", reinterpret_cast(HandleTimeZoneFileUpdate), this); - SYSLOG(Trace::Information, (_T("Installed file monitor for \"%s\""), _tzFile.c_str())); + SYSLOG(Logging::Notification, (_T("Installed file monitor for \"%s\""), _tzFile.c_str())); g_object_unref(file); } @@ -97,8 +99,9 @@ namespace TZ { void TimeZoneSupport::Deinitialize() { if (_timeZoneFileMonitor) { - if (_timeZoneFileMonitorId > 0) + if (_timeZoneFileMonitorId > 0) { g_signal_handler_disconnect(_timeZoneFileMonitor, _timeZoneFileMonitorId); + } g_object_unref(_timeZoneFileMonitor); _timeZoneFileMonitor = nullptr; diff --git a/WebKitBrowser/UX.conf.in b/WebKitBrowser/UX.conf.in new file mode 100644 index 0000000000..a84c0aa99e --- /dev/null +++ b/WebKitBrowser/UX.conf.in @@ -0,0 +1,67 @@ +startmode = "@PLUGIN_UX_STARTMODE@" +startuporder = "@PLUGIN_UX_STARTUPORDER@" + +configuration = JSON() + +configuration.add("url", "about:blank") +configuration.add("useragent", "@PLUGIN_UX_USERAGENT@") + +if not boolean("@WEBKIT_GLIB_API@"): + configuration.add("injectedbundle", "libWPEInjectedBundle@CMAKE_SHARED_LIBRARY_SUFFIX@") +else: + configuration.add("extensiondir", "@PLUGIN_WEBKITBROWSER_EXTENSION_DIRECTORY@") + +configuration.add("transparent", "@PLUGIN_WEBKITBROWSER_TRANSPARENT@") +configuration.add("compositor", "aa") +configuration.add("inspector", "@PLUGIN_UX_WEBINSPECTOR_ADDRESS@") +configuration.add("fps", "true") +configuration.add("cursor", "false") +configuration.add("touch", "false") +configuration.add("msebuffers", "@PLUGIN_UX_MSEBUFFERS@") +configuration.add("thunderdecryptorpreference", "@PLUGIN_WEBKITBROWSER_THUNDER_DECRYPTOR_PREFERENCE@") +configuration.add("memoryprofile", "@PLUGIN_WEBKITBROWSER_MEMORYPROFILE@") +configuration.add("mediacontenttypesrequiringhardwaresupport", "@PLUGIN_WEBKITBROWSER_MEDIA_CONTENT_TYPES_REQUIRING_HARDWARE_SUPPORT@") +configuration.add("mediadiskcache", "@PLUGIN_WEBKITBROWSER_MEDIADISKCACHE@") +configuration.add("diskcache", "@PLUGIN_WEBKITBROWSER_DISKCACHE@") +configuration.add("xhrcache", "@PLUGIN_WEBKITBROWSER_XHRCACHE@") +configuration.add("noncompositedwebgl", "true") +configuration.add("secure", "false") +configuration.add("webgl", "@PLUGIN_WEBKITBROWSER_WEBGL@") +configuration.add("threadedpainting", "@PLUGIN_WEBKITBROWSER_THREADEDPAINTING@") +configuration.add("height", "@PLUGIN_WEBKITBROWSER_HEIGHT@") +configuration.add("width", "@PLUGIN_WEBKITBROWSER_WIDTH@") +configuration.add("clientidentifier", "@PLUGIN_WEBKITBROWSER_CLIENTIDENTIFIER@") +configuration.add("secure", "@PLUGIN_UX_SECURE@") +configuration.add("localstorageenabled", "@PLUGIN_UX_LOCALSTORAGE_ENABLE@") +configuration.add("localstorage", "@PLUGIN_WEBKITBROWSER_LOCALSTORAGE@") +configuration.add("cookiestorage", "@PLUGIN_WEBKITBROWSER_COOKIESTORAGE@") +configuration.add("execpath", "@PLUGIN_WEBKITBROWSER_ALTERNATIVE_EXEC_PATH@") +configuration.add("proxy", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY@") +configuration.add("proxyexclusion", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY_EXCLUSION@") + +rootobject = JSON() +rootobject.add("mode", "@PLUGIN_UX_MODE@") +rootobject.add("locator", "lib@PLUGIN_WEBKITBROWSER_IMPLEMENTATION@.so") +rootobject.add("user", "@PLUGIN_WEBKITBROWSER_USER@") +rootobject.add("group", "@PLUGIN_WEBKITBROWSER_GROUP@") +configuration.add("root", rootobject) + +javascript = JSON() +javascript.add("useJIT", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_JIT@") else "false") +javascript.add("useDFG", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_DFG@") else "false") +configuration.add("javascript", javascript) + +webprocesssettings = JSON() +webprocesssettings.add("limit", "@PLUGIN_UX_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_UX_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_UX_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_UX_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") + +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_UX_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_UX_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") + +memory = JSON() +memory.add("webprocesssettings", webprocesssettings) +memory.add("networkprocesssettings", networkprocesssettings) +configuration.add("memory", memory) diff --git a/WebKitBrowser/WebKitBrowser.conf.in b/WebKitBrowser/WebKitBrowser.conf.in index 1c0312d66c..65f0939dc8 100644 --- a/WebKitBrowser/WebKitBrowser.conf.in +++ b/WebKitBrowser/WebKitBrowser.conf.in @@ -73,29 +73,17 @@ javascript.add("useJIT", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_JIT@") javascript.add("useDFG", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_DFG@") else "false") configuration.add("javascript", javascript) -memory = JSON() - webprocesssettings = JSON() -networkprocesssettings = JSON() - -if ("@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@ OR (@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@) OR @PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - - if ("@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@"): - webprocesssettings.add("limit", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("limit", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") - if ("@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@ AND @PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@"): - webprocesssettings.add("gpulimit","@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") - webprocesssettings.add("gpufile", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") - - if ("@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@"): - webprocesssettings.add("pollinterval", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") +memory = JSON() memory.add("webprocesssettings", webprocesssettings) - -if ("@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@ AND @PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - if ("@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@"): - networkprocesssettings.add("limit", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") - if ("@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@"): - networkprocesssettings.add("pollinterval", "@PLUGIN_WEBKITBROWSER_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") memory.add("networkprocesssettings", networkprocesssettings) configuration.add("memory", memory) diff --git a/WebKitBrowser/WebKitBrowser.cpp b/WebKitBrowser/WebKitBrowser.cpp index 4574adc0ca..df7f104c4d 100644 --- a/WebKitBrowser/WebKitBrowser.cpp +++ b/WebKitBrowser/WebKitBrowser.cpp @@ -46,14 +46,15 @@ namespace Plugin { /* virtual */ const string WebKitBrowser::Initialize(PluginHost::IShell* service) { string message; - + ASSERT(service != nullptr); ASSERT(_service == nullptr); ASSERT(_browser == nullptr); ASSERT(_memory == nullptr); ASSERT(_application == nullptr); + ASSERT(_connectionId == 0); - _connectionId = 0; _service = service; + _service->AddRef(); _skipURL = _service->WebPrefix().length(); _persistentStoragePath = _service->PersistentPath(); @@ -65,66 +66,51 @@ namespace Plugin { _browser = service->Root(_connectionId, 2000, _T("WebKitImplementation")); if (_browser != nullptr) { + PluginHost::IStateControl* stateControl(_browser->QueryInterface()); // We see that sometimes the WPE implementation crashes before it reaches this point, than there is // no StateControl. Cope with this situation. if (stateControl == nullptr) { - _browser->Release(); - _browser = nullptr; - + message = _T("WebKitBrowser StateControl could not be Obtained."); } else { _application = _browser->QueryInterface(); if (_application != nullptr) { + RegisterAll(); + Exchange::JWebBrowser::Register(*this, _browser); + + _cookieJar = _browser->QueryInterface(); + if (_cookieJar != nullptr) { + Exchange::JBrowserCookieJar::Register(*this, _cookieJar); + } + + _browserScripting = _browser->QueryInterface(); + if (_browserScripting) { + Exchange::JBrowserScripting::Register(*this, _browserScripting); + } + _browser->Register(&_notification); const RPC::IRemoteConnection *connection = _service->RemoteConnection(_connectionId); - _memory = WPEFramework::WebKitBrowser::MemoryObserver(connection); - ASSERT(_memory != nullptr); if (connection != nullptr) { + _memory = WPEFramework::WebKitBrowser::MemoryObserver(connection); + ASSERT(_memory != nullptr); connection->Release(); } if (stateControl->Configure(_service) != Core::ERROR_NONE) { - if (_memory != nullptr) { - _memory->Release(); - _memory = nullptr; - } - _application->Release(); - _application = nullptr; - _browser->Unregister(&_notification); - _browser->Release(); - _browser = nullptr; + message = _T("WebKitBrowser Implementation could not be Configured."); } else { stateControl->Register(&_notification); } - stateControl->Release(); } else { - stateControl->Release(); - _browser->Release(); - _browser = nullptr; + message = _T("WebKitBrowser Application interface could not be obtained"); } + stateControl->Release(); } } - - if (_browser == nullptr) { + else { message = _T("WebKitBrowser could not be instantiated."); - _service->Unregister(&_notification); - _service = nullptr; - } else { - RegisterAll(); - Exchange::JWebBrowser::Register(*this, _browser); - - _cookieJar = _browser->QueryInterface(); - if (_cookieJar) { - _cookieJar->Register(&_notification); - Exchange::JBrowserCookieJar::Register(*this, _cookieJar); - } - - _browserScripting = _browser->QueryInterface(); - if (_browserScripting) { - Exchange::JBrowserScripting::Register(*this, _browserScripting); - } } return message; @@ -132,63 +118,70 @@ namespace Plugin { /* virtual */ void WebKitBrowser::Deinitialize(PluginHost::IShell* service VARIABLE_IS_NOT_USED) { - ASSERT(_service == service); - ASSERT(_browser != nullptr); - ASSERT(_application != nullptr); - ASSERT(_memory != nullptr); - - if (_browser == nullptr) - return; - - // Make sure we get no longer get any notifications, we are deactivating.. - _service->Unregister(&_notification); - _browser->Unregister(&_notification); - _memory->Release(); - _application->Release(); - Exchange::JWebBrowser::Unregister(*this); - if (_browserScripting) { - Exchange::JBrowserScripting::Unregister(*this); - _browserScripting->Release(); - } - if (_cookieJar) { - Exchange::JBrowserCookieJar::Unregister(*this); - _cookieJar->Unregister(&_notification); - _cookieJar->Release(); - } - UnregisterAll(); + if (_service != nullptr) { + ASSERT(_service == service); - PluginHost::IStateControl* stateControl(_browser->QueryInterface()); + // Make sure we get no longer get any notifications, we are deactivating.. + _service->Unregister(&_notification); - // In case WPE rpcprocess crashed, there is no access to the statecontrol interface, check it !! - if (stateControl != nullptr) { - stateControl->Unregister(&_notification); - stateControl->Release(); - } + if (_browser != nullptr) { - RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + PluginHost::IStateControl* stateControl(_browser->QueryInterface()); + // In case WPE rpcprocess crashed, there is no access to the statecontrol interface, check it !! + if (stateControl != nullptr) { + stateControl->Unregister(&_notification); + stateControl->Release(); + } - // Stop processing of the browser: - VARIABLE_IS_NOT_USED uint32_t result = _browser->Release(); + if (_memory != nullptr) { + _memory->Release(); + _memory = nullptr; + } + if (_application != nullptr) { + if (_cookieJar != nullptr) { + Exchange::JBrowserCookieJar::Unregister(*this); + _cookieJar->Release(); + _cookieJar = nullptr; + } - // It should have been the last reference we are releasing, - // so it should end up in a DESCRUCTION_SUCCEEDED, if not we - // are leaking... - ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + if (_browserScripting != nullptr) { + Exchange::JBrowserScripting::Unregister(*this); + _browserScripting->Release(); + _browserScripting = nullptr; + } - // If this was running in a (container) process... - if (connection != nullptr) { - // Lets trigger a cleanup sequence for - // out-of-process code. Which will guard - // that unwilling processes, get shot if - // not stopped friendly :~) - connection->Terminate(); - connection->Release(); - } + Exchange::JWebBrowser::Unregister(*this); + UnregisterAll(); + _browser->Unregister(&_notification); + _application->Release(); + _application = nullptr; + } - _service = nullptr; - _browser = nullptr; - _application = nullptr; - _memory = nullptr; + RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + + // Stop processing of the browser: + VARIABLE_IS_NOT_USED uint32_t result = _browser->Release(); + _browser = nullptr; + // It should have been the last reference we are releasing, + // so it should end up in a DESCRUCTION_SUCCEEDED, if not we + // are leaking... + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + + // If this was running in a (container) process... + if (connection != nullptr) { + // Lets trigger a cleanup sequence for + // out-of-process code. Which will guard + // that unwilling processes, get shot if + // not stopped friendly :~) + connection->Terminate(); + connection->Release(); + } + } + + _service->Release(); + _service = nullptr; + _connectionId = 0; + } } /* virtual */ string WebKitBrowser::Information() const @@ -365,29 +358,74 @@ namespace WebKitBrowser { _T("WPEWebProcess") }; + class ProcessMemoryObserverImpl : public Exchange::IProcessMemory { + public: + explicit ProcessMemoryObserverImpl(Core::process_t id) + : Exchange::IProcessMemory() + , _info(id) + { + } + ~ProcessMemoryObserverImpl() override = default; + + ProcessMemoryObserverImpl(const ProcessMemoryObserverImpl&) = delete; + ProcessMemoryObserverImpl& operator=(const ProcessMemoryObserverImpl&) = delete; + + uint64_t Resident() const override { + return _info.Resident(); + } + + uint64_t Allocated() const override { + return _info.Allocated(); + } + + uint64_t Shared() const override { + return _info.Shared(); + } + + uint8_t Processes() const override { + return 0; // webkit and network process do now spawn mew children + } + + bool IsOperational() const override { + return _info.IsActive(); + } + + uint32_t Identifier() const override { + static_assert(sizeof(Core::process_t) <= sizeof(uint32_t), "PId type size too big to fit in IProcessMemory::ID"); + return _info.Id(); + } + + string Name() const override { + return _info.Name(); + } + + BEGIN_INTERFACE_MAP(ProcessMemoryObserverImpl) + INTERFACE_ENTRY(Exchange::IProcessMemory) + END_INTERFACE_MAP + + private: + Core::ProcessInfo _info; + }; + static constexpr uint16_t RequiredChildren = (sizeof(mandatoryProcesses) / sizeof(mandatoryProcesses[0])); using SteadyClock = std::chrono::steady_clock; using TimePoint = std::chrono::time_point; - - class MemoryObserverImpl : public Exchange::IMemory { + class MemoryObserverImpl : public Exchange::IMemory, public Exchange::IMemoryExtended { private: - MemoryObserverImpl(); - MemoryObserverImpl(const MemoryObserverImpl&); - MemoryObserverImpl& operator=(const MemoryObserverImpl&); - enum { TYPICAL_STARTUP_TIME = 10 }; /* in Seconds */ public: MemoryObserverImpl(const RPC::IRemoteConnection* connection) : _main(connection == nullptr ? Core::ProcessInfo().Id() : connection->RemoteId()) , _children(_main.Id()) , _startTime(connection == nullptr ? (TimePoint::min()) : (SteadyClock::now() + std::chrono::seconds(TYPICAL_STARTUP_TIME))) - { // IsOperation true till calculated time (microseconds) - } - ~MemoryObserverImpl() + , _adminLock() { } + ~MemoryObserverImpl() override = default; + + MemoryObserverImpl(const MemoryObserverImpl&) = delete; + MemoryObserverImpl& operator=(const MemoryObserverImpl&) = delete; - public: uint64_t Resident() const override { uint32_t result(0); @@ -451,10 +489,13 @@ namespace WebKitBrowser { uint8_t Processes() const override { // Refresh the children list !!! + _adminLock.Lock(); _children = Core::ProcessInfo::Iterator(_main.Id()); + _adminLock.Unlock(); + return ((_startTime == TimePoint::min()) || (_main.IsActive() == true) ? 1 : 0) + _children.Count(); } - const bool IsOperational() const override + bool IsOperational() const override { uint32_t requiredProcesses = 0; @@ -464,10 +505,12 @@ namespace WebKitBrowser { // In the end we check if all bits are 0, what means all mandatory processes are still running. requiredProcesses = (0xFFFFFFFF >> (32 - RequiredChildren)); + _adminLock.Lock(); if (_children.Count() < RequiredChildren) { // Refresh the children list !!! _children = Core::ProcessInfo::Iterator(_main.Id()); } + _adminLock.Unlock(); //!< If there are less children than in the the mandatoryProcesses struct, we are done and return false. if (_children.Count() >= RequiredChildren) { @@ -495,8 +538,49 @@ namespace WebKitBrowser { return (((requiredProcesses == 0) || (true == IsStarting())) && (true == _main.IsActive())); } + uint32_t Processes(RPC::IStringIterator*& processnames) const override { + _adminLock.Lock(); + if (_children.Count() < RequiredChildren) { + // Refresh the children list !!! + _children = Core::ProcessInfo::Iterator(_main.Id()); + } + Core::ProcessInfo::Iterator children(_children); + _adminLock.Unlock(); + + std::list processes; + children.Reset(); + while (children.Next() == true) { + processes.push_back(children.Current().Name()); + } + + processnames = Core::Service::Create(processes); + + return Core::ERROR_NONE; + } + + uint32_t Process(const string& processname, Exchange::IProcessMemory*& process) const override { + uint32_t result = Core::ERROR_UNAVAILABLE; + process = nullptr; + + _adminLock.Lock(); + Core::ProcessInfo::Iterator children(_children); + _adminLock.Unlock(); + + children.Reset(); + while (children.Next() == true ) { + if (children.Current().Name() == processname ) { + process = Core::Service::Create(children.Current().Id()); + result = Core::ERROR_NONE; + break; + } + } + + return result; + } + BEGIN_INTERFACE_MAP(MemoryObserverImpl) INTERFACE_ENTRY(Exchange::IMemory) + INTERFACE_ENTRY(Exchange::IMemoryExtended) END_INTERFACE_MAP private: @@ -509,6 +593,7 @@ namespace WebKitBrowser { Core::ProcessInfo _main; mutable Core::ProcessInfo::Iterator _children; TimePoint _startTime; // !< Reference for monitor + mutable Core::CriticalSection _adminLock; // note IMemory could be used from multiple threads (plugins)!! }; Exchange::IMemory* MemoryObserver(const RPC::IRemoteConnection* connection) diff --git a/WebKitBrowser/WebKitBrowser.h b/WebKitBrowser/WebKitBrowser.h index c2cad5f920..28fbe11394 100644 --- a/WebKitBrowser/WebKitBrowser.h +++ b/WebKitBrowser/WebKitBrowser.h @@ -67,9 +67,6 @@ namespace Plugin { class WebKitBrowser : public PluginHost::IPlugin, public PluginHost::IWeb, public PluginHost::JSONRPC { private: - WebKitBrowser(const WebKitBrowser&) = delete; - WebKitBrowser& operator=(const WebKitBrowser&) = delete; - class Notification : public RPC::IRemoteConnection::INotification, public PluginHost::IStateControl::INotification, public Exchange::IWebBrowser::INotification, @@ -85,9 +82,7 @@ namespace Plugin { { ASSERT(parent != nullptr); } - ~Notification() override - { - } + ~Notification() override = default; public: void LoadFinished(const string& URL, int32_t code) override @@ -162,9 +157,7 @@ namespace Plugin { Add(_T("hidden"), &Hidden); Add(_T("path"), &Path); } - ~Data() - { - } + ~Data() = default; public: Core::JSON::String URL; @@ -175,6 +168,8 @@ namespace Plugin { }; public: + WebKitBrowser(const WebKitBrowser&) = delete; + WebKitBrowser& operator=(const WebKitBrowser&) = delete; WebKitBrowser() : _skipURL(0) , _connectionId(0) @@ -189,9 +184,7 @@ namespace Plugin { { } - ~WebKitBrowser() override - { - } + ~WebKitBrowser() override = default; inline static bool EnvironmentOverride(const bool configFlag) { diff --git a/WebKitBrowser/WebKitImplementation.cpp b/WebKitBrowser/WebKitImplementation.cpp index 076ddf8cf8..db972a45e3 100644 --- a/WebKitBrowser/WebKitImplementation.cpp +++ b/WebKitBrowser/WebKitImplementation.cpp @@ -116,7 +116,7 @@ namespace Plugin { static WKPageNavigationClientV0 _handlerWebKit = { { 0, nullptr }, // decidePolicyForNavigationAction - [](WKPageRef, WKNavigationActionRef, WKFramePolicyListenerRef listener, WKTypeRef, const void* customData) { + [](WKPageRef, WKNavigationActionRef, WKFramePolicyListenerRef listener, WKTypeRef, const void* /* customData */) { WKFramePolicyListenerUse(listener); }, decidePolicyForNavigationResponse, @@ -152,7 +152,7 @@ namespace Plugin { WKGeolocationProviderV0 _handlerGeolocationProvider = { { 0, nullptr }, // startUpdating - [](WKGeolocationManagerRef geolocationManager, const void* clientInfo) { + [](WKGeolocationManagerRef geolocationManager, const void* /* clientInfo */) { std::cerr << "in WKGeolocationProviderV0::startUpdating" << std::endl; WKGeolocationPositionRef position = WKGeolocationPositionCreate(0.0, 51.49, 4.40, 1.0); WKGeolocationManagerProviderDidChangePosition(geolocationManager, position); @@ -195,7 +195,7 @@ namespace Plugin { nullptr, // exceededDatabaseQuota nullptr, // runOpenPanel // decidePolicyForGeolocationPermissionRequest - [](WKPageRef page, WKFrameRef frame, WKSecurityOriginRef origin, WKGeolocationPermissionRequestRef permissionRequest, const void* clientInfo) { + [](WKPageRef /* page */, WKFrameRef /* frame */, WKSecurityOriginRef /* origin */, WKGeolocationPermissionRequestRef permissionRequest, const void* /* clientInfo */) { WKGeolocationPermissionRequestAllow(permissionRequest); }, nullptr, // headerHeight @@ -210,7 +210,7 @@ namespace Plugin { nullptr, // createNewPage_deprecatedForUseWithV1 nullptr, // mouseDidMoveOverElement // decidePolicyForNotificationPermissionRequest - [](WKPageRef page, WKSecurityOriginRef origin, WKNotificationPermissionRequestRef permissionRequest, const void* clientInfo) { + [](WKPageRef /* page */, WKSecurityOriginRef /* origin */, WKNotificationPermissionRequestRef permissionRequest, const void* /* clientInfo */) { WKNotificationPermissionRequestAllow(permissionRequest); }, nullptr, // unavailablePluginButtonClicked_deprecatedForUseWithV1 @@ -248,7 +248,12 @@ namespace Plugin { nullptr, // checkUserMediaPermissionForOrigin nullptr, // runBeforeUnloadConfirmPanel nullptr, // fullscreenMayReturnToInline - willAddDetailedMessageToConsole, + //willAddDetailedMessageToConsole, + [](WKPageRef, WKStringRef /* source */, WKStringRef, uint64_t line, uint64_t column, WKStringRef message, WKStringRef, const void* /* clientInfo */) { + TRACE_GLOBAL(BrowserConsoleLog, (message, line, column)); + }, + nullptr, // requestPointerLock + nullptr // didLosePointerLock }; WKNotificationProviderV0 _handlerNotificationProvider = { @@ -1380,9 +1385,7 @@ static GSourceFuncs _handlerIntervention = _adminLock.Lock(); result = _cookieJar.Unpack(version, checksum, payload); _adminLock.Unlock(); - - if (result == Core::ERROR_NONE) - { + if (result == Core::ERROR_NONE) { g_main_context_invoke( _context, [](gpointer customdata) -> gboolean { @@ -1514,14 +1517,13 @@ static GSourceFuncs _handlerIntervention = } std::vector cookieVector; size_t size = cookies ? WKArrayGetSize(cookies) : 0; - if (size > 0) - { + if (size > 0) { cookieVector.reserve(size); - for (size_t i = 0; i < size; ++i) - { + for (size_t i = 0; i < size; ++i) { WKCookieRef cookie = static_cast(WKArrayGetItemAtIndex(cookies, i)); - if (WKCookieGetSession(cookie)) + if (WKCookieGetSession(cookie)) { continue; + } SoupCookie* soupCookie = toSoupCookie(cookie); gchar *cookieHeader = soup_cookie_to_set_cookie_header(soupCookie); cookieVector.push_back(cookieHeader); @@ -1543,16 +1545,17 @@ static GSourceFuncs _handlerIntervention = GList* cookies_list = nullptr; for (auto& cookie : cookies) { SoupCookie* sc = soup_cookie_parse(cookie.c_str(), nullptr); - if (!sc) + if (!sc) { continue; + } const char* domain = soup_cookie_get_domain(sc); - if (!domain) + if (!domain) { continue; + } // soup_cookie_parse() may prepend '.' to the domain, // check the original cookie string and remove '.' if needed - if (domain[0] == '.') - { + if (domain[0] == '.') { const char kDomainNeedle[] = "domain="; const size_t kDomainNeedleLength = sizeof(kDomainNeedle) - 1; auto it = std::search( @@ -1560,10 +1563,10 @@ static GSourceFuncs _handlerIntervention = [](const char c1, const char c2) { return ::tolower(c1) == c2; }); - if (it != cookie.end()) + if (it != cookie.end()) { it += kDomainNeedleLength; - if (it != cookie.end() && *it != '.' && *it != ';') - { + } + if (it != cookie.end() && *it != '.' && *it != ';') { char* adjustedDomain = g_strdup(domain + 1); soup_cookie_set_domain(sc, adjustedDomain); } @@ -1605,15 +1608,16 @@ static GSourceFuncs _handlerIntervention = for (const auto& cookie : cookies) { std::unique_ptr sc(soup_cookie_parse(cookie.c_str(), nullptr), soup_cookie_free); - if (!sc) + if (!sc) { continue; + } const char* domain = soup_cookie_get_domain(sc.get()); - if (!domain) + if (!domain) { continue; + } // soup_cookie_parse() may prepend '.' to the domain, // check the original cookie string and remove '.' if needed - if (domain[0] == '.') - { + if (domain[0] == '.') { const char kDomainNeedle[] = "domain="; const size_t kDomainNeedleLength = sizeof(kDomainNeedle) - 1; auto it = std::search( @@ -1621,10 +1625,10 @@ static GSourceFuncs _handlerIntervention = [](const char c1, const char c2) { return ::tolower(c1) == c2; }); - if (it != cookie.end()) + if (it != cookie.end()) { it += kDomainNeedleLength; - if (it != cookie.end() && *it != '.' && *it != ';') - { + } + if (it != cookie.end() && *it != '.' && *it != ';') { char* adjustedDomain = g_strdup(domain + 1); soup_cookie_set_domain(sc.get(), adjustedDomain); } @@ -1916,7 +1920,6 @@ static GSourceFuncs _handlerIntervention = uint32_t Identifier(string& id) const override { - uint32_t status = Core::ERROR_UNAVAILABLE; PluginHost::ISubSystem* subSystem = _service->SubSystems(); if (subSystem) { const PluginHost::ISubSystem::IIdentifier* identifier(subSystem->Get()); @@ -2271,7 +2274,8 @@ static GSourceFuncs _handlerIntervention = // Disk Cache Dir if (_config.DiskCacheDir.Value().empty() == false) { - Core::SystemInfo::SetEnvironment(_T("XDG_CACHE_HOME"), _config.DiskCacheDir.Value(), !environmentOverride); + _config.DiskCacheDir = _service->Substitute(_config.DiskCacheDir.Value()); + Core::SystemInfo::SetEnvironment(_T("XDG_CACHE_HOME"), _config.DiskCacheDir.Value(), !environmentOverride); } if (_config.XHRCache.Value() == false) { @@ -2280,9 +2284,14 @@ static GSourceFuncs _handlerIntervention = // Enable cookie persistent storage if (_config.CookieStorage.Value().empty() == false) { + _config.CookieStorage = _service->Substitute(_config.CookieStorage.Value()); Core::SystemInfo::SetEnvironment(_T("WPE_SHELL_COOKIE_STORAGE"), _T("1"), !environmentOverride); } + if (_config.LocalStorage.Value().empty() == false) { + _config.LocalStorage = _service->Substitute(_config.LocalStorage.Value()); + } + // Use cairo noaa compositor if (_config.Compositor.Value().empty() == false) { Core::SystemInfo::SetEnvironment(_T("CAIRO_GL_COMPOSITOR"), _config.Compositor.Value(), !environmentOverride); @@ -2630,8 +2639,9 @@ static GSourceFuncs _handlerIntervention = { if (type == WEBKIT_POLICY_DECISION_TYPE_RESPONSE) { auto *response = webkit_response_policy_decision_get_response(WEBKIT_RESPONSE_POLICY_DECISION(decision)); - if (webkit_uri_response_is_main_frame(response)) + if (webkit_uri_response_is_main_frame(response)) { browser->SetResponseHTTPStatusCode(webkit_uri_response_get_status_code(response)); + } } webkit_policy_decision_use(decision); return TRUE; @@ -2660,7 +2670,7 @@ static GSourceFuncs _handlerIntervention = static void loadFailedCallback(WebKitWebView*, WebKitLoadEvent loadEvent, const gchar* failingURI, GError* error, WebKitImplementation* browser) { string message(string("{ \"url\": \"") + failingURI + string("\", \"Error message\": \"") + error->message + string("\", \"loadEvent\":") + Core::NumberType(loadEvent).Text() + string(" }")); - SYSLOG(Trace::Information, (_T("LoadFailed: %s"), message.c_str())); + SYSLOG(Logging::Notification, (_T("LoadFailed: %s"), message.c_str())); if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED)) { browser->_ignoreLoadFinishedOnce = true; return; @@ -2671,13 +2681,13 @@ static GSourceFuncs _handlerIntervention = { switch (reason) { case WEBKIT_WEB_PROCESS_CRASHED: - SYSLOG(Trace::Fatal, (_T("CRASH: WebProcess crashed: exiting ..."))); + SYSLOG_GLOBAL(Logging::Fatal, (_T("CRASH: WebProcess crashed: exiting ..."))); break; case WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT: - SYSLOG(Trace::Fatal, (_T("CRASH: WebProcess terminated due to memory limit: exiting ..."))); + SYSLOG_GLOBAL(Logging::Fatal, (_T("CRASH: WebProcess terminated due to memory limit: exiting ..."))); break; case WEBKIT_WEB_PROCESS_TERMINATED_BY_API: - SYSLOG(Trace::Fatal, (_T("CRASH: WebProcess terminated by API"))); + SYSLOG_GLOBAL(Logging::Fatal, (_T("CRASH: WebProcess terminated by API"))); break; } g_signal_handlers_block_matched(webView, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, browser); @@ -2685,7 +2695,8 @@ static GSourceFuncs _handlerIntervention = { virtual void Dispatch() { exit(1); } }; - Core::IWorkerPool::Instance().Submit(Core::proxy_cast(Core::ProxyType::Create())); +// Core::IWorkerPool::Instance().Submit(Core::proxy_cast(Core::ProxyType::Create())); + Core::IWorkerPool::Instance().Submit(Core::ProxyType(Core::ProxyType::Create())); } static void closeCallback(VARIABLE_IS_NOT_USED WebKitWebView* webView, WebKitImplementation* browser) { @@ -2733,7 +2744,7 @@ static GSourceFuncs _handlerIntervention = return true; } #if defined(ENABLE_CLOUD_COOKIE_JAR) - static void cookieManagerChangedCallback(WebKitCookieManager* manager, WebKitImplementation* browser) { + static void cookieManagerChangedCallback(WebKitCookieManager* /* manager */, WebKitImplementation* browser) { browser->NotifyCookieJarChanged(); } #endif @@ -3314,7 +3325,7 @@ static GSourceFuncs _handlerIntervention = gchar* scriptContent; auto success = g_file_get_contents(path.c_str(), &scriptContent, nullptr, nullptr); if (!success) { - SYSLOG(Trace::Error, (_T("Unable to read user script '%s'"), path.c_str())); + SYSLOG(Logging::Error, (_T("Unable to read user script '%s'"), path.c_str())); return; } AddUserScriptImpl(scriptContent, false); @@ -3364,8 +3375,9 @@ static GSourceFuncs _handlerIntervention = void CheckWebProcess() { - if ( _webProcessCheckInProgress ) + if ( _webProcessCheckInProgress ) { return; + } _webProcessCheckInProgress = true; @@ -3392,20 +3404,23 @@ static GSourceFuncs _handlerIntervention = void DidReceiveWebProcessResponsivenessReply(bool isWebProcessResponsive) { - if (_config.WatchDogHangThresholdInSeconds.Value() == 0 || _config.WatchDogCheckTimeoutInSeconds.Value() == 0) + if (_config.WatchDogHangThresholdInSeconds.Value() == 0 || _config.WatchDogCheckTimeoutInSeconds.Value() == 0) { return; + } // How many unresponsive replies to ignore before declaring WebProcess hang state const uint32_t kWebProcessUnresponsiveReplyDefaultLimit = _config.WatchDogHangThresholdInSeconds.Value() / _config.WatchDogCheckTimeoutInSeconds.Value(); - if (!_webProcessCheckInProgress) + if (!_webProcessCheckInProgress) { return; + } _webProcessCheckInProgress = false; - if (isWebProcessResponsive && _unresponsiveReplyNum == 0) + if (isWebProcessResponsive && _unresponsiveReplyNum == 0) { return; + } #ifdef WEBKIT_GLIB_API std::string activeURL(webkit_web_view_get_uri(_view)); @@ -3437,7 +3452,7 @@ static GSourceFuncs _handlerIntervention = _unresponsiveReplyNum = kWebProcessUnresponsiveReplyDefaultLimit; Logging::DumpSystemFiles(webprocessPID); if (syscall(__NR_tgkill, webprocessPID, webprocessPID, SIGFPE) == -1) { - SYSLOG(Trace::Error, (_T("tgkill failed, signal=%d process=%u errno=%d (%s)"), SIGFPE, webprocessPID, errno, strerror(errno))); + SYSLOG(Logging::Error, (_T("tgkill failed, signal=%d process=%u errno=%d (%s)"), SIGFPE, webprocessPID, errno, strerror(errno))); } } else { DeactivateBrowser(PluginHost::IShell::FAILURE); @@ -3449,7 +3464,7 @@ static GSourceFuncs _handlerIntervention = Logging::DumpSystemFiles(webprocessPID); if (syscall(__NR_tgkill, webprocessPID, webprocessPID, SIGFPE) == -1) { - SYSLOG(Trace::Error, (_T("tgkill failed, signal=%d process=%u errno=%d (%s)"), SIGFPE, webprocessPID, errno, strerror(errno))); + SYSLOG(Logging::Error, (_T("tgkill failed, signal=%d process=%u errno=%d (%s)"), SIGFPE, webprocessPID, errno, strerror(errno))); } } else if (_unresponsiveReplyNum == (2 * kWebProcessUnresponsiveReplyDefaultLimit)) { DeactivateBrowser(PluginHost::IShell::WATCHDOG_EXPIRED); @@ -3464,7 +3479,7 @@ static GSourceFuncs _handlerIntervention = if (self->_unresponsiveReplyNum > 0) { std::string activeURL(webkit_web_view_get_uri(self->_view)); - SYSLOG(Logging::Notification, (_T("WebProcess recovered after %d unresponsive replies, url=%s\n"), + SYSLOG_GLOBAL(Logging::Notification, (_T("WebProcess recovered after %d unresponsive replies, url=%s\n"), self->_unresponsiveReplyNum, activeURL.c_str())); self->_unresponsiveReplyNum = 0; } @@ -3478,7 +3493,7 @@ static GSourceFuncs _handlerIntervention = std::string activeURL = GetPageActiveURL(page); pid_t webprocessPID = WKPageGetProcessIdentifier(page); - SYSLOG(Logging::Notification, (_T("WebProcess recovered after %d unresponsive replies, pid=%u, url=%s\n"), + SYSLOG_GLOBAL(Logging::Notification, (_T("WebProcess recovered after %d unresponsive replies, pid=%u, url=%s\n"), self._unresponsiveReplyNum, webprocessPID, activeURL.c_str())); self._unresponsiveReplyNum = 0; } @@ -3544,7 +3559,7 @@ static GSourceFuncs _handlerIntervention = #ifndef WEBKIT_GLIB_API // Handles synchronous messages from injected bundle. - /* static */ void onDidReceiveSynchronousMessageFromInjectedBundle(WKContextRef context, WKStringRef messageName, + /* static */ void onDidReceiveSynchronousMessageFromInjectedBundle(WKContextRef /* context */, WKStringRef messageName, WKTypeRef messageBodyObj, WKTypeRef* returnData, const void* clientInfo) { int configLen = strlen(Tags::Config); @@ -3577,7 +3592,7 @@ static GSourceFuncs _handlerIntervention = } } - /* static */ void didStartProvisionalNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo) + /* static */ void didStartProvisionalNavigation(WKPageRef page, WKNavigationRef navigation, WKTypeRef /* userData */, const void* clientInfo) { WebKitImplementation* browser = const_cast(static_cast(clientInfo)); @@ -3593,7 +3608,7 @@ static GSourceFuncs _handlerIntervention = WKRelease(urlStringRef); } - /* static */ void didSameDocumentNavigation(const OpaqueWKPage* page, const OpaqueWKNavigation* nav, WKSameDocumentNavigationType type, const void* clientInfo, const void* info) + /* static */ void didSameDocumentNavigation(const OpaqueWKPage* page, const OpaqueWKNavigation* /* nav */, WKSameDocumentNavigationType type, const void* /* clientInfo */, const void* info) { if (type == kWKSameDocumentNavigationAnchorNavigation) { WebKitImplementation* browser = const_cast(static_cast(info)); @@ -3610,7 +3625,7 @@ static GSourceFuncs _handlerIntervention = } } - /* static */ void didFinishDocumentLoad(WKPageRef page, WKNavigationRef navigation, WKTypeRef userData, const void* clientInfo) + /* static */ void didFinishDocumentLoad(WKPageRef page, WKNavigationRef navigation, WKTypeRef /* userData */, const void* clientInfo) { WebKitImplementation* browser = const_cast(static_cast(clientInfo)); @@ -3626,7 +3641,7 @@ static GSourceFuncs _handlerIntervention = WKRelease(urlStringRef); } - /* static */ void requestClosure(const void* clientInfo) + /* static */ void requestClosure(const void* /* clientInfo */) { // WebKitImplementation* browser = const_cast(static_cast(clientInfo)); // TODO: @Igalia, make sure the clientInfo is actually holding the correct clientINfo, currently it is nullptr. For @@ -3636,7 +3651,7 @@ static GSourceFuncs _handlerIntervention = realBrowser->NotifyClosure(); } - /* static */ void onNotificationShow(WKPageRef page, WKNotificationRef notification, const void* clientInfo) + /* static */ void onNotificationShow(WKPageRef /* page */, WKNotificationRef notification, const void* clientInfo) { const WebKitImplementation* browser = static_cast(clientInfo); @@ -3656,7 +3671,7 @@ static GSourceFuncs _handlerIntervention = WKRelease(titleRef); } - /* static */ void onFrameDisplayed(WKViewRef view, const void* clientInfo) + /* static */ void onFrameDisplayed(WKViewRef /* view */, const void* clientInfo) { WebKitImplementation* browser = const_cast(static_cast(clientInfo)); browser->SetFPS(); @@ -3677,8 +3692,7 @@ static GSourceFuncs _handlerIntervention = /* static */ void decidePolicyForNavigationResponse(WKPageRef, WKNavigationResponseRef response, WKFramePolicyListenerRef listener, WKTypeRef, const void* clientInfo) { WKFramePolicyListenerUse(listener); - if (WKNavigationResponseIsMainFrame(response)) - { + if (WKNavigationResponseIsMainFrame(response)) { WebKitImplementation* browser = const_cast(static_cast(clientInfo)); WKURLResponseRef urlResponse = WKNavigationResponseGetURLResponse(response); browser->SetResponseHTTPStatusCode(WKURLResponseHTTPStatusCode(urlResponse)); @@ -3699,7 +3713,7 @@ static GSourceFuncs _handlerIntervention = string url = GetPageActiveURL(page); string message(string("{ \"url\": \"") + url + string("\", \"Error code\":") + Core::NumberType(errorcode).Text() + string(" }")); - SYSLOG(Trace::Information, (_T("LoadFailed: %s"), message.c_str())); + SYSLOG(Logging::Notification, (_T("LoadFailed: %s"), message.c_str())); bool isCanceled = errorDomain && @@ -3707,8 +3721,9 @@ static GSourceFuncs _handlerIntervention = WebKitNetworkErrorCancelled == WKErrorGetErrorCode(error); WKRelease(errorDomain); - if (isCanceled) + if (isCanceled) { return; + } WebKitImplementation* browser = const_cast(static_cast(clientInfo)); browser->OnLoadFailed(url); @@ -3716,7 +3731,7 @@ static GSourceFuncs _handlerIntervention = /* static */ void webProcessDidCrash(WKPageRef, const void*) { - SYSLOG(Trace::Fatal, (_T("CRASH: WebProcess crashed, exiting..."))); + SYSLOG_GLOBAL(Logging::Fatal, (_T("CRASH: WebProcess crashed: exiting ..."))); exit(1); } diff --git a/WebKitBrowser/YouTube.conf.in b/WebKitBrowser/YouTube.conf.in new file mode 100644 index 0000000000..f28f69f068 --- /dev/null +++ b/WebKitBrowser/YouTube.conf.in @@ -0,0 +1,75 @@ +precondition = ["Internet"] +startmode = "@PLUGIN_YOUTUBE_STARTMODE@" +startuporder = "@PLUGIN_YOUTUBE_STARTUPORDER@" + +configuration = JSON() + +configuration.add("url", "@PLUGIN_YOUTUBE_STARTURL@@PLUGIN_YOUTUBE_STARTURL_QUERYSTRING@") +configuration.add("useragent", "@PLUGIN_YOUTUBE_USERAGENT@") + +if not boolean("@WEBKIT_GLIB_API@"): + configuration.add("injectedbundle", "libWPEInjectedBundle@CMAKE_SHARED_LIBRARY_SUFFIX@") +else: + configuration.add("extensiondir", "@PLUGIN_WEBKITBROWSER_EXTENSION_DIRECTORY@") + +configuration.add("transparent", "@PLUGIN_WEBKITBROWSER_TRANSPARENT@") +configuration.add("compositor", "@PLUGIN_HTML_APP_COMPOSITOR@") +configuration.add("inspector", "@PLUGIN_YOUTUBE_WEBINSPECTOR_ADDRESS@") +configuration.add("fps", "true") +configuration.add("cursor", "false") +configuration.add("touch", "false") +configuration.add("msebuffers", "@PLUGIN_YOUTUBE_MSEBUFFERS@") +configuration.add("thunderdecryptorpreference", "@PLUGIN_WEBKITBROWSER_THUNDER_DECRYPTOR_PREFERENCE@") +configuration.add("memoryprofile", "@PLUGIN_WEBKITBROWSER_MEMORYPROFILE@") +configuration.add("mediacontenttypesrequiringhardwaresupport", "@PLUGIN_WEBKITBROWSER_MEDIA_CONTENT_TYPES_REQUIRING_HARDWARE_SUPPORT@") +configuration.add("mediadiskcache", "@PLUGIN_WEBKITBROWSER_MEDIADISKCACHE@") +configuration.add("diskcache", "@PLUGIN_WEBKITBROWSER_DISKCACHE@") +configuration.add("xhrcache", "@PLUGIN_WEBKITBROWSER_XHRCACHE@") +configuration.add("webgl", "@PLUGIN_YOUTUBE_WEBGL@") +configuration.add("windowclose", "@PLUGIN_WEBKITBROWSER_WINDOWCLOSE@") +configuration.add("threadedpainting", "@PLUGIN_WEBKITBROWSER_THREADEDPAINTING@") +configuration.add("height", "@PLUGIN_YOUTUBE_HEIGHT@") +configuration.add("width", "@PLUGIN_YOUTUBE_WIDTH@") +configuration.add("clientidentifier", "@PLUGIN_WEBKITBROWSER_CLIENTIDENTIFIER@") +configuration.add("localstorageenabled", "@PLUGIN_YOUTUBE_LOCALSTORAGE_ENABLE@") +configuration.add("localstorage", "@PLUGIN_WEBKITBROWSER_LOCALSTORAGE@") +configuration.add("cookiestorage", "@PLUGIN_WEBKITBROWSER_COOKIESTORAGE@") + +if "@PLUGIN_WEBKITBROWSER_PTSOFFSET@" != "0": + configuration.add("ptsoffset", "@PLUGIN_WEBKITBROWSER_PTSOFFSET@") +configuration.add("execpath", "@PLUGIN_WEBKITBROWSER_ALTERNATIVE_EXEC_PATH@") +configuration.add("proxy", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY@") +configuration.add("proxyexclusion", "@PLUGIN_WEBKITBROWSER_HTTP_PROXY_EXCLUSION@") +configuration.add("clientcert", "@PLUGIN_WEBKITBROWSER_CLIENT_CERT@") +configuration.add("clientcertkey", "@PLUGIN_WEBKITBROWSER_CLIENT_CERT_KEY@") +configuration.add("logtosystemconsoleenabled", "@PLUGIN_WEBKITBROWSER_LOGTOSYSTEMCONSOLE@") + +configuration.add("secure", "@PLUGIN_WEBKITBROWSER_SECURE@") +configuration.add("watchdogchecktimeoutinseconds", 10) +configuration.add("watchdoghangthresholdtinseconds", 60) +rootobject = JSON() +rootobject.add("mode", "@PLUGIN_YOUTUBE_MODE@") +rootobject.add("locator", "lib@PLUGIN_WEBKITBROWSER_IMPLEMENTATION@.so") +rootobject.add("user", "@PLUGIN_WEBKITBROWSER_USER@") +rootobject.add("group", "@PLUGIN_WEBKITBROWSER_GROUP@") +configuration.add("root", rootobject) + +javascript = JSON() +javascript.add("useJIT", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_JIT@") else "false") +javascript.add("useDFG", "true" if boolean("@PLUGIN_WEBKITBROWSER_ENABLE_DFG@") else "false") +configuration.add("javascript", javascript) + +webprocesssettings = JSON() +webprocesssettings.add("limit", "@PLUGIN_YOUTUBE_MEMORYPRESSURE_WEBPROCESS_SETTINGS_LIMIT@") +webprocesssettings.add("gpulimit", "@PLUGIN_YOUTUBE_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_LIMIT@") +webprocesssettings.add("gpufile", "@PLUGIN_YOUTUBE_MEMORYPRESSURE_WEBPROCESS_SETTINGS_GPU_FILE@") +webprocesssettings.add("pollinterval", "@PLUGIN_YOUTUBE_MEMORYPRESSURE_WEBPROCESS_SETTINGS_POLLINTERVAL@") + +networkprocesssettings = JSON() +networkprocesssettings.add("limit", "@PLUGIN_YOUTUBE_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_LIMIT@") +networkprocesssettings.add("pollinterval", "@PLUGIN_YOUTUBE_MEMORYPRESSURE_NETWORKPROCESS_SETTINGS_POLLINTERVAL@") + +memory = JSON() +memory.add("webprocesssettings", webprocesssettings) +memory.add("networkprocesssettings", networkprocesssettings) +configuration.add("memory", memory)