Tizen Native API  10.0
System Information Plugin Interface

The System Information Plugin API provides internal interfaces for implementing system information plugins. This section provides internal documentation for system information plugin development including complete implementation examples.

Required Header

#include <system_info_intf.h>

Overview

The System Information Plugin API provides internal interfaces that allow OEMs and vendors to implement custom system information plugins. These plugins enable the extension of system information capabilities by adding custom key/value pairs that are not part of the standard Tizen platform.

Custom Keys

Custom keys are system information keys that are defined and implemented by OEMs or vendors, rather than being part of the standard Tizen platform. These keys allow device manufacturers to provide device-specific information that can be accessed through the System Information API.

Features of custom keys:

  • Custom keys are defined using the "custom" tag (TAG_CUSTOM)
  • They support various data types: boolean (TYPE_BOOL), integer (TYPE_INT), double (TYPE_DBL), and string (TYPE_STR)
  • Custom keys are accessed through the same System Information API functions as platform keys, but with the "custom" tag
  • The implementation of custom keys is done through external plugins that implement the system_info_external_plugin_interface

To implement a custom system information plugin:

  1. Implement the get_value_external function pointer to retrieve values for custom keys
  2. Implement the get_type_external function pointer to return the data type of custom keys
  3. Register the plugin interface with the system information framework
Note:
This interface is intended for internal use by OEMs and vendors implementing system information plugins. Application developers should use the public System Information API functions instead.

Buffer Value Format Requirements

All getter functions in system information plugins must store values as strings in the provided buffer, regardless of the actual data type. This is a critical requirement that all plugin implementations must follow:

  • For boolean values: store "true" or "TRUE" for true, any other string for false
  • For integer values: store the integer as a string (e.g., "42")
  • For double values: store the double as a string (e.g., "3.14")
  • For string values: store the string directly

This string-based approach allows the system information framework to handle all data types uniformly and provides flexibility for data representation.

Boolean Type Handling

For boolean type keys, the System Information API has specific handling requirements:

  • Only "true" or "TRUE" (case-sensitive) are recognized as true values
  • All other string values (including "false", "FALSE", "0", "1", etc.) are interpreted as false

Complete Plugin Implementation Example

The following example demonstrates a complete system information plugin implementation that provides custom device information keys. This example shows how to implement static device information keys that don't change at runtime.

File Structure

A typical system information plugin consists of a single implementation file:

  • system_info_plugin_example.c - Main plugin implementation with getter functions

Complete Implementation Code

 {.c}
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <system_info.h>
 #include <system_info_intf.h>

 // Custom key prefix for this plugin
 #define CUSTOM_EXAMPLE_KEY_PREFIX "http://example.com/system"

 // Key getter function prototypes
 static int system_info_plugin_get_device_has_fingerprint_sensor(char *val, unsigned int buf_size);
 static int system_info_plugin_get_device_max_core_count(char *val, unsigned int buf_size);
 static int system_info_plugin_get_device_hardware_version(char *val, unsigned int buf_size);

 // Plugin key list structure
 struct system_info_plugin_key {
     const char *key;
     const char *type;
     int (*get_value)(char *buf, unsigned int len);
 };

 // Define supported custom keys (only static device information)
 static struct system_info_plugin_key system_info_plugin_key_list[] = {
     { CUSTOM_EXAMPLE_KEY_PREFIX"/device.has_fingerprint_sensor", TYPE_BOOL, system_info_plugin_get_device_has_fingerprint_sensor },
     { CUSTOM_EXAMPLE_KEY_PREFIX"/device.max_core_count", TYPE_INT, system_info_plugin_get_device_max_core_count },
     { CUSTOM_EXAMPLE_KEY_PREFIX"/device.hardware_version", TYPE_STR, system_info_plugin_get_device_hardware_version },
 };

 // Find key in the key list
 static struct system_info_plugin_key *system_info_plugin_find_key(const char *key)
 {
     int elem;
     int len = sizeof(system_info_plugin_key_list) / sizeof(struct system_info_plugin_key);

     for (elem = 0; elem < len; elem++)
         if (!strncmp(key, system_info_plugin_key_list[elem].key, strlen(key) + 1))
             return &system_info_plugin_key_list[elem];

     return NULL;
 }

 // Get value for a custom key
 static int system_info_plugin_get_value(const char *tag, const char *key, const char *type, char *buf, unsigned int len)
 {
     int ret;
     struct system_info_plugin_key *elem = system_info_plugin_find_key(key);

     if (!elem || !elem->type)
         return SYSTEM_INFO_ERROR_INVALID_PARAMETER;

     ret = elem->get_value(buf, len);
     if (ret != SYSTEM_INFO_ERROR_NONE)
         return ret;

     return SYSTEM_INFO_ERROR_NONE;
 }

 // Get type for a custom key
 static int system_info_plugin_get_type(const char *tag, const char *key, char *buf, unsigned int len)
 {
     struct system_info_plugin_key *elem = system_info_plugin_find_key(key);

     if (!elem || !elem->type)
         return SYSTEM_INFO_ERROR_INVALID_PARAMETER;

     snprintf(buf, len, "%s", elem->type);
     return SYSTEM_INFO_ERROR_NONE;
 }

 // Get device fingerprint sensor support (boolean type)
 int system_info_plugin_get_device_has_fingerprint_sensor(char *val, unsigned int buf_size)
 {
     if (buf_size < 6) { // Enough for "true" or "false"
         return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
     }

     // Example: Check if fingerprint sensor device file exists
     FILE *fp = fopen("/sys/class/fingerprint/fingerprint0/present", "r");
     if (fp) {
         fclose(fp);
         snprintf(val, buf_size, "true"); // Must be exactly "true" or "TRUE"
     } else {
         snprintf(val, buf_size, "false");
     }

     return SYSTEM_INFO_ERROR_NONE;
 }

 // Get device max core count (integer type)
 int system_info_plugin_get_device_max_core_count(char *val, unsigned int buf_size)
 {
     if (buf_size < 4) { // Enough for up to 3 digits + null terminator
         return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
     }

     // Example: Read from CPU info
     FILE *fp = fopen("/sys/devices/system/cpu/present", "r");
     if (!fp) {
         snprintf(val, buf_size, "4"); // Default value
         return SYSTEM_INFO_ERROR_NONE;
     }

     char range[32];
     if (!fgets(range, sizeof(range), fp)) {
         fclose(fp);
         snprintf(val, buf_size, "4"); // Default value
         return SYSTEM_INFO_ERROR_NONE;
     }

     fclose(fp);

     // Parse range like "0-3" to get core count (4 cores)
     int start, end;
     if (sscanf(range, "%d-%d", &start, &end) == 2) {
         snprintf(val, buf_size, "%d", end + 1);
     } else {
         snprintf(val, buf_size, "4"); // Default value
     }

     return SYSTEM_INFO_ERROR_NONE;
 }

 // Get device hardware version (string type)
 int system_info_plugin_get_device_hardware_version(char *val, unsigned int buf_size)
 {
     if (buf_size < 16) {
         return SYSTEM_INFO_ERROR_INVALID_PARAMETER;
     }

     // Example: Read from system property
     char *hw_version = getenv("HW_VERSION");
     if (!hw_version) {
         snprintf(val, buf_size, "1.0.0"); // Default version
     } else {
         snprintf(val, buf_size, "%s", hw_version);
     }

     return SYSTEM_INFO_ERROR_NONE;
 }

 // Plugin interface definition
 static const system_info_external_plugin_interface interface = {
     .get_value_external = system_info_plugin_get_value,
     .get_type_external = system_info_plugin_get_type
 };

 // Plugin interface accessor function
 const system_info_external_plugin_interface *system_info_get_external_plugin_interface(void)
 {
     return &interface;
 }

