To create a built-in native service, you must write the source code and prepare the required configuration files.
For easier understanding, the process to create a built-in JS service is explained using using a sample service in Sample Code Repository. The sample service has the following features:
Has a method named hello that responds with the string “Hello, Native Service!!”.
Calls com.webos.service.systemservice/clock/getTime method and prints the UTC time on the log.
The directory structure of the sample service must be as follows:
Line(3~5) : Include header files to use LS2, PmLog, and pbnjson.
Line(7~15) : A function that calls PmLogGetContext() in PmLog library to print logs. For more details, see Using PmLogLib in C/C++.
Line(17~32) : Create pbnjson utility functions, which convert String to Json and Json to String based on pbnjson library. pbnjson is a JSON engine, implemented as a pair of libraries with APIs for easier C and C++ abstraction.
Line(34~56) : Implement the onHello() callback function that is invoked when com.example.service.native/hello is called. The third argument of LSMessageReply() should be in JSON format.
Line(58~74) : Implement the cbGetTime() callback function for systemservice’s getTime method call. When the UTC time is received in response, this function prints the time on the log.
Line(76~78) : Register the hello method and the onHello() callback function in the LSMethod array.
Line(84~85) : Declare and initialize LSError.
Line(87~88) : Declare GMainLoop and LSHandle variables.
Line(90~96) : Register the com.example.service.native service using LSRegister().
Line(98~104) : Register the hello method and the onHello() callback function in LSHandle (m_handle).
Line(106~112) : Attach the com.example.service.native service to GMainLoop.
Line(114~124) : Call systemservice’s getTime method using LSCall().
Line(126) : Run an iteration loop.
Line(128~134) : After the iteration loop is stopped, unregister the service.
Line(136~137) : Release GMainLoop.
README.md
This file provides general information of the native service.
Caution
If the README.md file is missing, a build error occurs.
Make sure the ‘Summary’ section is a single line. Even any whitespace at the line above the ‘Description’ section is considered a part of the summary and can cause the build to fail.
Sample README.md
Summary
-------
native service sample
Description
-----------
native service sample
How to Build on Linux
---------------------
## Dependencies
Below are the tools and libraries (and their minimum versions) required to build sample program:
* cmake (version required by cmake-modules-webos)
* gcc
* glib-2.0
* make
* cmake-modules-webos
## Building
$ cd build-webos
$ source oe-init-build-env
$ bitbake com.example.service.native
Copyright and License Information
=================================
Unless otherwise specified, all content, including all source code files and
documentation files in this repository are:
Copyright (c) 2020 LG Electronics, Inc.
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.
SPDX-License-Identifier: Apache-2.0
Step 2: Configure the Native Service
This section describes how to prepare the configuration files required to build and test the native service.
LS2 Configuration Files
To register and execute a service through LS2, it is necessary to create a Service Configuration file, Role file, Permission file, and Groups file. You must create a files/sysbus directory in your project so that the configuration files are installed in the right place on the target.
Note This section briefly describes about configuration files. For more details, see Security Guide.
Service Configuration File
This file contains description of the service type and launch command.
Line(5~7) : allowedNames - Names that this service is allowed to register. It can be an array of any valid service name strings, empty array [] for none, and empty string "" for an unnamed service.
Line(8~15) : The permissions for the service.
outbound - Array of services that this service is allowed to send requests to. It can include strings of any valid service names. Use “*” for all, empty array [] for none, and empty string "" for unnamed services. It’s possible to use a wildcard (*) at the end of a string.
Client Permission File
This file defines what groups are required for this component to function properly.
Line(3) : Since com.example.service.native calls systemservice’s getTime method, add the method’s group name “time.query” to the client permission file.
API Permission File
This file defines ACG values of the service and methods those ACG values contain.
Line(3) : Set an ACG value and specify the methods that belong to the ACG value. In this example, the ACG value is “examplenativeservice.acgvalue”, and the com.example.service.native/hello method is added to this value.
Groups File
This file defines the trust levels of each ACG value.
Line(3) : Describe the dependency of service execution. If the dependent unit is normal, the unit is started. The example allows the ls-hubd.service unit to run and then run the service.
Line(2) : Specify the project name and the file extension type. In this tutorial, we use “com.example.service.native” as the project name for indicating various filenames and pathnames. The file extension type allows CMake to skip unnecessary compiler checks.
Line(5) : Include webOS OSE modules for the build.
Line(6) : Specify the “cmake-modules-webos” version.
Line(7) : Specify webos_component with the component version to use webOS variables for the standard system paths. It commonly follows three digit versioning scheme.
Line(9~39) : Add GLib, LS2, PmLogLib, and pbnjson dependencies, and add options to use C++11.
Line(41) : Install the executable in /usr/sbin.
Line(43) : Install the LS2 configuration files (/files/sysbus) to the target.
Line(44) : Install the systemd configuration file on the target (etc/systemd/system).
Step 3: Build the Native Service
After implementing and configuring the Native service, you must build the service.
Add the Recipe File
webOS OSE uses OpenEmbedded of Yocto Project to build its components. OpenEmbedded needs a recipe file that configures the build environment. For more details about the recipe, see Yocto Project Reference Manual.
You must move the recipe file into webOS OSE project directory.
Destination directory:build-webos/meta-webosose/meta-webos/recipes-webos/<native service name>
where <native service name> is the name of the native service. For the sample native service, <native service name> must be replaced by ‘com.example.service.native’.
com.example.service.native.bb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SUMMARY="Native service sample"AUTHOR="Author's name <Author's e-mail>"LICENSE="Apache-2.0"LIC_FILES_CHKSUM="file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"DEPENDS="glib-2.0 luna-service2 pmloglib libpbnjson"WEBOS_VERSION="0.0.1"PR="r0"inherit webos_component
inherit webos_submissions
inherit webos_daemon
inherit webos_cmake
inherit webos_system_bus
A brief explanation of the above file:
Lines(1~4) : Basic descriptions of the component.
Line(6) : Add GLib, LS2, PmLog, and pbnjson as dependencies.
Line(8) : Version of the component. For the webOS OSE component, this field is mandatory.
Line(9) : Revision version of the recipe. Each recipe requires a counter to track its modification history. Make sure that you increment the version when you edit the recipe, unless you only change the value of the WEBOS_VERSION field or comments.
Line(11) : Inherit common functions of webOS OSE. For all components of webOS OSE, this entry is required.
Line(12) : Instruct OpenEmbedded to use the WEBOS_VERSION value as the component version number. If you develop your component on a local repository, this entry is required.
Line(13) : Every component that installs a daemon inherits webos_daemon.
Line(14) : Instruct OpenEmbedded that the component uses CMake for configuration, which is the preferred choice for webOS components.
Line(15) : To register component as a service and install LS2 configuration files, inherit webos_system_bus.
Configure the Local Source Directory
To build a component that is located on the local system, you must specify the directory information.
You must move the configuration file into webOS OSE project directory.
Line(2) : The local source directory. The syntax of the property is EXTERNALSRC:pn-<component>. For the value, input "<absolute path of the project directory>"
Line(3) : The local build directory. The syntax of the property is EXTERNALSRC_BUILD:pn-<component>. For the value, input "<absolute path of the project directory>/build/"
Line(4) : The appended revision version (PR) for building local source files. The syntax of the property is PR:append:pn-<component>. This property is optional.
Note We recommend that you add a trailing slash (/) at the end of all local directory paths, as in Line(2) and Line(3).
Build the Service
To build the component on the OpenEmbedded environment, enter the following commands on the shell.
After building the service, you must verify its functionality.
Copy the IPK to the target.
When the build is successful, oe-related directories are created under the project root directory. These directories are linked to the directory where the build output is generated from the actual build-webos sub-directory.
If com.example.service.native is not registered successfully, you will see a return message as below.
root@raspberrypi4-64:/# luna-send -n 1 -f luna://com.example.service.native/hello '{}'{"errorCode": -1,
"returnValue": false,
"errorText": "Service does not exist: com.example.service.native."}
Specify the Order of Execution on the Target
To verify that the service can run automatically after rebooting, add the service to the systemd’s start execution list. This ensures that the service runs automatically without the systemctl start command.
Update the file:webos-bd.target
Directory:/etc/systemd/system (on the target device)
Modify Systemd Execution List on webos-initscripts
Modify the webos-initscripts component which is responsible for systemd configuration in webOS. Through this process, you can learn how to modify a built-in component in webOS.
Download the webos-initscripts component source from GitHub repository to your local system.
In this document, we download the webos-initscripts component to ~/project/webOS/webos-initscripts.