diff --git a/Dictionary/Dictionary.cpp b/Dictionary/Dictionary.cpp index 75a023ded..e663ec7c8 100644 --- a/Dictionary/Dictionary.cpp +++ b/Dictionary/Dictionary.cpp @@ -27,7 +27,7 @@ ENUM_CONVERSION_BEGIN(Plugin::Dictionary::enumType) { Plugin::Dictionary::enumType::PERSISTENT, _TXT("persistent") }, { Plugin::Dictionary::enumType::CLOSURE, _TXT("closure") }, - ENUM_CONVERSION_END(Plugin::Dictionary::enumType); + ENUM_CONVERSION_END(Plugin::Dictionary::enumType) namespace Plugin { diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 16312b012..180b6ed4d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,6 +37,7 @@ option(EXAMPLE_IOCONNECTOR_TEST "Include IOConnector test suite" OFF) option(EXAMPLE_MESSAGECONTROL_UDP_CLIENT "Include UDP output client for message control" OFF) option(EXAMPLE_DYNAMICLOADING "Include dynamic loading examples" OFF) option(EXAMPLE_SIMPLECOMRPC_TEST "Include Simple COMRPC test client" OFF) +option(EXAMPLE_FIREBOLTPLUGIN "Include Simple Firebolt Privacy module" OFF) if(EXAMPLE_COMRPCCLIENT) add_subdirectory(COMRPCClient) @@ -92,3 +93,13 @@ if (EXAMPLE_SIMPLECOMRPC_TEST) add_subdirectory(SimpleCOMRPCPluginServer) add_subdirectory(SimpleCOMRPCClient) endif() + +if (EXAMPLE_FIREBOLTPRIVACY) + add_subdirectory(FireboltPrivacy) +endif() + +if (EXAMPLE_FIREBOLTDISCOVERY) + add_subdirectory(FireboltDiscovery) +endif() +add_subdirectory(FireboltPrivacy) +add_subdirectory(FireboltDiscovery) diff --git a/examples/FireboltDiscovery/.FireboltDiscoveryImplementation.h.swp b/examples/FireboltDiscovery/.FireboltDiscoveryImplementation.h.swp new file mode 100644 index 000000000..5ad2d2439 Binary files /dev/null and b/examples/FireboltDiscovery/.FireboltDiscoveryImplementation.h.swp differ diff --git a/examples/FireboltDiscovery/CMakeLists.txt b/examples/FireboltDiscovery/CMakeLists.txt new file mode 100644 index 000000000..827e4fea3 --- /dev/null +++ b/examples/FireboltDiscovery/CMakeLists.txt @@ -0,0 +1,57 @@ +# If not stated otherwise in this file or this component's LICENSE file the +# following copyright and licenses apply: +# +# Copyright 2020 Metrological +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project(FireboltDiscovery) + +cmake_minimum_required(VERSION 3.3) + +find_package(WPEFramework) + +project_version(1.0.0) + +set(MODULE_NAME ${NAMESPACE}${PROJECT_NAME}) + +message("Setup ${MODULE_NAME} v${PROJECT_VERSION}") + +set(PLUGIN_FIREBOLTDISCOVERY_AUTOSTART "Activated" CACHE STRING "Automatically start FireboltDiscovery plugin") + +find_package(${NAMESPACE}Core REQUIRED) +find_package(${NAMESPACE}Messaging REQUIRED) +find_package(${NAMESPACE}Plugins REQUIRED) +find_package(${NAMESPACE}Definitions REQUIRED) +find_package(CompileSettingsDebug CONFIG REQUIRED) + +add_library(${MODULE_NAME} SHARED + FireboltDiscovery.cpp + FireboltDiscoveryImplementation.cpp + Module.cpp) + + +set_target_properties(${MODULE_NAME} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + +target_link_libraries(${MODULE_NAME} + PRIVATE + CompileSettingsDebug::CompileSettingsDebug + ${NAMESPACE}Plugins::${NAMESPACE}Plugins + ${NAMESPACE}Definitions::${NAMESPACE}Definitions) + +install(TARGETS ${MODULE_NAME} + DESTINATION lib/${STORAGE_DIRECTORY}/plugins) + +write_config() diff --git a/examples/FireboltDiscovery/FireboltDiscovery.conf.in b/examples/FireboltDiscovery/FireboltDiscovery.conf.in new file mode 100644 index 000000000..98238b4ae --- /dev/null +++ b/examples/FireboltDiscovery/FireboltDiscovery.conf.in @@ -0,0 +1,10 @@ +startmode = "@PLUGIN_FIREBOLTDISCOVERY_AUTOSTART@" +callsign = "Privacy" + +configuration = JSON() + +rootobject = JSON() +rootobject.add("mode", "Local") +rootobject.add("locator", "lib@MODULE_NAME@.so") +configuration.add("root", rootobject) + diff --git a/examples/FireboltDiscovery/FireboltDiscovery.cpp b/examples/FireboltDiscovery/FireboltDiscovery.cpp new file mode 100644 index 000000000..b85bbeafc --- /dev/null +++ b/examples/FireboltDiscovery/FireboltDiscovery.cpp @@ -0,0 +1,146 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FireboltDiscovery.h" +#include + +namespace WPEFramework { + +namespace Plugin +{ + + namespace { + + static Metadata metadata( + // Version + 1, 0, 0, + // Preconditions + {}, + // Terminations + {}, + // Controls + {} + ); + } + + + FireboltDiscovery::FireboltDiscovery() + : _connectionId(0) + , _service(nullptr) + , _fireboltDiscovery(nullptr) + { + } + +#if 0 + PluginHost::JSONRPC::classification FireboltDiscovery::CheckToken(const string& token, const string& method, const string& parameters){ + SYSLOG(Logging::Startup, (_T("Received Token: %s method: %s, Params: %s"), token.c_str(), method.c_str(), parameters.c_str())); + return PluginHost::JSONRPC::classification::VALID; + } +#endif + + const string FireboltDiscovery::Initialize(PluginHost::IShell * service) + { + string message; + + ASSERT(service != nullptr); + ASSERT(_service == nullptr); + ASSERT(_connectionId == 0); + ASSERT(_fireboltDiscovery == nullptr); + _service = service; + _service->AddRef(); + + // Register the Process::Notification stuff. The Remote process might die before we get a + // change to "register" the sink for these events !!! So do it ahead of instantiation. + + _fireboltDiscovery = service->Root(_connectionId, RPC::CommunicationTimeOut, _T("FireboltDiscoveryImplementation")); + if (_fireboltDiscovery != nullptr) { + + Exchange::IConfiguration* configFireboltDiscovery = _fireboltDiscovery->QueryInterface(); + if (configFireboltDiscovery != nullptr) { + if (configFireboltDiscovery->Configure(service) != Core::ERROR_NONE) { + message = _T("FireboltDiscovery could not be configured."); + } + configFireboltDiscovery->Release(); + configFireboltDiscovery = nullptr; + } + } + else { + message = _T("FireboltDiscovery could not be instantiated."); + } + //Exchange::JSONRPC::JFireboltDiscovery::Register(*this, _fireboltDiscovery); + Exchange::JSONRPC::JFireboltDiscovery::Register(*this, this); + + // On success return empty, to indicate there is no error text. + return (message); + } + + void FireboltDiscovery::Deinitialize(PluginHost::IShell* service VARIABLE_IS_NOT_USED) + { + if (_service != nullptr) { + ASSERT(_service == service); + + if (_fireboltDiscovery != nullptr) { + Exchange::JSONRPC::JFireboltDiscovery::Unregister(*this); + + RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + VARIABLE_IS_NOT_USED uint32_t result = _fireboltDiscovery->Release(); + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + _fireboltDiscovery = nullptr; + + // 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; + _connectionId = 0; + } + } + + string FireboltDiscovery::Information() const + { + // No additional info to report. + return (string()); + } + + Core::hresult FireboltDiscovery::SignIn(const Core::JSONRPC::Context& context, const bool param ) { + std::cout<<"Context appId: "<Id()) { + ASSERT(_service != nullptr); + Core::IWorkerPool::Instance().Submit(PluginHost::IShell::Job::Create(_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE)); + } + } + + + +} // namespace Plugin +} // namespace WPEFramework + diff --git a/examples/FireboltDiscovery/FireboltDiscovery.h b/examples/FireboltDiscovery/FireboltDiscovery.h new file mode 100644 index 000000000..56f0e8e25 --- /dev/null +++ b/examples/FireboltDiscovery/FireboltDiscovery.h @@ -0,0 +1,113 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#pragma once + +#include "Module.h" + +#include +#include +#include + +namespace WPEFramework { +namespace Plugin { + + class FireboltDiscovery : public PluginHost::IPlugin + , public PluginHost::JSONRPC + , public Exchange::JSONRPC::IFireboltDiscovery { + private: +#if 0 + class NotificationHandler : public RPC::IRemoteConnection::INotification, public Exchange::IFireboltDiscovery::INotification { + public: + NotificationHandler() = delete; + NotificationHandler(const NotificationHandler&) = delete; + NotificationHandler(NotificationHandler&&) = delete; + NotificationHandler& operator=(const NotificationHandler&) = delete; + NotificationHandler& operator=(NotificationHandler&&) = delete; + + NotificationHandler(FireboltDiscovery& parent) + : _parent(parent) + { + } + ~NotificationHandler() override = default; + + public: + void Activated(RPC::IRemoteConnection* /* connection */) override + { + } + void Deactivated(RPC::IRemoteConnection* connection) override + { + _parent.Deactivated(connection); + } + void Terminated (RPC::IRemoteConnection* /* connection */) override + { + } + + + void OnAllowResumePointsChanged(const bool allowResumePoint) override + { + _parent.OnAllowResumePointsChanged(allowResumePoint); + } + BEGIN_INTERFACE_MAP(NotificationHandler) + INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) + INTERFACE_ENTRY(Exchange::IFireboltDiscovery::INotification) + END_INTERFACE_MAP + + private: + FireboltDiscovery& _parent; + }; +#endif + public: + FireboltDiscovery(const FireboltDiscovery&) = delete; + FireboltDiscovery(FireboltDiscovery&&) = delete; + FireboltDiscovery& operator=(const FireboltDiscovery&) = delete; + FireboltDiscovery& operator=(FireboltDiscovery&) = delete; + + FireboltDiscovery(); + ~FireboltDiscovery() override = default; + + // Build QueryInterface implementation, specifying all possible interfaces to be returned. + BEGIN_INTERFACE_MAP(FireboltDiscovery) + INTERFACE_ENTRY(PluginHost::IPlugin) + INTERFACE_ENTRY(PluginHost::IDispatcher) + //INTERFACE_AGGREGATE(Exchange::IFDiscovery, _fireboltDiscovery) + END_INTERFACE_MAP + + public: + // IPlugin methods + // ------------------------------------------------------------------------------------------------------- + const string Initialize(PluginHost::IShell* service) override; + void Deinitialize(PluginHost::IShell* service) override; + string Information() const override; + Core::hresult SignIn(const Core::JSONRPC::Context& context, const bool param ) override; + + + private: + void Deactivated(RPC::IRemoteConnection* connection); + + private: + uint32_t _connectionId; + PluginHost::IShell* _service; + Exchange::IFDiscovery* _fireboltDiscovery; + + }; + +} // namespace Plugin +} // namespace WPEFramework diff --git a/examples/FireboltDiscovery/FireboltDiscoveryImplementation.cpp b/examples/FireboltDiscovery/FireboltDiscoveryImplementation.cpp new file mode 100644 index 000000000..25ea896c8 --- /dev/null +++ b/examples/FireboltDiscovery/FireboltDiscoveryImplementation.cpp @@ -0,0 +1,132 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FireboltDiscoveryImplementation.h" + +namespace WPEFramework { + +namespace Plugin +{ + class FireboltDiscoveryImplementation : public Exchange::IFDiscovery, + public Exchange::IConfiguration { + + private: + + class Config : public Core::JSON::Container { + public: + Config(const Config&) = delete; + Config(Config&&) = delete; + Config& operator=(const Config&) = delete; + Config& operator=(Config&&) = delete; + + Config() + : Core::JSON::Container() + , DictionaryCallSign() + { + Add(_T("callsign"), &DictionaryCallSign); + } + ~Config() override = default; + public: + Core::JSON::String DictionaryCallSign; + }; + + + public: + + FireboltDiscoveryImplementation(const FireboltDiscoveryImplementation&) = delete; + FireboltDiscoveryImplementation(FireboltDiscoveryImplementation&&) = delete; + FireboltDiscoveryImplementation& operator= (const FireboltDiscoveryImplementation&) = delete; + FireboltDiscoveryImplementation& operator= (FireboltDiscoveryImplementation&&) = delete; + + FireboltDiscoveryImplementation() + : _service(nullptr) + , _adminLock() + { + } + ~FireboltDiscoveryImplementation() override { + } + Core::hresult watched(const string& appId) { + std::cout<<"Received Watch request for appId"<AddRef(); + } + _adminLock.Unlock(); + + return Core::ERROR_NONE; + } + + Core::hresult Unregister(Exchange::IFireboltDiscovery::INotification* notification) override + { + ASSERT(notification != nullptr); + Core::hresult result = Core::ERROR_NONE; + + _adminLock.Lock(); + ASSERT(std::find(_notifications.begin(), _notifications.end(), notification) == _notifications.end()); + auto item = std::find(_notifications.begin(), _notifications.end(), notification); + if(item != _notifications.end()){ + notification->Release(); + _notifications.erase(item); + } + else { + result = Core::ERROR_INVALID_PARAMETER; + } + _adminLock.Unlock(); + + return result; + } +#endif + + + + uint32_t Configure(PluginHost::IShell* service) override { + + ASSERT( service != nullptr); + uint32_t result = Core::ERROR_NONE; + Config config; + config.FromString(service->ConfigLine()); + _service = service; + return result; + } + + BEGIN_INTERFACE_MAP(FireboltDiscoveryImplementation) + INTERFACE_ENTRY(Exchange::IFDiscovery) + INTERFACE_ENTRY(Exchange::IConfiguration) + END_INTERFACE_MAP + + private: + PluginHost::IShell* _service; + mutable Core::CriticalSection _adminLock; + bool _allowResumePoints; + }; + + SERVICE_REGISTRATION(FireboltDiscoveryImplementation, 1, 0, 0) +} // namespace Plugin +} // namespace WPEFramework + diff --git a/examples/FireboltDiscovery/FireboltDiscoveryImplementation.h b/examples/FireboltDiscovery/FireboltDiscoveryImplementation.h new file mode 100644 index 000000000..e9df412a6 --- /dev/null +++ b/examples/FireboltDiscovery/FireboltDiscoveryImplementation.h @@ -0,0 +1,28 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "Module.h" +#include +#include +#include +#include + +static constexpr TCHAR PrivacyNamespace[] = _T("FireboltDiscovery"); +static constexpr TCHAR PrivacyKeyAllowResume[] = _T("AllowResumePoints"); diff --git a/examples/FireboltDiscovery/FireboltDiscoveryPlugin.json b/examples/FireboltDiscovery/FireboltDiscoveryPlugin.json new file mode 100644 index 000000000..650f542e3 --- /dev/null +++ b/examples/FireboltDiscovery/FireboltDiscoveryPlugin.json @@ -0,0 +1,35 @@ +{ + "$schema": "plugin.schema.json", + "info": { + "title": "Firebolt Privacy Plugin", + "callsign": "Privacy", + "locator": "libWPEFrameworkFireboltDiscovery.so", + "status": "production", + "description": [ + "The Firebolt Privacy plugin provides functionality to store user settings either in local or in remote." + ], + "version": "1.0" + }, + "configuration": { + "type": "object", + "properties": { + "configuration": { + "type": "object", + "required": [], + "properties": { + "devicemanifest": { + "type": "string", + "description": "Device manifest filename (default: firebolt-device-manifest.json)" + }, + "fireboltconfigpath": { + "type": "string", + "description": "Path where firebolt configurations are present (default: /etc/)" + } + } + } + } + }, + "interface": { + "$ref": "${cppinterfacedir}/IFireboltDiscovery.h" + } +} diff --git a/examples/FireboltDiscovery/Module.cpp b/examples/FireboltDiscovery/Module.cpp new file mode 100644 index 000000000..393d6a267 --- /dev/null +++ b/examples/FireboltDiscovery/Module.cpp @@ -0,0 +1,22 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Module.h" + +MODULE_NAME_DECLARATION(BUILD_REFERENCE) diff --git a/examples/FireboltDiscovery/Module.h b/examples/FireboltDiscovery/Module.h new file mode 100644 index 000000000..2356d17f6 --- /dev/null +++ b/examples/FireboltDiscovery/Module.h @@ -0,0 +1,31 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef MODULE_NAME +#define MODULE_NAME Plugin_FireboltDiscovery +#endif + +#include +#include +#include + +#undef EXTERNAL +#define EXTERNAL diff --git a/examples/FireboltPrivacy.conf.in b/examples/FireboltPrivacy.conf.in new file mode 100644 index 000000000..afe64eba2 --- /dev/null +++ b/examples/FireboltPrivacy.conf.in @@ -0,0 +1,10 @@ +startmode = "@PLUGIN_FIREBOLTPRIVACY_AUTOSTART@" +callsign = "Privacy" + +configuration = JSON() + +rootobject = JSON() +rootobject.add("mode", "Local") +rootobject.add("locator", "lib@MODULE_NAME@.so") +configuration.add("root", rootobject) + diff --git a/examples/FireboltPrivacy.cpp b/examples/FireboltPrivacy.cpp new file mode 100644 index 000000000..99562dcb2 --- /dev/null +++ b/examples/FireboltPrivacy.cpp @@ -0,0 +1,145 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FireboltPrivacy.h" +#include + +namespace WPEFramework { + +namespace Plugin +{ + + namespace { + + static Metadata metadata( + // Version + 1, 0, 0, + // Preconditions + {}, + // Terminations + {}, + // Controls + {} + ); + } + + + FireboltPrivacy::FireboltPrivacy() + : JSONRPC(std::bind(&FireboltPrivacy::CheckToken, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) + , _connectionId(0) + , _service(nullptr) + , _fireboltPrivacy(nullptr) + , _notificationSink(*this) + { + } + + PluginHost::JSONRPC::classification FireboltPrivacy::CheckToken(const string& token, const string& method, const string& parameters){ + SYSLOG(Logging::Startup, (_T("Received Token: %s method: %s, Params: %s"), token.c_str(), method.c_str(), parameters.c_str())); + return PluginHost::JSONRPC::classification::VALID; + } + + const string FireboltPrivacy::Initialize(PluginHost::IShell * service) + { + string message; + + ASSERT(service != nullptr); + ASSERT(_service == nullptr); + ASSERT(_connectionId == 0); + ASSERT(_fireboltPrivacy == nullptr); + _service = service; + _service->AddRef(); + + // Register the Process::Notification stuff. The Remote process might die before we get a + // change to "register" the sink for these events !!! So do it ahead of instantiation. + _service->Register(&_notificationSink); + + _fireboltPrivacy = service->Root(_connectionId, RPC::CommunicationTimeOut, _T("FireboltPrivacyImplementation")); + if (_fireboltPrivacy != nullptr) { + _fireboltPrivacy->Register(&_notificationSink); + + Exchange::IConfiguration* configFireboltPrivacy = _fireboltPrivacy->QueryInterface(); + if (configFireboltPrivacy != nullptr) { + if (configFireboltPrivacy->Configure(service) != Core::ERROR_NONE) { + message = _T("FireboltPrivacy could not be configured."); + } + configFireboltPrivacy->Release(); + configFireboltPrivacy = nullptr; + } + } + else { + message = _T("FireboltPrivacy could not be instantiated."); + } + Exchange::JFireboltPrivacy::Register(*this, _fireboltPrivacy); + + // On success return empty, to indicate there is no error text. + return (message); + } + + void FireboltPrivacy::Deinitialize(PluginHost::IShell* service VARIABLE_IS_NOT_USED) + { + if (_service != nullptr) { + ASSERT(_service == service); + _service->Unregister(&_notificationSink); + + if (_fireboltPrivacy != nullptr) { + _fireboltPrivacy->Unregister(&_notificationSink); + Exchange::JFireboltPrivacy::Unregister(*this); + + RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + VARIABLE_IS_NOT_USED uint32_t result = _fireboltPrivacy->Release(); + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + _fireboltPrivacy = nullptr; + + // 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; + _connectionId = 0; + } + } + + string FireboltPrivacy::Information() const + { + // No additional info to report. + return (string()); + } + + + void FireboltPrivacy::Deactivated(RPC::IRemoteConnection* connection) + { + // This can potentially be called on a socket thread, so the deactivation (wich in turn kills this object) must be done + // on a seperate thread. Also make sure this call-stack can be unwound before we are totally destructed. + if (_connectionId == connection->Id()) { + ASSERT(_service != nullptr); + Core::IWorkerPool::Instance().Submit(PluginHost::IShell::Job::Create(_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE)); + } + } + + void FireboltPrivacy::OnAllowResumePointsChanged(const bool allowResumePoint) { + Exchange::JFireboltPrivacy::Event::OnAllowResumePointsChanged(*this, allowResumePoint); + } +} // namespace Plugin +} // namespace WPEFramework + diff --git a/examples/FireboltPrivacy.h b/examples/FireboltPrivacy.h new file mode 100644 index 000000000..f1df8ab64 --- /dev/null +++ b/examples/FireboltPrivacy.h @@ -0,0 +1,112 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#pragma once + +#include "Module.h" + +#include +#include +#include + +namespace WPEFramework { +namespace Plugin { + + class FireboltPrivacy : public PluginHost::IPlugin, + public PluginHost::JSONRPC { + private: + class NotificationHandler : public RPC::IRemoteConnection::INotification, public Exchange::IFireboltPrivacy::INotification { + public: + NotificationHandler() = delete; + NotificationHandler(const NotificationHandler&) = delete; + NotificationHandler(NotificationHandler&&) = delete; + NotificationHandler& operator=(const NotificationHandler&) = delete; + NotificationHandler& operator=(NotificationHandler&&) = delete; + + NotificationHandler(FireboltPrivacy& parent) + : _parent(parent) + { + } + ~NotificationHandler() override = default; + + public: + void Activated(RPC::IRemoteConnection* /* connection */) override + { + } + void Deactivated(RPC::IRemoteConnection* connection) override + { + _parent.Deactivated(connection); + } + void Terminated (RPC::IRemoteConnection* /* connection */) override + { + } + + + void OnAllowResumePointsChanged(const bool allowResumePoint) override + { + _parent.OnAllowResumePointsChanged(allowResumePoint); + } + BEGIN_INTERFACE_MAP(NotificationHandler) + INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) + INTERFACE_ENTRY(Exchange::IFireboltPrivacy::INotification) + END_INTERFACE_MAP + + private: + FireboltPrivacy& _parent; + }; + public: + FireboltPrivacy(const FireboltPrivacy&) = delete; + FireboltPrivacy(FireboltPrivacy&&) = delete; + FireboltPrivacy& operator=(const FireboltPrivacy&) = delete; + FireboltPrivacy& operator=(FireboltPrivacy&) = delete; + + FireboltPrivacy(); + ~FireboltPrivacy() override = default; + + // Build QueryInterface implementation, specifying all possible interfaces to be returned. + BEGIN_INTERFACE_MAP(FireboltPrivacy) + INTERFACE_ENTRY(PluginHost::IPlugin) + INTERFACE_ENTRY(PluginHost::IDispatcher) + INTERFACE_AGGREGATE(Exchange::IFireboltPrivacy, _fireboltPrivacy) + END_INTERFACE_MAP + + public: + // IPlugin methods + // ------------------------------------------------------------------------------------------------------- + const string Initialize(PluginHost::IShell* service) override; + void Deinitialize(PluginHost::IShell* service) override; + string Information() const override; + + + private: + void Deactivated(RPC::IRemoteConnection* connection); + void OnAllowResumePointsChanged(const bool allowResumePoint); + PluginHost::JSONRPC::classification CheckToken(const string& token, const string& method, const string& parameters); + + private: + uint32_t _connectionId; + PluginHost::IShell* _service; + Exchange::IFireboltPrivacy* _fireboltPrivacy; + Core::SinkType _notificationSink; + + }; + +} // namespace Plugin +} // namespace WPEFramework diff --git a/examples/FireboltPrivacy.tgz b/examples/FireboltPrivacy.tgz new file mode 100644 index 000000000..8a88c3bcd Binary files /dev/null and b/examples/FireboltPrivacy.tgz differ diff --git a/examples/FireboltPrivacy/.FireboltPrivacyImplementation.h.swp b/examples/FireboltPrivacy/.FireboltPrivacyImplementation.h.swp new file mode 100644 index 000000000..95887bf55 Binary files /dev/null and b/examples/FireboltPrivacy/.FireboltPrivacyImplementation.h.swp differ diff --git a/examples/FireboltPrivacy/CMakeLists.txt b/examples/FireboltPrivacy/CMakeLists.txt new file mode 100644 index 000000000..0d92eac48 --- /dev/null +++ b/examples/FireboltPrivacy/CMakeLists.txt @@ -0,0 +1,57 @@ +# If not stated otherwise in this file or this component's LICENSE file the +# following copyright and licenses apply: +# +# Copyright 2020 Metrological +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +project(FireboltPrivacy) + +cmake_minimum_required(VERSION 3.3) + +find_package(WPEFramework) + +project_version(1.0.0) + +set(MODULE_NAME ${NAMESPACE}${PROJECT_NAME}) + +message("Setup ${MODULE_NAME} v${PROJECT_VERSION}") + +set(PLUGIN_FIREBOLTPRIVACY_AUTOSTART "Activated" CACHE STRING "Automatically start FireboltPrivacy plugin") + +find_package(${NAMESPACE}Core REQUIRED) +find_package(${NAMESPACE}Messaging REQUIRED) +find_package(${NAMESPACE}Plugins REQUIRED) +find_package(${NAMESPACE}Definitions REQUIRED) +find_package(CompileSettingsDebug CONFIG REQUIRED) + +add_library(${MODULE_NAME} SHARED + FireboltPrivacy.cpp + FireboltPrivacyImplementation.cpp + Module.cpp) + + +set_target_properties(${MODULE_NAME} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + +target_link_libraries(${MODULE_NAME} + PRIVATE + CompileSettingsDebug::CompileSettingsDebug + ${NAMESPACE}Plugins::${NAMESPACE}Plugins + ${NAMESPACE}Definitions::${NAMESPACE}Definitions) + +install(TARGETS ${MODULE_NAME} + DESTINATION lib/${STORAGE_DIRECTORY}/plugins) + +write_config() diff --git a/examples/FireboltPrivacy/FireboltPrivacy.conf.in b/examples/FireboltPrivacy/FireboltPrivacy.conf.in new file mode 100644 index 000000000..afe64eba2 --- /dev/null +++ b/examples/FireboltPrivacy/FireboltPrivacy.conf.in @@ -0,0 +1,10 @@ +startmode = "@PLUGIN_FIREBOLTPRIVACY_AUTOSTART@" +callsign = "Privacy" + +configuration = JSON() + +rootobject = JSON() +rootobject.add("mode", "Local") +rootobject.add("locator", "lib@MODULE_NAME@.so") +configuration.add("root", rootobject) + diff --git a/examples/FireboltPrivacy/FireboltPrivacy.cpp b/examples/FireboltPrivacy/FireboltPrivacy.cpp new file mode 100644 index 000000000..99562dcb2 --- /dev/null +++ b/examples/FireboltPrivacy/FireboltPrivacy.cpp @@ -0,0 +1,145 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FireboltPrivacy.h" +#include + +namespace WPEFramework { + +namespace Plugin +{ + + namespace { + + static Metadata metadata( + // Version + 1, 0, 0, + // Preconditions + {}, + // Terminations + {}, + // Controls + {} + ); + } + + + FireboltPrivacy::FireboltPrivacy() + : JSONRPC(std::bind(&FireboltPrivacy::CheckToken, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)) + , _connectionId(0) + , _service(nullptr) + , _fireboltPrivacy(nullptr) + , _notificationSink(*this) + { + } + + PluginHost::JSONRPC::classification FireboltPrivacy::CheckToken(const string& token, const string& method, const string& parameters){ + SYSLOG(Logging::Startup, (_T("Received Token: %s method: %s, Params: %s"), token.c_str(), method.c_str(), parameters.c_str())); + return PluginHost::JSONRPC::classification::VALID; + } + + const string FireboltPrivacy::Initialize(PluginHost::IShell * service) + { + string message; + + ASSERT(service != nullptr); + ASSERT(_service == nullptr); + ASSERT(_connectionId == 0); + ASSERT(_fireboltPrivacy == nullptr); + _service = service; + _service->AddRef(); + + // Register the Process::Notification stuff. The Remote process might die before we get a + // change to "register" the sink for these events !!! So do it ahead of instantiation. + _service->Register(&_notificationSink); + + _fireboltPrivacy = service->Root(_connectionId, RPC::CommunicationTimeOut, _T("FireboltPrivacyImplementation")); + if (_fireboltPrivacy != nullptr) { + _fireboltPrivacy->Register(&_notificationSink); + + Exchange::IConfiguration* configFireboltPrivacy = _fireboltPrivacy->QueryInterface(); + if (configFireboltPrivacy != nullptr) { + if (configFireboltPrivacy->Configure(service) != Core::ERROR_NONE) { + message = _T("FireboltPrivacy could not be configured."); + } + configFireboltPrivacy->Release(); + configFireboltPrivacy = nullptr; + } + } + else { + message = _T("FireboltPrivacy could not be instantiated."); + } + Exchange::JFireboltPrivacy::Register(*this, _fireboltPrivacy); + + // On success return empty, to indicate there is no error text. + return (message); + } + + void FireboltPrivacy::Deinitialize(PluginHost::IShell* service VARIABLE_IS_NOT_USED) + { + if (_service != nullptr) { + ASSERT(_service == service); + _service->Unregister(&_notificationSink); + + if (_fireboltPrivacy != nullptr) { + _fireboltPrivacy->Unregister(&_notificationSink); + Exchange::JFireboltPrivacy::Unregister(*this); + + RPC::IRemoteConnection* connection(_service->RemoteConnection(_connectionId)); + VARIABLE_IS_NOT_USED uint32_t result = _fireboltPrivacy->Release(); + ASSERT(result == Core::ERROR_DESTRUCTION_SUCCEEDED); + _fireboltPrivacy = nullptr; + + // 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; + _connectionId = 0; + } + } + + string FireboltPrivacy::Information() const + { + // No additional info to report. + return (string()); + } + + + void FireboltPrivacy::Deactivated(RPC::IRemoteConnection* connection) + { + // This can potentially be called on a socket thread, so the deactivation (wich in turn kills this object) must be done + // on a seperate thread. Also make sure this call-stack can be unwound before we are totally destructed. + if (_connectionId == connection->Id()) { + ASSERT(_service != nullptr); + Core::IWorkerPool::Instance().Submit(PluginHost::IShell::Job::Create(_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE)); + } + } + + void FireboltPrivacy::OnAllowResumePointsChanged(const bool allowResumePoint) { + Exchange::JFireboltPrivacy::Event::OnAllowResumePointsChanged(*this, allowResumePoint); + } +} // namespace Plugin +} // namespace WPEFramework + diff --git a/examples/FireboltPrivacy/FireboltPrivacy.h b/examples/FireboltPrivacy/FireboltPrivacy.h new file mode 100644 index 000000000..f1df8ab64 --- /dev/null +++ b/examples/FireboltPrivacy/FireboltPrivacy.h @@ -0,0 +1,112 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#pragma once + +#include "Module.h" + +#include +#include +#include + +namespace WPEFramework { +namespace Plugin { + + class FireboltPrivacy : public PluginHost::IPlugin, + public PluginHost::JSONRPC { + private: + class NotificationHandler : public RPC::IRemoteConnection::INotification, public Exchange::IFireboltPrivacy::INotification { + public: + NotificationHandler() = delete; + NotificationHandler(const NotificationHandler&) = delete; + NotificationHandler(NotificationHandler&&) = delete; + NotificationHandler& operator=(const NotificationHandler&) = delete; + NotificationHandler& operator=(NotificationHandler&&) = delete; + + NotificationHandler(FireboltPrivacy& parent) + : _parent(parent) + { + } + ~NotificationHandler() override = default; + + public: + void Activated(RPC::IRemoteConnection* /* connection */) override + { + } + void Deactivated(RPC::IRemoteConnection* connection) override + { + _parent.Deactivated(connection); + } + void Terminated (RPC::IRemoteConnection* /* connection */) override + { + } + + + void OnAllowResumePointsChanged(const bool allowResumePoint) override + { + _parent.OnAllowResumePointsChanged(allowResumePoint); + } + BEGIN_INTERFACE_MAP(NotificationHandler) + INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) + INTERFACE_ENTRY(Exchange::IFireboltPrivacy::INotification) + END_INTERFACE_MAP + + private: + FireboltPrivacy& _parent; + }; + public: + FireboltPrivacy(const FireboltPrivacy&) = delete; + FireboltPrivacy(FireboltPrivacy&&) = delete; + FireboltPrivacy& operator=(const FireboltPrivacy&) = delete; + FireboltPrivacy& operator=(FireboltPrivacy&) = delete; + + FireboltPrivacy(); + ~FireboltPrivacy() override = default; + + // Build QueryInterface implementation, specifying all possible interfaces to be returned. + BEGIN_INTERFACE_MAP(FireboltPrivacy) + INTERFACE_ENTRY(PluginHost::IPlugin) + INTERFACE_ENTRY(PluginHost::IDispatcher) + INTERFACE_AGGREGATE(Exchange::IFireboltPrivacy, _fireboltPrivacy) + END_INTERFACE_MAP + + public: + // IPlugin methods + // ------------------------------------------------------------------------------------------------------- + const string Initialize(PluginHost::IShell* service) override; + void Deinitialize(PluginHost::IShell* service) override; + string Information() const override; + + + private: + void Deactivated(RPC::IRemoteConnection* connection); + void OnAllowResumePointsChanged(const bool allowResumePoint); + PluginHost::JSONRPC::classification CheckToken(const string& token, const string& method, const string& parameters); + + private: + uint32_t _connectionId; + PluginHost::IShell* _service; + Exchange::IFireboltPrivacy* _fireboltPrivacy; + Core::SinkType _notificationSink; + + }; + +} // namespace Plugin +} // namespace WPEFramework diff --git a/examples/FireboltPrivacy/FireboltPrivacyImplementation.cpp b/examples/FireboltPrivacy/FireboltPrivacyImplementation.cpp new file mode 100644 index 000000000..5c963e576 --- /dev/null +++ b/examples/FireboltPrivacy/FireboltPrivacyImplementation.cpp @@ -0,0 +1,260 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FireboltPrivacyImplementation.h" + +namespace WPEFramework { + +namespace Plugin +{ + class FireboltPrivacyImplementation : public Exchange::IFireboltPrivacy, + public Exchange::IConfiguration { + + private: + class Dictionary : public WPEFramework::RPC::SmartInterfaceType { + + private: + using BaseClass = WPEFramework::RPC::SmartInterfaceType; + + public: + Dictionary(string& callsign) + : BaseClass() { + BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), _T(callsign.c_str())); + } + + ~Dictionary() { + BaseClass::Close(WPEFramework::Core::infinite); + } + + public: + bool Get(const string& nameSpace, const string& key, string& value ) const { + bool result = false; + const WPEFramework::Exchange::IDictionary* impl = BaseClass::Interface(); + + if (impl != nullptr) { + result = impl->Get(nameSpace, key, value); + impl->Release(); + } else { + SYSLOG(Logging::Error, (_T("Unable to get Dictionary implementation:"))); + } + + return (result); + } + + bool Set(const string& nameSpace, const string& key, const string& value) { + bool result = false; + WPEFramework::Exchange::IDictionary* impl = BaseClass::Interface(); + + if (impl != nullptr) { + result = impl->Set(nameSpace, key, value); + impl->Release(); + } else { + SYSLOG(Logging::Error, (_T("Unable to get Dictionary implementation:"))); + } + + return (result); + } + + private: + + void Operational(const bool upAndRunning) { + SYSLOG(Logging::Notification , (_T("Operational state of Dictionary : %s"), upAndRunning ? _T("true"): _T("false"))); + } + }; + + class Config : public Core::JSON::Container { + public: + Config(const Config&) = delete; + Config(Config&&) = delete; + Config& operator=(const Config&) = delete; + Config& operator=(Config&&) = delete; + + Config() + : Core::JSON::Container() + , DictionaryCallSign() + { + Add(_T("callsign"), &DictionaryCallSign); + } + ~Config() override = default; + public: + Core::JSON::String DictionaryCallSign; + }; + + class NotificationDispatcher: public Core::IDispatch { + public: + NotificationDispatcher(const NotificationDispatcher&) = delete; + NotificationDispatcher(NotificationDispatcher&&) = delete; + NotificationDispatcher& operator= (const NotificationDispatcher&) = delete; + NotificationDispatcher& operator= (NotificationDispatcher&&) = delete; + NotificationDispatcher(FireboltPrivacyImplementation& parent, bool allowResumePoints): _parent(parent) + , _allowResumePoints(allowResumePoints) { + } + + void Dispatch() override { + _parent.NotifySink(_allowResumePoints); + } + + private: + FireboltPrivacyImplementation& _parent; + bool _allowResumePoints; + }; + + public: + using Notifications = std::vector; + + FireboltPrivacyImplementation(const FireboltPrivacyImplementation&) = delete; + FireboltPrivacyImplementation(FireboltPrivacyImplementation&&) = delete; + FireboltPrivacyImplementation& operator= (const FireboltPrivacyImplementation&) = delete; + FireboltPrivacyImplementation& operator= (FireboltPrivacyImplementation&&) = delete; + + FireboltPrivacyImplementation() + : _service(nullptr) + , _adminLock() + , _allowResumePoints(false) + , _inMemory(true) + , _notifications() + , _localStore() + { + } + ~FireboltPrivacyImplementation() override { + if (_localStore.IsValid() == true) { + _localStore.Release(); + } + } + + Core::hresult Register(Exchange::IFireboltPrivacy::INotification* notification) override + { + ASSERT(notification != nullptr); + + _adminLock.Lock(); + ASSERT(std::find(_notifications.begin(), _notifications.end(), notification) == _notifications.end()); + if(std::find(_notifications.begin(), _notifications.end(), notification) == _notifications.end()){ + _notifications.push_back(notification); + notification->AddRef(); + } + _adminLock.Unlock(); + + return Core::ERROR_NONE; + } + + Core::hresult Unregister(Exchange::IFireboltPrivacy::INotification* notification) override + { + ASSERT(notification != nullptr); + Core::hresult result = Core::ERROR_NONE; + + _adminLock.Lock(); + ASSERT(std::find(_notifications.begin(), _notifications.end(), notification) == _notifications.end()); + auto item = std::find(_notifications.begin(), _notifications.end(), notification); + if(item != _notifications.end()){ + notification->Release(); + _notifications.erase(item); + } + else { + result = Core::ERROR_INVALID_PARAMETER; + } + _adminLock.Unlock(); + + return result; + } + + Core::hresult GetAllowResumePoints(const string& appId, bool& allowResumePoints /* @out */) const override { + SYSLOG(Logging::Error, (_T("Getting allow resume points: %s"), appId.c_str())); + if (_inMemory) { + _adminLock.Lock(); + allowResumePoints = _allowResumePoints; + _adminLock.Unlock(); + } else { + string value; + _localStore->Get(PrivacyNamespace, PrivacyKeyAllowResume, value); + if (value.empty() || strcasecmp(value.c_str(), "false") == 0 ) { + allowResumePoints = false; + } else { + allowResumePoints = true; + } + } + return Core::ERROR_NONE; + } + + Core::hresult SetAllowResumePoints(const string& appId, const bool& allowResumePoints ) override { + SYSLOG(Logging::Error, (_T("Setting allow resume points: %s"), appId.c_str())); + if (_inMemory) { + _adminLock.Lock(); + _allowResumePoints = allowResumePoints; + _adminLock.Unlock(); + Core::IWorkerPool::Instance().Submit(Core::ProxyType(Core::ProxyType::Create(*this, allowResumePoints))); + } else { + string value; + bool ret_val; + if (allowResumePoints) { + ret_val = _localStore->Set(PrivacyNamespace, PrivacyKeyAllowResume, "true"); + } else { + ret_val = _localStore->Set(PrivacyNamespace, PrivacyKeyAllowResume, "false"); + } + if (ret_val == true) { + Core::IWorkerPool::Instance().Submit(Core::ProxyType(Core::ProxyType::Create(*this, allowResumePoints))); + } + } + return Core::ERROR_NONE; + } + + void NotifySink(const bool allowResumePoints) { + _adminLock.Lock(); + for (auto notification: _notifications) { + notification->OnAllowResumePointsChanged(allowResumePoints); + } + _adminLock.Unlock(); + } + + uint32_t Configure(PluginHost::IShell* service) override { + + ASSERT( service != nullptr); + uint32_t result = Core::ERROR_NONE; + Config config; + config.FromString(service->ConfigLine()); + _service = service; + + if (config.DictionaryCallSign.IsNull() == false && config.DictionaryCallSign.Value().empty() == false) { + _inMemory = false; + string callsign = config.DictionaryCallSign.Value(); + if (_localStore.IsValid() == false) { + _localStore = Core::ProxyType::Create(callsign); + } + } + + return result; + } + + BEGIN_INTERFACE_MAP(FireboltPrivacyImplementation) + INTERFACE_ENTRY(Exchange::IFireboltPrivacy) + INTERFACE_ENTRY(Exchange::IConfiguration) + END_INTERFACE_MAP + + private: + PluginHost::IShell* _service; + mutable Core::CriticalSection _adminLock; + bool _allowResumePoints; + bool _inMemory; + Notifications _notifications; + Core::ProxyType _localStore; + }; + + SERVICE_REGISTRATION(FireboltPrivacyImplementation, 1, 0, 0) +} // namespace Plugin +} // namespace WPEFramework + diff --git a/examples/FireboltPrivacy/FireboltPrivacyImplementation.h b/examples/FireboltPrivacy/FireboltPrivacyImplementation.h new file mode 100644 index 000000000..1c567af02 --- /dev/null +++ b/examples/FireboltPrivacy/FireboltPrivacyImplementation.h @@ -0,0 +1,28 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "Module.h" +#include +#include +#include +#include + +static constexpr TCHAR PrivacyNamespace[] = _T("FireboltPrivacy"); +static constexpr TCHAR PrivacyKeyAllowResume[] = _T("AllowResumePoints"); diff --git a/examples/FireboltPrivacy/FireboltPrivacyPlugin.json b/examples/FireboltPrivacy/FireboltPrivacyPlugin.json new file mode 100644 index 000000000..1228af6f3 --- /dev/null +++ b/examples/FireboltPrivacy/FireboltPrivacyPlugin.json @@ -0,0 +1,35 @@ +{ + "$schema": "plugin.schema.json", + "info": { + "title": "Firebolt Privacy Plugin", + "callsign": "Privacy", + "locator": "libWPEFrameworkFireboltPrivacy.so", + "status": "production", + "description": [ + "The Firebolt Privacy plugin provides functionality to store user settings either in local or in remote." + ], + "version": "1.0" + }, + "configuration": { + "type": "object", + "properties": { + "configuration": { + "type": "object", + "required": [], + "properties": { + "devicemanifest": { + "type": "string", + "description": "Device manifest filename (default: firebolt-device-manifest.json)" + }, + "fireboltconfigpath": { + "type": "string", + "description": "Path where firebolt configurations are present (default: /etc/)" + } + } + } + } + }, + "interface": { + "$ref": "${cppinterfacedir}/IFireboltPrivacy.h" + } +} diff --git a/examples/FireboltPrivacy/Module.cpp b/examples/FireboltPrivacy/Module.cpp new file mode 100644 index 000000000..393d6a267 --- /dev/null +++ b/examples/FireboltPrivacy/Module.cpp @@ -0,0 +1,22 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Module.h" + +MODULE_NAME_DECLARATION(BUILD_REFERENCE) diff --git a/examples/FireboltPrivacy/Module.h b/examples/FireboltPrivacy/Module.h new file mode 100644 index 000000000..6c904c9a3 --- /dev/null +++ b/examples/FireboltPrivacy/Module.h @@ -0,0 +1,31 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef MODULE_NAME +#define MODULE_NAME Plugin_FireboltPrivacy +#endif + +#include +#include +#include + +#undef EXTERNAL +#define EXTERNAL diff --git a/examples/FireboltPrivacyImplementation.cpp b/examples/FireboltPrivacyImplementation.cpp new file mode 100644 index 000000000..dcc1faeca --- /dev/null +++ b/examples/FireboltPrivacyImplementation.cpp @@ -0,0 +1,268 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FireboltPrivacyImplementation.h" + +namespace WPEFramework { + +namespace Plugin +{ + class FireboltPrivacyImplementation : public Exchange::IFireboltPrivacy, + public Exchange::IConfiguration { + + private: + class Dictionary : public WPEFramework::RPC::SmartInterfaceType { + + private: + using BaseClass = WPEFramework::RPC::SmartInterfaceType; + + public: + Dictionary(string& callsign) + : BaseClass() { + BaseClass::Open(RPC::CommunicationTimeOut, BaseClass::Connector(), _T(callsign.c_str())); + } + + ~Dictionary() { + BaseClass::Close(WPEFramework::Core::infinite); + } + + public: + bool Get(const string& nameSpace, const string& key, string& value ) const { + bool result = false; + const WPEFramework::Exchange::IDictionary* impl = BaseClass::Interface(); + + if (impl != nullptr) { + result = impl->Get(nameSpace, key, value); + impl->Release(); + } else { + SYSLOG(Logging::Error, (_T("Unable to get Dictionary implementation:"))); + } + + return (result); + } + + bool Set(const string& nameSpace, const string& key, const string& value) { + bool result = false; + WPEFramework::Exchange::IDictionary* impl = BaseClass::Interface(); + + if (impl != nullptr) { + result = impl->Set(nameSpace, key, value); + impl->Release(); + } else { + SYSLOG(Logging::Error, (_T("Unable to get Dictionary implementation:"))); + } + + return (result); + } + + private: + + void Operational(const bool upAndRunning) { + SYSLOG(Logging::Notification , (_T("Operational state of Dictionary : %s"), upAndRunning ? _T("true"): _T("false"))); + } + }; + + class Config : public Core::JSON::Container { + public: + Config(const Config&) = delete; + Config(Config&&) = delete; + Config& operator=(const Config&) = delete; + Config& operator=(Config&&) = delete; + + Config() + : Core::JSON::Container() + , DictionaryCallSign() + { + Add(_T("callsign"), &DictionaryCallSign); + } + ~Config() override = default; + public: + Core::JSON::String DictionaryCallSign; + }; + + class NotificationDispatcher: public Core::IDispatch { + public: + NotificationDispatcher(const NotificationDispatcher&) = delete; + NotificationDispatcher(NotificationDispatcher&&) = delete; + NotificationDispatcher& operator= (const NotificationDispatcher&) = delete; + NotificationDispatcher& operator= (NotificationDispatcher&&) = delete; + NotificationDispatcher(FireboltPrivacyImplementation& parent, bool allowResumePoints): _parent(parent) + , _allowResumePoints(allowResumePoints) { + } + + void Dispatch() override { + _parent.NotifySink(_allowResumePoints); + } + + private: + FireboltPrivacyImplementation& _parent; + bool _allowResumePoints; + }; + + public: + using Notifications = std::vector; + + FireboltPrivacyImplementation(const FireboltPrivacyImplementation&) = delete; + FireboltPrivacyImplementation(FireboltPrivacyImplementation&&) = delete; + FireboltPrivacyImplementation& operator= (const FireboltPrivacyImplementation&) = delete; + FireboltPrivacyImplementation& operator= (FireboltPrivacyImplementation&&) = delete; + + FireboltPrivacyImplementation() + : _service(nullptr) + , _adminLock() + , _allowResumePoints(false) + , _inMemory(true) + , _notifications() + , _localStore() + { + } + ~FireboltPrivacyImplementation() override { + if (_localStore.IsValid() == true) { + _localStore.Release(); + } + } + + Core::hresult Register(Exchange::IFireboltPrivacy::INotification* notification) override + { + ASSERT(notification != nullptr); + + _adminLock.Lock(); + ASSERT(std::find(_notifications.begin(), _notifications.end(), notification) == _notifications.end()); + if(std::find(_notifications.begin(), _notifications.end(), notification) == _notifications.end()){ + _notifications.push_back(notification); + notification->AddRef(); + } + _adminLock.Unlock(); + + return Core::ERROR_NONE; + } + + Core::hresult Unregister(Exchange::IFireboltPrivacy::INotification* notification) override + { + ASSERT(notification != nullptr); + Core::hresult result = Core::ERROR_NONE; + + _adminLock.Lock(); + ASSERT(std::find(_notifications.begin(), _notifications.end(), notification) == _notifications.end()); + auto item = std::find(_notifications.begin(), _notifications.end(), notification); + if(item != _notifications.end()){ + notification->Release(); + _notifications.erase(item); + } + else { + result = Core::ERROR_INVALID_PARAMETER; + } + _adminLock.Unlock(); + + return result; + } + + Core::hresult GetStorageLocation(StorageLocation& value /* @out */) const override { + if (_inMemory) { + value = StorageLocation::InMemory; + } else { + value = StorageLocation::Disk; + } + return Core::ERROR_NONE; + } + + Core::hresult GetAllowResumePoints(bool& allowResumePoints /* @out */) const override { + SYSLOG(Logging::Error, (_T("Getting allow resume points:"))); + if (_inMemory) { + _adminLock.Lock(); + allowResumePoints = _allowResumePoints; + _adminLock.Unlock(); + } else { + string value; + _localStore->Get(PrivacyNamespace, PrivacyKeyAllowResume, value); + if (value.empty() || strcasecmp(value.c_str(), "false") == 0 ) { + allowResumePoints = false; + } else { + allowResumePoints = true; + } + } + return Core::ERROR_NONE; + } + + Core::hresult SetAllowResumePoints(const bool& allowResumePoints ) override { + if (_inMemory) { + _adminLock.Lock(); + _allowResumePoints = allowResumePoints; + _adminLock.Unlock(); + Core::IWorkerPool::Instance().Submit(Core::ProxyType(Core::ProxyType::Create(*this, allowResumePoints))); + } else { + string value; + bool ret_val; + if (allowResumePoints) { + ret_val = _localStore->Set(PrivacyNamespace, PrivacyKeyAllowResume, "true"); + } else { + ret_val = _localStore->Set(PrivacyNamespace, PrivacyKeyAllowResume, "false"); + } + if (ret_val == true) { + Core::IWorkerPool::Instance().Submit(Core::ProxyType(Core::ProxyType::Create(*this, allowResumePoints))); + } + } + return Core::ERROR_NONE; + } + + void NotifySink(const bool allowResumePoints) { + _adminLock.Lock(); + for (auto notification: _notifications) { + notification->OnAllowResumePointsChanged(allowResumePoints); + } + _adminLock.Unlock(); + } + + uint32_t Configure(PluginHost::IShell* service) override { + + ASSERT( service != nullptr); + uint32_t result = Core::ERROR_NONE; + Config config; + config.FromString(service->ConfigLine()); + _service = service; + + if (config.DictionaryCallSign.IsNull() == false && config.DictionaryCallSign.Value().empty() == false) { + _inMemory = false; + string callsign = config.DictionaryCallSign.Value(); + if (_localStore.IsValid() == false) { + _localStore = Core::ProxyType::Create(callsign); + } + } + + return result; + } + + BEGIN_INTERFACE_MAP(FireboltPrivacyImplementation) + INTERFACE_ENTRY(Exchange::IFireboltPrivacy) + INTERFACE_ENTRY(Exchange::IConfiguration) + END_INTERFACE_MAP + + private: + PluginHost::IShell* _service; + mutable Core::CriticalSection _adminLock; + bool _allowResumePoints; + bool _inMemory; + Notifications _notifications; + Core::ProxyType _localStore; + }; + + SERVICE_REGISTRATION(FireboltPrivacyImplementation, 1, 0, 0) +} // namespace Plugin +} // namespace WPEFramework + diff --git a/examples/FireboltPrivacyImplementation.h b/examples/FireboltPrivacyImplementation.h new file mode 100644 index 000000000..1c567af02 --- /dev/null +++ b/examples/FireboltPrivacyImplementation.h @@ -0,0 +1,28 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "Module.h" +#include +#include +#include +#include + +static constexpr TCHAR PrivacyNamespace[] = _T("FireboltPrivacy"); +static constexpr TCHAR PrivacyKeyAllowResume[] = _T("AllowResumePoints"); diff --git a/examples/FireboltPrivacyPlugin.json b/examples/FireboltPrivacyPlugin.json new file mode 100644 index 000000000..1228af6f3 --- /dev/null +++ b/examples/FireboltPrivacyPlugin.json @@ -0,0 +1,35 @@ +{ + "$schema": "plugin.schema.json", + "info": { + "title": "Firebolt Privacy Plugin", + "callsign": "Privacy", + "locator": "libWPEFrameworkFireboltPrivacy.so", + "status": "production", + "description": [ + "The Firebolt Privacy plugin provides functionality to store user settings either in local or in remote." + ], + "version": "1.0" + }, + "configuration": { + "type": "object", + "properties": { + "configuration": { + "type": "object", + "required": [], + "properties": { + "devicemanifest": { + "type": "string", + "description": "Device manifest filename (default: firebolt-device-manifest.json)" + }, + "fireboltconfigpath": { + "type": "string", + "description": "Path where firebolt configurations are present (default: /etc/)" + } + } + } + } + }, + "interface": { + "$ref": "${cppinterfacedir}/IFireboltPrivacy.h" + } +} diff --git a/examples/Module.cpp b/examples/Module.cpp new file mode 100644 index 000000000..393d6a267 --- /dev/null +++ b/examples/Module.cpp @@ -0,0 +1,22 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Module.h" + +MODULE_NAME_DECLARATION(BUILD_REFERENCE) diff --git a/examples/Module.h b/examples/Module.h new file mode 100644 index 000000000..6c904c9a3 --- /dev/null +++ b/examples/Module.h @@ -0,0 +1,31 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2020 Metrological + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#ifndef MODULE_NAME +#define MODULE_NAME Plugin_FireboltPrivacy +#endif + +#include +#include +#include + +#undef EXTERNAL +#define EXTERNAL