From bbd70245c05dec8c93d9c6437486f101488d1a15 Mon Sep 17 00:00:00 2001 From: Neeraj Deshpande Date: Sat, 30 Apr 2022 00:01:00 +0530 Subject: [PATCH] Added WebExtension to export Thunder interface (IIdentifier) to JS. (#157) --- WebKitBrowser/Extension/CMakeLists.txt | 6 + WebKitBrowser/Extension/IIdentifier.cpp | 168 ++++++++++++++++++++++++ WebKitBrowser/Extension/IIdentifier.h | 32 +++++ WebKitBrowser/Extension/main.cpp | 12 +- 4 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 WebKitBrowser/Extension/IIdentifier.cpp create mode 100644 WebKitBrowser/Extension/IIdentifier.h diff --git a/WebKitBrowser/Extension/CMakeLists.txt b/WebKitBrowser/Extension/CMakeLists.txt index aebe8c3efc..bf31dac804 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_FIREBOLTOS_ENDPOINT "Enable injection of __firebolt.endpoint." ON) @@ -42,6 +43,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) diff --git a/WebKitBrowser/Extension/IIdentifier.cpp b/WebKitBrowser/Extension/IIdentifier.cpp new file mode 100644 index 0000000000..cb5d7737a0 --- /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->Aquire(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 ae7c3133ca..8202ab33de 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 @@ -106,7 +110,7 @@ static class PluginHost { webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(windowObjectClearedCallback), - nullptr); + this); g_signal_connect( extension, @@ -136,7 +140,7 @@ static class PluginHost { } private: - static void windowObjectClearedCallback(WebKitScriptWorld* world, WebKitWebPage* page VARIABLE_IS_NOT_USED, WebKitFrame* frame) + static void windowObjectClearedCallback(WebKitScriptWorld* world, WebKitWebPage* page VARIABLE_IS_NOT_USED, WebKitFrame* frame, VARIABLE_IS_NOT_USED PluginHost* host) { JavaScript::Milestone::InjectJS(world, frame); JavaScript::NotifyWPEFramework::InjectJS(world, frame); @@ -145,6 +149,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