RDK Resources
[*RDK Preferred*]
Code Management Facility
RDK Forums
[RDK Conferences]
RDK Support
Archives
Papers & Presentations Archive
Injected bundle is an Integration layer between Service Manager and the player in RDK Browser and WPE.
a. Expose C/C++ API using injectedbundle
1. Define an Injectedbundle CB that's invoked when a page is loaded
Define an object of WKBundlePageLoaderClientV1 with your own function callback for didCommitLoadForFrame. This callback gets invoked when a page's DOM contens finishes
loading. This will also provide the mainFrame instance in which the JS object is to be loaded
Eg -
WKBundlePageLoaderClientV1 client {
{1, clientInfo},
// Version 0.
nullptr, // didStartProvisionalLoadForFrame;
nullptr, // didReceiveServerRedirectForProvisionalLoadForFrame;
nullptr, // didFailProvisionalLoadWithErrorForFrame;
didCommitLoad, // didCommitLoadForFrame;
nullptr, // didFinishDocumentLoadForFrame;
nullptr, // didFinishLoadForFrame;
nullptr, // didFailLoadWithErrorForFrame;
nullptr, // didSameDocumentNavigationForFrame;
nullptr, // didReceiveTitleForFrame;
nullptr, // didFirstLayoutForFrame;
nullptr, // didFirstVisuallyNonEmptyLayoutForFrame;
nullptr, // didRemoveFrameFromHierarchy;
nullptr, // didDisplayInsecureContentForFrame;
nullptr, // didRunInsecureContentForFrame;
nullptr, // didClearWindowObjectForFrame;
nullptr, // didCancelClientRedirectForFrame;
nullptr, // willPerformClientRedirectForFrame;
nullptr, // didHandleOnloadEventsForFrame;
// Version 1.
nullptr, // didLayoutForFrame
nullptr, // didNewFirstVisuallyNonEmptyLayout_unavailable
nullptr, // didNewFirstVisuallyNonEmptyLayout_unavailable
nullptr,
nullptr, // globalObjectIsAvailableForFrame
nullptr, // globalObjectIsAvailableForFrame
nullptr, // didReconnectDOMWindowExtensionToGlobalObject
nullptr // willDestroyGlobalObjectForDOMWindowExtension
};
2. void didCommitLoad(WKBundlePageRef page, WKBundleFrameRef frame) // WKBundleFrameRef frame provides the JS context in which to load JS/C++ bindings
Eg -
void didCommitLoad(WKBundlePageRef page, WKBundleFrameRef frame)
{
JSGlobalContextRef context = WKBundleFrameGetJavaScriptContext(frame);
LoadJS(context);
}
3. Using the context obtained from frame you can load custom JS objects, but first you need to define a JS class definition which provides a standard set of callbacks and properties
for the JS object
Ref - usr/include/JavaScriptCore/JSObjectRef.h
typedef struct {
int version; /* current (and only) version is 0 */
JSClassAttributes attributes;
const char* className;
JSClassRef parentClass;
const JSStaticValue* staticValues;
const JSStaticFunction* staticFunctions;
JSObjectInitializeCallback initialize;
JSObjectFinalizeCallback finalize;
JSObjectHasPropertyCallback hasProperty;
JSObjectGetPropertyCallback getProperty;
JSObjectSetPropertyCallback setProperty;
JSObjectDeletePropertyCallback deleteProperty;
JSObjectGetPropertyNamesCallback getPropertyNames;
JSObjectCallAsFunctionCallback callAsFunction;
JSObjectCallAsConstructorCallback callAsConstructor;
JSObjectHasInstanceCallback hasInstance;
JSObjectConvertToTypeCallback convertToType;
} JSClassDefinition;
The important parameters for any JS object are staticValues, staticFunctions which helps to implement JSObject.property (get/set) and JSObject.function()
You may find more about the structure of JSStaticValue and JSStaticFunction in JSObjectRef.h
4. Once the class and corresponding callbacks are defined, you may load this object onto the context that is retrieved from the frame object in injectedbundle
static const JSClassDefinition JS_class_def;
void LoadJS(JSGlobalContextRef context)
{
struct CustomObject* obj = new CustomObject(); //Create a custom object that holds the context and any other variables that are required, for eg- seesion keeping var
JSClassRef classDef = JSClassCreate(&JS_class_def);
JSObjectRef classObj = JSObjectMake(context, classDef, obj);
JSObjectRef globalObj = JSContextGetGlobalObject(context);
JSStringRef str = JSStringCreateWithUTF8CString("JSObject"); //If you would like to name your object as JSObject and access like JSObject.property
JSObjectSetProperty(context, globalObj, str, classObj, kJSPropertyAttributeReadOnly, NULL); //t this loads the JSObject to page
JSClassRelease(classDef);
JSStringRelease(str);
}
5. Once the page is loaded, you may add an event listenet for onDOMContentLoaded and verify if the JSObject is defined ( if(typeof global.JSObject !== "undefined" {console.log ("JSObject available")})
============================================================================================================================================================================
b. Invoke a JS API from C/C++
1. Pass the JS API function pointer to Native code and store it as a JSObjectRef
JSObject.addEventListener(eventType, eventListener) //with eventListener having a definition like "function eventListener(event: any) {....}"
static JSValueRef addEventListener(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception)
{
JSObjectRef callbackObj = JSValueToObject(context, arguments[1], NULL);
if (callbackObj != NULL && JSObjectIsFunction(context, callbackObj))
{
//Store the callbackObj in a variable
eventListener = callbackObj;
JSValueProtect(context, callbackObj);
}
else
{
return JSValueMakeUndefined(context);
}
return JSValueMakeNull(context);
}
2. To invoke the JS API from C/C++, call JSObjectCallAsFunction with the callbackObj and arguments
JSObjectCallAsFunction(context, callbackObj, NULL, 1, args, NULL); //args is the list of arguments if required