Usage Example

After implementing the plugin, you can access custom keys using the System Information API:

 {.c}
 #include <system_info.h>
 #include <stdio.h>
 #include <stdlib.h>

 int main()
 {
     char *str_value = NULL;
     int int_value;
     bool bool_value;
     int ret;

     // Get device fingerprint sensor support (boolean)
     ret = system_info_get_custom_bool("http://example.com/system/device.has_fingerprint_sensor", &bool_value);
     if (ret == SYSTEM_INFO_ERROR_NONE) {
         printf("Device Has Fingerprint Sensor: %s\n", bool_value ? "true" : "false");
     }

     // Get device max core count (integer)
     ret = system_info_get_custom_int("http://example.com/system/device.max_core_count", &int_value);
     if (ret == SYSTEM_INFO_ERROR_NONE) {
         printf("Device Max Core Count: %d\n", int_value);
     }

     // Get device hardware version (string)
     ret = system_info_get_custom_string("http://example.com/system/device.hardware_version", &str_value);
     if (ret == SYSTEM_INFO_ERROR_NONE) {
         printf("Device Hardware Version: %s\n", str_value);
         free(str_value);
     }

     return 0;
 }

Compiling the Plugin

Compile the plugin as a shared library:

 {.sh}
 gcc -fPIC -shared $(pkg-config --cflags --libs capi-system-info-plugin) \
     system_info_plugin_example.c -o libsystem-info-plugin-example.so

When using other build systems, you must also add the equivalent compiler and linker flags provided by capi-system-info-plugin.pc.

Installing the Plugin

The plugin library must be installed in one of the following locations to be recognized by the system:

1. Install as a single external plugin library:

 {.sh}
 cp libsystem-info-plugin-example.so /usr/lib/libsystem-info-external-plugin.so
 # or
 cp libsystem-info-plugin-example.so /usr/lib64/libsystem-info-external-plugin.so

2. Or install in the plugins directory:

 {.sh}
 cp libsystem-info-plugin-example.so /usr/lib/libsystem_info_plugins/
 # or
 cp libsystem-info-plugin-example.so /usr/lib64/libsystem_info_plugins/
Note:
The plugin filename must have the .so extension to be recognized as a shared library.
The system information searches for custom keys in the following order: 1. First, it searches the /usr/lib/libsystem-info-external-plugin.so 2. Then, it searches the plugins directory, /usr/lib/libsystem_info_plugins/, for libraries in alphabetical order by filename

Important Implementation Notes

  • The plugin must be compiled as a shared library with the .so extension
  • The plugin must export the system_info_get_external_plugin_interface function that returns a pointer to the plugin interface structure
  • The plugin interface accessor function name must be exactly system_info_get_external_plugin_interface for the system information framework to properly load and recognize the plugin
  • All getter functions must return SYSTEM_INFO_ERROR_NONE on success
  • Buffer size validation should be performed in all getter functions
  • Error handling should follow the System Information API error codes
  • The plugin should provide static device information that doesn't change at runtime
  • All values must be stored as strings regardless of data type (see Buffer Value Format Requirements section)
  • Boolean values must be exactly "true" or "TRUE" to be recognized as true (see Boolean Type Handling section)