SystemControl HAL 介绍

1. 概述

SystemControl HAL 服务是实现图像、色温、音频、展频等选项的功能设置和数据开关机存储,其软件架构分为 SystemControl AIDL 接口、SystemControl AIDL 服务器和相关的 Selinux 配置。以下将围绕接口及功能、数据存储方式、开机初始化流程、以及用户菜单和工厂菜单的部分功能展开介绍。

2. SystemControl HAL 软件架构介绍

2.1. SystemControl AIDL 接口

SystemControl AIDL 目录位于 /vendor/sigmastar/interfaces/systemcontrol/aidl ,其层级结构如下:

.
├── aidl_api
│   └── vendor.sstar.hardware.systemcontrol
│       └── current
│           └── vendor
│               └── sstar
│                   └── hardware
│                       └── systemcontrol
│                           ├── AspectRatio.aidl
│                           ├── AudioOutputDev.aidl
│                           ├── ColorTemperatureInfo.aidl
│                           ├── ColorTemperatureItem.aidl
│                           ├── ColorTemperatureMode.aidl
│                           ├── DisplayId.aidl
│                           ├── InputSource.aidl
│                           ├── ISystemControl.aidl
│                           ├── Nonlinearity.aidl
│                           ├── NonlinearityItem.aidl
│                           ├── NonlinearityType.aidl
│                           ├── PictureMode.aidl
│                           ├── PictureModeItem.aidl
│                           ├── PictureQuality.aidl
│                           ├── SoundMode.aidl
│                           ├── SpdifMode.aidl
│                           ├── SpreadSpectrumItem.aidl
│                           ├── SpreadSpectrumParameter.aidl
│                           └── SpreadSpectrumType.aidl
│                           └── ... ...
├── Android.bp
└── vendor
    └── sstar
        └── hardware
            └── systemcontrol
                ├── AspectRatio.aidl
                ├── AudioOutputDev.aidl
                ├── ColorTemperatureInfo.aidl
                ├── ColorTemperatureItem.aidlrol
                ├── ColorTemperatureMode.aidl
                ├── DisplayId.aidl
                ├── InputSource.aidl
                ├── ISystemControl.aidl
                ├── Nonlinearity.aidl
                ├── NonlinearityItem.aidl
                ├── NonlinearityType.aidl
                ├── PictureMode.aidl
                ├── PictureModeItem.aidl
                ├── PictureQuality.aidl
                ├── SoundMode.aidl
                ├── SpdifMode.aidl
                ├── SpreadSpectrumItem.aidl
                ├── SpreadSpectrumParameter.aidl
                └── SpreadSpectrumType.aidl
                └── ... ...

需要注意的是:

  • AIDL 文件名称要与目录层级相对应,vendor.sstar.hardware.systemcontrol AIDL 对应的目录层级为vendor/sstar/hardware/systemcontrol

  • aidl_api 目录下为 SDK 工具编译后自动生成的 AIDL 接口文件,并生成 vendor.sstar.hardware.systemcontrol/current 目录存放当前的 AIDL 接口文件,每次修改当前版本的 AIDL 接口时都需要使用 SDK 工具更新一次接口。

  • 如果删除了某个接口文件时,更新接口之后 aidl_api 目录下的生成文件不会自动更新删除,需要手动去删除或者重新生成。

2.1.1. SystemControl AIDL 类型

  • 接口

    ISystemControl.aidl 为例,该接口定义了一系列需要后端实现的方法,方法的参数可以是零个或者多个。方法的参数类型可以是 inout 或 inout ,代表的是 IPC 调用时参数的传递方向,in 是默认方向,表示数据从调用方传递给被调用方,out 表示数据从被调用方传递给调用方,inout 是这两种方向的组合。可以在ISystemControl.aidl 文件中添加新方法用于 IPC 通信。

    package vendor.sstar.hardware.systemcontrol;
    
    import vendor.sstar.hardware.systemcontrol.AspectRatio;
    import vendor.sstar.hardware.systemcontrol.InputSource;
    ... ...
    
    @vintfstability
    interface ISystemControl {
        void setAspectRatio(in AspectRatio radio);
        InputSource getInputSource();
        ... ...
    }
    
  • 枚举

    AspectRatio.aidl 为例,如果不指定初始值,默认从 0 开始。其枚举由 Backing 指定存储类型,可以是 byte (8 bit)、int(32 bit) 、long (64 bit)类型,默认为 byte 类型。

    package vendor.sstar.hardware.systemcontrol;
    
    @Vintfstability
    @Backing(type="int")
    enm AspectRatio {
        RATIO_AUTO,
        RATIO_16TO9,
        ... ...
    }
    
  • Parcelable

    PictureQualityItem.aidl 为例,其作用是将多个枚举类型封装成类,故需要导入其他枚举类型的 AIDL 文件。如果需要在 AIDL 中自定义类作为参数或返回值,可以使用 Parcelable。

    package vendor.sstar.hardware.systemcontrol;
    
    import vendor.sstar.hardware.systemcontrol.InputSource;
    import vendor.sstar.hardware.systemcontrol.pictureMode;
    import vendor.sstar.hardware.systemcontrol.pictureQuality;
    import vendor.sstar.hardware.systemcontrol.DisplayId;
    
    @vintfstability
    parcelable PictureModeItem {
        DisplayId displayId = DisplayId PRIMARY;
    
        InputSource source = InputSource MEDIA;
    
        PictureMode mode = PictureMode STANDARD;
    
        PictureQuality quality pictureQuality BRIGHTNESS;
    }
    

    除了以上类型外,还可以使用联合体、常量等类型用于binder间通信。

2.1.2. SystemControl AIDL 更新或发布方法

同级目录下的对应的 Android.bp 文件如下:

aidl_interface {
    name: "vendor.sstar.hardware.systemcontrol",
    product_specific: true,
    vendor_available: true,
    owner: "sigmastar",
    srcs: ["vendor/sstar/hardware/systemcontrol/*.aidl"],
    stability: "vintf",
    backend: {
        java: {
            sdk_version: "module_current",
        },
        ndk: {
            enabled: true,
        },
        cpp: {
            enabled: false,
        },
    },
}

添加或修改 AIDL 接口后,可以在 aidl 根目录下执行该命令。执行后会在 vendor.sstar.hardware.systemcontrol/current 目录下自动更新 AIDL 接口文件,并在 out/soong/.intermediates/vendor/sigmastar/interfaces/systemcontrol/aidl/ 目录下生成对应的 IBinder 接口文件。

m vendor.sstar.hardware.systemcontrol-update-api

AIDL 接口稳定后,可通过以下命令进行冻结,AIDL 接口将被打上版本号并归档

m vendor.sstar.hardware.systemcontrol-freeze-api

执行完后将在 aidl_ap/vendor.sstar.hardware.systemcontrol/current 同级目录下生成冻结版本的 AIDL 文件:

.
├── aidl_api
│   └── vendor.sstar.hardware.systemcontrol
│       └── 1 // 冻结版本1接口目录
│       │   └── vendor
│       │       └── sstar
│       │           └── hardware
│       │               └── systemcontrol
│       │                   ├── AspectRatio.aidl
│       │                   └── ...
│       └── current // 当前开发版本接口目录
│           └── vendor
│               └── sstar
│                   └── hardware
│                       └── systemcontrol
│                           ├── AspectRatio.aidl
│                           └── ...
├── Android.bp
└── vendor
    └── sstar
        └── hardware
            └── systemcontrol
                ├── AspectRatio.aidl
                └── ...

冻结版本之后 Android.bp 文件也会被同步更新,更新之后的 Android.bp 文件如下:

aidl_interface {
    name: "vendor.sstar.hardware.systemcontrol",
    product_specific: true,
    vendor_available: true,
    owner: "sigmastar",
    srcs: ["vendor/sstar/hardware/systemcontrol/*.aidl"],
    stability: "vintf",
    backend: {
        java: {
            sdk_version: "module_current",
        },
        ndk: {
            enabled: true,
        },
        cpp: {
            enabled: false,
        },
    },
    versions: ["1"],
}

2.1.3. SystemControl AIDL 接口获取方法

例如在 SystemControlService 中获取 SystemControl AIDL 接口,需要先导入上述定义的接口、枚举、parcelable 等 AIDL 类型,再通过 ISystemControl.Stub.asInterface 绑定 ISystemControl 对象,之后便可以调用 ISystemControl 对象的接口方法。

// SystemControlService.java
import vendor.sstar.hardware.systemcontrol.ColorTemperatureItem;
import vendor.sstar.hardware.systemcontrol.ColorTemperatureMode;
import vendor.sstar.hardware.systemcontrol.DisplayId;
import vendor.sstar.hardware.systemcontrol.Isystemcontrol;
...

@Override
public void onCreate() {
    super.oncreate ()
    mSystemControl = ISystemControl.stub.asInterface
            ServiceManager.getservice(ISystemControl.DESCRIPTOR + "/default"));
    ...
}

2.2. SystemControl AIDL 服务器

SystemControl AIDL 的后端实现在 vendor/sigmastar/hardware/systemcontrol 目录中,目录层级如下:

.
├── Android.bp
├── main.cpp            // 服务启动文件
├── sstar_drm.h         // DRM驱动相关定义的头文件
├── SystemControl.cpp   // 后端接口实现的cpp文件
├── system_control_factory_configuration.xml
├── SystemControl.h     // 后端接口定义的头文件
├── systemcontrol.rc    // 启动配置文件
├── system_control_user_configuration.xml
└── systemcontrol.xml   // 设备清单文件

SystemControl.h 用于定义后端接口,可以参考 SystemControl AIDL 在上述 out 目录下自动生成的 ISystemControl.h 文件,实现如下:

#include <aidl/vendor/sstar/hardware/systemcontrol/BnSystemControl.h> // 引用ndk接口的头文件

namespace aidl {
namespace vendor {
namespace sstar {
namespace hardware {
namespace systemcontrol {

class SystemControl : public BnSystemControl { // 具体的后端实现
    ndk::ScopedAStatus setInputSource(InputSource source) override; // 后端实现接口
    ...
};

} // namespace systemcontrol
} // namespace hardware
} // namespace sstar
} // namespace vendor
} // namespace aidl

在服务注册进程文件 main.cpp 实现如下:

#include "systemcontrol-impl/SystemControl.h"

#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>

using aidl::vendor::sstar::hardware::systemcontrol::SystemControl;

int main() {
    ABinderProcess_setThreadPoolMaxThreadCount(0);

    // make a default systemcontrol service
    LOG(INFO) << "SystemControl service start"; // 这里打印一句log说明服务正常启动
    auto sc = ndk::SharedRefBase::make<SystemControl>();
    const std::string scName = std::string() + SystemControl::descriptor +
                               "/default"; // 静态获取接口描述符作为服务名字
    binder_status_t status = AServiceManager_addService(sc->asBinder().get(),
    scName.c_str()); // 添加binder服务
    CHECK(status == STATUS_OK);

    ABinderProcess_joinThreadPool();
    return EXIT_FAILURE; // should not reach
}

systemcontrol.rc 文件实现了 SystemControl AIDL 的启动配置,通过 service 命令声明了 vendor.sstar.hardware.systemcontrol 是一个开机自启动的服务,且被 kill 之后能重启,实现如下:

service vendor.sstar.hardware.systemcontrol /vendor/bin/hw/vendor.sstar.hardware.systemcontrol-service
    class hal
    user system
    group system

on post-fs-data
    mkdir /data/vendor/hardware/system_control 0777 system system
    chown system system /mnt/factory/system_control_factory_configuration.xml

实现 systemcontrol.xml 设备清单文件:

<manifest version="1.0" type="device">
    <hal format="aidl">
        <name>vendor.sstar.hardware.systemcontrol</name>
        <fqname>ISystemControl/default</fqname>
    </hal>
</manifest>

2.3. Selinux 配置

先在 service.te 文件中配置 SystemControl HAL 服务上下文:

type hal_systemcontrol_service, service_manager_type, vendor_service;

由于 SystemControl HAL 是客制化的 HAL,这里必须在设备专用 service_contexts 文件中添加如下:

vendor.sstar.hardware.systemcontrol.ISystemcontrol/default u:object_r:hal_systemcontrol_service:s0

在 hal_systemcontrol_default_te 文件中制定权限政策:

# systemcontrol aidl service
type hal_systemcontrol_default, domain;

type hal_systemcontrol_default_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_systemcontrol_default)

type systemcontrol_configs_file, file_type;
file_type_auto_trans(hal_systemcontrol_default, vendor_data_file, systemcontrol_configs_file)

# Allow for set the display related persist property
set_prop(hal_systemcontrol_default, vendor_display_prop)

allow hal_systemcontrol_default mnt_factory_file:file rw_file_perms;
allow hal_systemcontrol_default mnt_factory_file:dir r_dir_perms;

allow hal_systemcontrol_default gpu_device:chr_file rw_file_perms;

vndbinder_use(hal_systemcontrol_default)

allow hal_systemcontrol_default composertransmission_service:service_manager { find };
neverallow {
  domain
  -hal_systemcontrol_default
  -init
  -vendor_init
} mnt_factory_file:file rw_file_perms;

hal_server_domain(hal_systemcontrol_default, hal_systemcontrol)
binder_ use(hal_systemcontrol_default)

需要注意的是,这里添加的neverallow规则是限定 mnt_factory_file 上下文访问 hal_systemcontrol_service ,即只有 factory 分区对 SystemControl HAL 有访问权限。

3. SystemControl AIDL 接口及功能介绍

3.1. 接口说明

SystemControl AIDL 接口返回值使用的是 ndk::ScopedAStatus 类,如果执行成功,则返回ndk::ScopedAStatus::ok() ,如果执行失败,则返回对应的异常情况,具体定义在 binder_status.h 文件中。

3.2. 图像设置相关接口介绍

3.2.1. setInputSource

  • 功能

    设置当前的信号源。

  • 语法

    setInputSource(InputSource source)
    
  • 参数

    参数 描述
    source 要设置的信号源,分为 HDMI / VGA / MEDIA
  • 返回值

    成功则返回 ok()

3.2.2. getInputSource

  • 功能

    获取当前的信号源。

  • 语法

    getInputSource(InputSource* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return 返回当前的信号源
  • 返回值

    • 成功则返回 ok()

3.2.3. setAspectRatio

  • 功能

    设置当前的屏幕宽高比。

  • 语法

    setAspectRatio(AspectRatio radio)
    
  • 参数

    参数 描述
    radio 要设置的屏幕宽高比,分为 RATIO_AUTO / RATIO_16TO9 / RATIO_4TO3 / RATIO_JUST_SCAN / RATIO_ZOOM1 / RATIO_ZOOM2
  • 返回值

    • 成功则返回 ok()

    • 失败则返回 STATUS_FAILED_TRANSACTION

3.2.4. getAspectRatio

  • 功能

    获取当前的屏幕宽高比

  • 语法

    getAspectRatio(AspectRatio* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return 返回当前的屏幕宽高比
  • 返回值

    • 成功则返回 ok()

3.2.5. setPictureQuality

  • 功能

    设置指定屏幕的图像参数,可以对亮度、对比度、饱和度、清晰度和色调进行调节,默认值都为 50 ;如果有设置非线性度,则将 value 映射成非线性值再设置到底层驱动。

  • 语法

    setPictureQuality(DisplayId displayId, PictureQuality quality, int32_t value)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    quality 图像参数,分为 BRIGHTNESS / CONTRAST / SATURATION / SHARPNESS / HUE
    value 可调范围为0-100
  • 返回值

    • 成功则返回 ok()

    • 获取DRM资源失败则返回 STATUS_FAILED_TRANSACTION ,调用 drmIoctl() 失败则返回 STATUS_INVALID_OPERATION

3.2.6. getPictureQuality

  • 功能

    获取指定屏幕下的图像参数对应的值。

  • 语法

    getPictureQuality(DisplayId displayId, PictureQuality quality, int32_t* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    quality 图像参数,分为 BRIGHTNESS / CONTRAST / SATURATION / SHARPNESS / HUE
    _aidl_return 返回选定屏幕和图像参数的值
  • 返回值

    • 成功则返回 ok()

3.2.7. setPictureMode

  • 功能

    设置指定屏幕的图像模式,可以切换标准、电影、动态、柔和、游戏和自定义模式,随即生效的是上一次该模式下各个图像参数所保存的值

  • 语法

    setPictureMode(DisplayId displayId, PictureMode mode)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    mode 图像模式,分为 STANDARD / FILM / DYNAMIC / SOFT / GAME / CUSTOMIZED
  • 返回值

    • 成功则返回 ok()

    • 获取 DRM 资源失败则返回 STATUS_FAILED_TRANSACTION ,调用 drmIoctl() 失败则返回 STATUS_INVALID_OPERATION

3.2.8. getPictureMode

  • 功能

    获取指定屏幕生效的图像模式

  • 语法

    getPictureMode(DisplayId displayId, PictureMode* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回屏幕对应的图像模式
  • 返回值

    • 成功则返回 ok()

3.3. 色温设置相关接口介绍

3.3.1. setWhiteBalance

  • 功能

    设置指定屏幕的色温,可以对 R 、G 、B 、R_offset 、G_offset 、B_offset 三原色及其偏移进行调节,其中 R 、G 、B 的默认值为128,R_offset 、G_offset 、B_offset 设置功能还未开发,默认值为 0。

  • 语法

    setWhiteBalance(DisplayId displayId, WhiteBalanceInfo info, int32_t value)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    info 色温参数,分为 R / G / B / R_offset / G_offset / B_offset
    value 可调范围为 0 - 255
  • 返回值

    • 成功则返回 ok()

    • 获取DRM资源失败则返回 STATUS_FAILED_TRANSACTION ,调用 drmIoctl() 失败则返回 STATUS_INVALID_OPERATION

3.3.2. getWhiteBalance

  • 功能

    获取指定屏幕下选定色温参数对应的值。

  • 语法

    getWhiteBalance(DisplayId displayId, WhiteBalanceInfo info, int32_t* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    info 色温参数,分为 R / G / B / R_offset / G_offset / B_offset
    _aidl_return 返回对应屏幕和色温参数的值
  • 返回值

    • 成功则返回 ok()

3.3.3. setColorTemperatureMode

  • 功能

    设置指定屏幕的色温模式,可以切换为暖色、冷色、自然色和自定义模式,随即生效的是上一次该模式下各个色温参数所保存的值。

  • 语法

    setColorTemperatureMode(DisplayId displayId, ColorTemperatureMode mode)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    mode 色温模式,分为 NATURE / COOL / WARM
  • 返回值

    • 成功则返回 ok()

    • 获取DRM资源失败则返回 STATUS_FAILED_TRANSACTION ,调用 drmIoctl() 失败则返回 STATUS_INVALID_OPERATION

3.3.4. getColorTemperatureMode

  • 功能

    获取指定屏幕下生效的色温模式。

  • 语法

    getColorTemperatureMode(DisplayId displayId, ColorTemperatureMode* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回屏幕对应的色温模式
  • 返回值

    • 成功则返回 ok()

3.4. 音频设置相关接口介绍

3.4.1. setSoundMode

  • 功能

    设置当前的声音模式,可切换标准、电影、新闻、运动和音乐模式。

  • 语法

    setSoundMode(SoundMode mode)
    
  • 参数

    参数 描述
    mode 声音模式,分为 STANDARD / MOVIE / NEWS / SPORTS / MUSIC
  • 返回值

    • 成功则返回 ok()

3.4.2. getSoundMode

  • 功能

    获取当前的声音模式。

  • 语法

    getSoundMode(SoundMode* _aidl_return)
    
  • 参数

    参数 描述
    mode 声音模式,分为 STANDARD / MOVIE / NEWS / SPORTS / MUSIC
  • 返回值

    • 成功则返回 ok()

3.4.3. setAudioOutputDevice

  • 功能

    设置当前的音频输出设备,可切换 Speaker、SPDIF、HDMI_ARC 设备。

  • 语法

    setAudioOutputDevice(AudioOutputDev dev)
    
  • 参数

    参数 描述
    dev 音频输出设备,分为 SPEAKER / SPDIF / HDMI_ARC
  • 返回值

    • 成功则返回 ok()

3.4.4. getAudioOutputDevice

  • 功能

    获取当前的音频输出设备。

  • 语法

    getAudioOutputDevice(AudioOutputDev* _aidl_return)
    
  • 参数

    参数 描述
    dev 音频输出设备,分为 SPEAKER / SPDIF / HDMI_ARC
  • 返回值

    • 成功则返回 ok()

3.4.5. setAudioBalance

  • 功能

    设置当前的音频平衡。

  • 语法

    setAudioBalance(int32_t value)
    
  • 参数

    参数 描述
    value 设置范围为 0 - 100
  • 返回值

    • 成功则返回 ok()

3.4.6. getAudioBalance

  • 功能

    获取当前的音频平衡。

  • 语法

    getAudioBalance(int32_t* _aid1_return)
    
  • 参数

    参数 描述
    value 设置范围为 0 - 100
  • 返回值

    • 成功则返回 ok()

3.4.7. setSpdifMode

  • 功能

    设置当前的 spdif 模式,可切换 PCM 和 RAW 格式输出。

  • 语法

    setSpdifMode(SpdifMode mode)
    
  • 参数

    参数 描述
    mode spdif 模式,分为 PCM / RAW
  • 返回值

    • 成功则返回 ok()

3.4.8. getSpdifMode

  • 功能

    获取当前的 spdif 模式。

  • 语法

    getSpdifMode(SpdifMode* _aidl_return)
    
  • 参数

    参数 描述
    mode spdif 模式,分为 PCM / RAW
  • 返回值

    • 成功则返回 ok()

3.4.9. setAudioBass

  • 功能

    设置音频低音增益。

  • 语法

    setAudioBass(int32_t value)
    
  • 参数

    参数 描述
    value 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

3.4.10. getAudioBass

  • 功能

    获取音频低音增益。

  • 语法

    getAudioBass(int32_t* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

3.4.11. setAudioTreble

  • 功能

    设置音频高音增益。

  • 语法

    setAudioTreble(int32_t value)
    
  • 参数

    参数 描述
    value 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

3.4.12. getAudioTreble

  • 功能

    获取音频高音增益。

  • 语法

    getAudioTreble(int32_t* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

3.4.13. setAudioEqFrequency

  • 功能

    设置音频均衡器对应索引的频率。

  • 语法

    setAudioEqFrequency(AudioEqFilter index, int32_t value)
    
  • 参数

    参数 描述
    index AudioEqFilter 枚举类型,可选 INDEX_0 / INDEX_1 / INDEX_2 / INDEX_3 / INDEX_4
    value 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

3.4.14. getAudioEqFrequency

  • 功能

    获取音频均衡器对应索引的频率。

  • 语法

    ndk::ScopedAStatus getAudioEqFrequency(AudioEqOption option, int32_t* _aidl_return)
    
  • 参数

    参数 描述
    index AudioEqFilter 枚举类型,可选 INDEX_0 / INDEX_1 / INDEX_2 / INDEX_3 / INDEX_4
    _aidl_return 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

3.4.15. setAudioEqGain

  • 功能

    设置音频均衡器对应索引的增益。

  • 语法

    setAudioEqGain(AudioEqOption option, int32_t value)
    
  • 参数

    参数 描述
    index AudioEqFilter 枚举类型,可选 INDEX_0 / INDEX_1 / INDEX_2 / INDEX_3 / INDEX_4
    value 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

3.4.16. getAudioEqGain

  • 功能

    获取音频均衡器对应索引的增益。

  • 语法

    getAudioEqGain(AudioEqOption option, int32_t* _aidl_return)
    
  • 参数

    参数 描述
    index AudioEqFilter 枚举类型,可选 INDEX_0 / INDEX_1 / INDEX_2 / INDEX_3 / INDEX_4
    _aidl_return 范围为 (-8) - 8
  • 返回值

    • 成功则返回 ok()

    除以上接口外,还提供了 AUDIO APC,ANR,EQ,HPF,AGC,DRC 等参数获取接口,不在此赘述。

3.5. 菜单其他参数设置相关接口介绍

3.5.1. setNonlinearityItem

  • 功能

    设置背光、亮度、对比度、饱和度、锐度、色调和音量曲线的非线性度,将这些曲线设置的线性值映射成非线性值。

  • 语法

    setNonlinearityItem(const NonlinearityItem& item, int32_t value)
    
  • 参数

    参数 描述
    item NonlinearityItem 是 Parcelable 自定义类,包含 BACKLIGHTBRIGHTNESSCONTRASTSATURATIONSHARPNESSHUEVOLUME_CURVE 七种枚举变量,每种枚举变量都有 POINT_0 / POINT_25 / POINT_50 / POINT_75 / POINT_100 五档数值
    value 可调范围为 0 - 100
  • 返回值

    • 成功则返回 ok()

3.5.2. getNonlinearityItem

  • 功能

    获取指定参数曲线下某个档位的值。

  • 语法

    getNonlinearityItem(const NonlinearityItem& item, int32_t* _aid1_return)
    
  • 参数

    参数 描述
    item NonlinearityItem 是 Parcelable 自定义类,包含 BACKLIGHTBRIGHTNESSCONTRASTSATURATIONSHARPNESSHUEVOLUME_CURVE 七种枚举变量,每种枚举变量都有 POINT_0 / POINT_25 / POINT_50 / POINT_75 / POINT_100 五档数值
    _aid1_return 返回选定参数曲线和档位的值
  • 返回值

    • 成功则返回 ok()

3.5.3. enableSpreadSpectrum

  • 功能

    展频类型使能,设置之后生效的是该展频类型上一次保存的展频参数。

  • 语法

    enableSpreadSpectrum(DisplayId displayId, SpreadSpectrumType type, bool on)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    type 展频类型,分为 PANEL / DDRAM
    on true 或者 false,选择是否使能
  • 返回值

    • 成功则返回 ok()

    • 获取DRM资源失败则返回 STATUS_FAILED_TRANSACTION ,调用 drmIoctl() 失败则返回 STATUS_INVALID_OPERATION

3.5.4. isSpreadSpectrumEnable

  • 功能

    判断该展频类型是否使能。

  • 语法

    isSpreadSpectrumEnable(DisplayId displayId, SpreadSpectrumType type, bool* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    type 展频类型,分为 PANEL / DDRAM
    _aidl_return 返回bool类型
  • 返回值

    • 成功则返回 ok()

3.5.5. setSpreadSpectrumItem

  • 功能

    设置展频参数,可调节指定屏幕选定展频类型对应的步长和展频范围。

  • 语法

    setSpreadSpectrumItem(const SpreadSpectrumItem& item, int32_t value)
    
  • 参数

    参数 描述
    item SpreadSpectrumItem 是 Parcelable 自定义类,包含 DisplayIdSpreadSpectrumTypeSpreadSpectrumItemParamenter 三种枚举变量,其中 DisplayId 分为 PRIMARY / SECONDARYSpreadSpectrumType 分为 PANEL / DDRAMSpreadSpectrumItemParamenter 分为 RADIO / FREQ
    value RADIO 对应的设置范围为 0 - 32,FREQ 对应的设置范围为 0 - 10
  • 返回值

    • 成功则返回 ok()

    • 获取DRM资源失败则返回 STATUS_FAILED_TRANSACTION ,调用 drmIoctl() 失败则返回 STATUS_INVALID_OPERATION

3.5.6. setVideoMutecolor

  • 功能

    设置视频黑屏颜色,有黑色、白色、红色、绿色、蓝色五种颜色可选。

  • 语法

    setVideoMutecolor(int32_t value)
    
  • 参数

    参数 描述
    value 范围 0 - 4,分别对应黑色、白色、红色、绿色、蓝色
  • 返回值

    • 成功则返回 ok()

3.5.7. getVideoMuteColor

  • 功能

    获取视频黑屏颜色。

  • 语法

    getVideoMuteColor(int32_t* _aid1_return)
    
  • 参数

    参数 描述
    _aid1_return 范围 0 - 4,分别对应黑色、白色、红色、绿色、蓝色
  • 返回值

    • 成功则返回 ok()

3.5.8. setVideoPattern

  • 功能

    设置视频模式。

  • 语法

    setVideoPattern(int32_t pattern)
    
  • 参数

    参数 描述
    pattern 范围 0 - 4,具体 pattern 还未定义
  • 返回值

    • 成功则返回 ok()

3.5.9. getVideoPattern

  • 功能

    获取视频模式。

  • 语法

    getVideoPattern(int32_t* _aidl_return)
    
  • 参数

    参数 描述
    _aid1_return 范围 0 - 4
  • 返回值

    • 成功则返回 ok()

3.5.10. setHdmiDrivecurrent

  • 功能

    设置 HDMI 驱动电流。

  • 语法

    setHdmiDrivecurrent(int32_t current)
    
  • 参数

    参数 描述
    current 范围 0 - 32
  • 返回值

    • 成功则返回 ok()

3.5.11. getHdmiDrivecurrent

  • 功能

    获取 HDMI 驱动电流。

  • 语法

    getHdmiDrivecurrent(int32_t* _aid1_return)
    
  • 参数

    参数 描述
    _aid1_return 范围 0 - 32
  • 返回值

    • 成功则返回 ok()

3.5.12. setLvdsDrivecurrent

  • 功能

    设置 LVDS 驱动电流。

  • 语法

    setLvdsDrivecurrent(int32_t current)
    
  • 参数

    参数 描述
    current 范围 0 - 32
  • 返回值

    • 成功则返回 ok()

3.5.13. getLvdsDrivecurrent

  • 功能

    获取 LVDS 驱动电流。

  • 语法

    getLvdsDrivecurrent(int32_t* _aid1_return)
    
  • 参数

    参数 描述
    _aid1_return 范围 0 - 32
  • 返回值

    • 成功则返回 ok()

3.5.14. enablesoftwareWatchDog

  • 功能

    设置软件看门狗开启或关闭状态。

  • 语法

    enablesoftwareWatchDog(bool enable)
    
  • 参数

    参数 描述
    enable truefalse
  • 返回值

    • 成功则返回 ok()

3.5.15. isSoftwareWatchDogEnable

  • 功能

    获取软件看门狗开启或关闭状态。

  • 语法

    isSoftwareWatchDogEnable(bool* _aid1_return)
    
  • 参数

    参数 描述
    _aid1_return truefalse
  • 返回值

    • 成功则返回 ok()

3.5.16. setHdmiMuteThreshold

  • 功能

    设置 HDMI 信号源黑屏阈值。

  • 语法

    setHdmiMuteThreshold(int32_t thres)
    
  • 参数

    参数 描述
    thres 范围 0 - 32
  • 返回值

    • 成功则返回 ok()

3.5.17. getHdmiMuteThreshold

  • 功能

    获取 HDMI 信号源黑屏阈值。

  • 语法

    getHdmiMuteThreshold(int32_t* _aid1_return)
    
  • 参数

    参数 描述
    current 范围 0 - 32
  • 返回值

    • 成功则返回 ok()

3.6. 外设模块相关接口介绍

外设模块包含 I2C、PWM、UART、SPI、GPIO、ADC 功能,调用底层的 libperipherals.so,如果调用失败均返回 STATUS_FAILED_TRANSACTION

3.6.1. initI2c

  • 功能

    初始化 I2C。

  • 语法

    initI2c(int32_t i2cNo)
    
  • 参数

    参数 描述
    i2cNo I2C 通道
  • 返回值

    • 成功则返回 ok()

3.6.2. deInitI2c

  • 功能

    去初始化 I2C。

  • 语法

    deInitI2c(int32_t i2cNo)
    
  • 参数

    参数 描述
    i2cNo I2C 通道
  • 返回值

    • 成功则返回 ok()

3.6.3. setI2cRate

  • 功能

    I2C 设置通信速率。

  • 语法

    setI2cRate(int32_t i2cNo, int32_t rate)
    
  • 参数

    参数 描述
    i2cNo I2C 通道
    rate 要配置的 I2C 速率
  • 返回值

    • 成功则返回 ok()

3.6.4. getI2cRate

  • 功能

    I2C 获取通信速率。

  • 语法

    getI2cRate(int32_t i2cNo, int32_t* rate)
    
  • 参数

    参数 描述
    i2cNo I2C 通道
    rate 返回获取到的 I2C 速率
  • 返回值

    • 成功则返回 ok()

3.6.5. writeI2c

  • 功能

    I2C 写数据。

  • 语法

    writeI2c(int32_t i2cNo, const I2cAddr& addr, const std::vector<char16_t>& data, int32_t length)
    
  • 参数

    参数 描述
    i2cNo I2C 通道
    addr I2C 从机信息,I2cAddr 是 Parcelable 自定义类,包含 slaveAddrregAddrI2cRegAddrBitslaveAddrregAddr 分别为从机地址和寄存器地址,I2cRegAddrBit 是表述寄存器地址位数的枚举类型,有 ADDR_8_BITADDR_16_BITADDR_24_BITADDR_32_BIT 四种
    data 要写入的数据
    length 数据长度
  • 返回值

    • 成功则返回 ok()

3.6.6. readI2c

  • 功能

    I2C 读数据。

  • 语法

    readI2c(int32_t i2cNo, const I2cAddr& addr, int32_t length, std::vector<char16_t>* _aidl_return)
    
  • 参数

    参数 描述
    i2cNo I2C 通道
    addr I2C 从机信息,I2cAddr 是 Parcelable 自定义类,包含 slaveAddrregAddrI2cRegAddrBitslaveAddrregAddr 分别为从机地址和寄存器地址,I2cRegAddrBit 是表述寄存器地址位数的枚举类型,有 ADDR_8_BITADDR_16_BITADDR_24_BITADDR_32_BIT 四种
    _aidl_return 返回读取到的数据
    length 数据长度
  • 返回值

    • 成功则返回 ok()

3.6.7. initPwm

  • 功能

    PWM 通道初始化,如果初始化成功,将在 /sys/class/pwm/pwmchip0 下生成对应通道号的 PWM 节点。

  • 语法

    initPwm(int32_t pwmNo)
    
  • 参数

    参数 描述
    pwmNo PWM 通道号
  • 返回值

    • 成功则返回 ok()

3.6.8. deInitPwm

  • 功能

    PWM 通道去初始化,如果去初始化成功,将注销 /sys/class/pwm/pwmchip0 对应PWM 节点。

  • 语法

    deInitPwm(int32_t pwmNo)
    
  • 参数

    参数 描述
    pwmNo PWM 通道号
  • 返回值

    • 成功则返回 ok()

3.6.9. setPwmEnable

  • 功能

    PWM 通道使能,必须要在 PWM 参数配置完之后使能。

  • 语法

    setPwmEnable(int32_t pwmNo, bool enable)
    
  • 参数

    参数 描述
    pwmNo PWM 通道号
  • 返回值

    • 成功则返回 ok()

3.6.10. setPwmAttr

  • 功能

    PWM 周期、占空比和极性参数配置,如果没有设置,周期和占空比默认为 0,极性默认为 normal

  • 语法

    setPwmAttr(int32_t pwmNo, const PwmAttr& attr)
    
  • 参数

    参数 描述
    pwmNo PWM 通道号
    attr 返回 PWM 参数配置,PwmAttr 是 Parcelable 自定义类,包含 dutyperiodPwmPolarity。其中 dutyperiod 分别对应周期、占空比,PwmPolarity 是代表 PWM 极性的枚举类型,包含 NORMAL 正极性和 INVERSED 负极性
  • 返回值

    • 成功则返回 ok()

3.6.11. getPwmAttr

  • 功能

    获取 PWM 周期、占空比和极性参数配置。

  • 语法

    getPwmAttr(int32_t pwmNo, PwmAttr* _aidl_return)
    
  • 参数

    参数 描述
    pwmNo PWM 通道号
    _aidl_return PWM 参数配置,PwmAttr 是 Parcelable 自定义类,包含 dutyperiodPwmPolarity。其中 dutyperiod 分别对应周期、占空比,PwmPolarity 是代表 PWM 极性的枚举类型,包含 NORMAL 正极性和 INVERSED 负极性
  • 返回值

    • 成功则返回 ok()

3.6.12. initUart

  • 功能

    UART 通道初始化。

  • 语法

    initUart(int32_t uartNo)
    
  • 参数

    参数 描述
    uartNo UART 通道号
  • 返回值

    • 成功则返回 ok()

3.6.13. deInitUart

  • 功能

    UART 通道去初始化。

  • 语法

    deInitUart(int32_t uartNo)
    
  • 参数

    参数 描述
    uartNo UART 通道号
  • 返回值

    • 成功则返回 ok()

3.6.14. setUartAttr

  • 功能

    设置 UART 通道的波特率、数据位、停止位和校验位。

  • 语法

    setUartAttr(int32_t uartNo, const UartAttr& attr)
    
  • 参数

    参数 描述
    uartNo UART 通道号
    attr UART 参数配置,包括波特率、数据位、停止位和校验位。UartAttr 是 Parcelable 自定义类,包含 UartBuadUartDataBitUartStopBitUartParityUartBuad 代表 UART 通信波特率,罗列在 UartBaud.aidl 文件中;UartDataBit 是数据位,有 DATABIT_5DATABIT_6DATABIT_7DATABIT_8 5 - 8 bit 位宽可以设置;UartStopBit 是停止位,可选 STOPBIT_1 一个停止位和 STOPBIT_1 两个停止位;UartParity 表示校验位,有 NON_PARITY 无校验位、ODD_PARITY 偶校验和 EVEN_PARITY 奇校验三种选项
  • 返回值

    • 成功则返回 ok()

3.6.15. getUartAttr

  • 功能

    获取 UART 通道的波特率、数据位、停止位和校验位。

  • 语法

    getUartAttr(int32_t uartNo, UartAttr* _aidl_return)
    
  • 参数

    参数 描述
    uartNo UART 通道号
    _aidl_return 返回获取到的 UART 参数配置,包括波特率、数据位、停止位和校验位。UartAttr 是 Parcelable 自定义类,包含 UartBuadUartDataBitUartStopBitUartParityUartBuad 代表 UART 通信波特率,罗列在 UartBaud.aidl 文件中;UartDataBit 是数据位,有 DATABIT_5DATABIT_6DATABIT_7DATABIT_8 5 - 8 bit 位宽可以设置;UartStopBit 是停止位,可选 STOPBIT_1 一个停止位和 STOPBIT_1 两个停止位;UartParity 表示校验位,有 NON_PARITY 无校验位、ODD_PARITY 偶校验和 EVEN_PARITY 奇校验三种选项
  • 返回值

    • 成功则返回 ok()

3.6.16. writeUart

  • 功能

    UART 写数据。

  • 语法

    writeUart(int32_t uartNo, const std::vector<char16_t>& buffer, int32_t length)
    
  • 参数

    参数 描述
    uartNo UART 通道号
    buffer 要写入的数据
    length 数据长度
  • 返回值

    • 成功则返回 ok()

3.6.17. readUart

  • 功能

    UART 读数据。

  • 语法

    readUart(int32_t uartNo, int32_t length, std::vector<char16_t>* _aidl_return)
    
  • 参数

    参数 描述
    uartNo UART 通道号
    _aidl_return 返回读取到的数据
    length 数据长度
  • 返回值

    • 成功则返回 ok()

3.6.18. initSpi

  • 功能

    SPI 通道初始化。

  • 语法

    initSpi(int32_t spiNo, int32_t devNo)
    
  • 参数

    参数 描述
    spiNo SPI 通道号
    devNo 设备号
  • 返回值

    • 成功则返回 ok()

3.6.19. deInitSpi

  • 功能

    SPI 通道去初始化。

  • 语法

    deInitSpi(int32_t spiNo, int32_t devNo)
    
  • 参数

    参数 描述
    spiNo SPI 通道号
    devNo 设备号
  • 返回值

    • 成功则返回 ok()

3.6.20. setSpiAttr

  • 功能

    设置 SPI 模式、LSB 或 MSB、位宽和最大通信速率。

  • 语法

    setSpiAttr(int32_t spiNo, int32_t devNo, const SpiAttr& attr)
    
  • 参数

    参数 描述
    spiNo SPI 通道号
    devNo 设备号
    attr SPI 参数配置。SpiAttr 是 Parcelable 自定义类,包含 SpiModeSpiFirstBytespiBitsPerWordspiMaxSpeedHzSpiMode 代表 SPI 模式,包含 SPI_MODE0 (CPOL=0,CPHA=0)、SPI_MODE1 (CPOL=0,CPHA=1)、SPI_MODE2 (CPOL=1,CPHA=0)、SPI_MODE3 (CPOL=1,CPHA=1);SpiFirstByte 决定 LSBMSBspiBitsPerWordspiMaxSpeedHz 变量可以设定位宽和最大通信速率
  • 返回值

    • 成功则返回 ok()

3.6.20. getSpiAttr

  • 功能

    获取 SPI 模式、LSB 或 MSB、位宽和最大通信速率。

  • 语法

    getSpiAttr(int32_t spiNo, int32_t devNo, const SpiAttr& _aidl_return)
    
  • 参数

    参数 描述
    spiNo SPI 通道号
    devNo 设备号
    _aidl_return 返回获取到的 SPI 参数配置。SpiAttr 是 Parcelable 自定义类,包含 SpiModeSpiFirstBytespiBitsPerWordspiMaxSpeedHzSpiMode 代表 SPI 模式,包含 SPI_MODE0 (CPOL=0,CPHA=0)、SPI_MODE1 (CPOL=0,CPHA=1)、SPI_MODE2 (CPOL=1,CPHA=0)、SPI_MODE3 (CPOL=1,CPHA=1);SpiFirstByte 决定 LSBMSBspiBitsPerWordspiMaxSpeedHz 变量可以设定位宽和最大通信速率
  • 返回值

    • 成功则返回 ok()

3.6.21. spiTransfer

  • 功能

    SPI 双向通信。

  • 语法

    spiTransfer(int32_t spiNo, int32_t devNo, const std::vector<char16_t>& tx, int32_t len, std::vector<char16_t>* _aidl_return)
    
  • 参数

    参数 描述
    spiNo SPI 通道号
    devNo SPI 通道号
    tx 要写入的数据
    _aidl_return 返回读取的数据
    length 数据长度
  • 返回值

    • 成功则返回 ok()

3.6.22. writeSpi

  • 功能

    SPI 写数据。

  • 语法

    writeSpi(int32_t spiNo, int32_t devNo, const std::vector<char16_t>& tx, int32_t length)
    
  • 参数

    参数 描述
    spiNo SPI 通道号
    devNo SPI 通道号
    tx 要写入的数据
    length 数据长度
  • 返回值

    • 成功则返回 ok()

3.6.23. readSpi

  • 功能

    SPI 读数据。

  • 语法

    readSpi(int32_t spiNo, int32_t devNo, int32_t length, std::vector<char16_t>* _aidl_return)
    
  • 参数

    参数 描述
    spiNo SPI 通道号
    devNo SPI 通道号
    _aidl_return 返回读取的数据
    length 数据长度
  • 返回值

    • 成功则返回 ok()

3.6.24. initGpio

  • 功能

    GPIO 通道初始化。

  • 语法

    initGpio(int32_t gpioNo)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
  • 返回值

    • 成功则返回 ok()

3.6.25. deInitGpio

  • 功能

    GPIO 通道去初始化。

  • 语法

    deInitGpio(int32_t gpioNo)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
  • 返回值

    • 成功则返回 ok()

3.6.26. writeGpio

  • 功能

    设置 GPIO 引脚的电平。

  • 语法

    writeGpio(int32_t gpioNo, bool highVolt)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
    highVolt true 代表写入高电平状态,false 表示写入低电平状态
  • 返回值

    • 成功则返回 ok()

3.6.27. readGpio

  • 功能

    读取 GPIO 引脚的电平。

  • 语法

    readGpio(int32_t gpioNo, bool* _aidl_return)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
    _aidl_return true 代表写入高电平状态,false 表示写入低电平状态
  • 返回值

    • 成功则返回 ok()

3.6.28. setGpioDirection

  • 功能

    设置 GPIO 端口方向。

  • 语法

    setGpioDirection(int32_t gpioNo, GpioDirection dir)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
    dir 端口方向,GpioDirection 是 Parcelable 自定义类,分别有 INOUTHIGHLOW 。值为 IN 时,表示输入模式,value 不可写。值为 OUT 时,表示输出模式,value 可写,值为 HIGH 时,表示输出模式,默认高电平状态,value 可写。值为 LOW 时,表示输出模式,默认低电平状态,value 可写。
  • 返回值

    • 成功则返回 ok()

3.6.29. getGpioDirection

  • 功能

    获取 GPIO 端口方向。

  • 语法

    getGpioDirection(int32_t gpioNo, GpioDirection* _aidl_return)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
    _aidl_return 端口方向,GpioDirection 是 Parcelable 自定义类,分别有 INOUTHIGHLOW 。值为 IN 时,表示输入模式,value 不可写。值为 OUT 时,表示输出模式,value 可写,值为 HIGH 时,表示输出模式,默认高电平状态,value 可写。值为 LOW 时,表示输出模式,默认低电平状态,value 可写。
  • 返回值

    • 成功则返回 ok()

3.6.30. setGpioEdge

  • 功能

    设置 GPIO 中断触发方式。

  • 语法

    setGpioEdge(int32_t gpioNo, GpioEdge edge)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
    edge 中断类型,GpioEdge 是 Parcelable 自定义类,分别有 NONERISINGFALLINGBOTHNONE 表示 disable gpio 中断,RISING 表示使能 gpio 中断并设置为上升沿触发,FALLING 表示使能 gpio 中断并设置为下降沿触发,BOTH 表示使能 gpio 中断并设置为双边沿触发
  • 返回值

    • 成功则返回 ok()

3.6.31. getGpioEdge

  • 功能

    获取 GPIO 中断触发方式。

  • 语法

    getGpioEdge(int32_t gpioNo, GpioEdge* _aidl_return)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
    _aidl_return 中断类型,GpioEdge 是 Parcelable 自定义类,分别有 NONERISINGFALLINGBOTHNONE 表示 disable gpio 中断,RISING 表示使能 gpio 中断并设置为上升沿触发,FALLING 表示使能 gpio 中断并设置为下降沿触发,BOTH 表示使能 gpio 中断并设置为双边沿触发
  • 返回值

    • 成功则返回 ok()

3.6.32. GpioPoll

  • 功能

    监听 GPIO 中断,开启线程轮询 poll() 返回值,若监听到中断触发,就会调用 registerGpioCallback 注册的中断处理函数。

  • 语法

    GpioPoll(int32_t gpioNo)
    
  • 参数

    参数 描述
    gpioNo GPIO 通道号
  • 返回值

    • 成功则返回 ok()

3.6.33. registerGpioCallback

  • 功能

    注册 GPIO 中断回调函数,如果 GPIO 中断被触发,则会调用注册的中断处理函数。

  • 语法

    registerGpioCallback(const std::shared_ptr`<`IGpioCallback`>`& callback)
    
  • 参数

    参数 描述
    callback 回调函数指针
  • 返回值

    • 成功则返回 ok()

3.6.34. initPwmAdc()

  • 功能

    用于 enable PWM-ADC。

  • 语法

    initPwmAdc()
    
  • 返回值

    • 成功则返回 ok()

3.6.35. deInitPwmAdc()

  • 功能

    用于 disable PWM-ADC。

  • 语法

    deInitPwmAdc()
    
  • 返回值

    • 成功则返回 ok()

3.6.36. setPwmAdcDmaConfig

  • 功能

    设置 ADC DMA Mode 相关的配置。

  • 语法

    setPwmAdcDmaConfig(int32_t align, int32_t enable, int32_t size)
    
  • 参数

    参数 描述
    align 设置数据对齐方式,1表示左对齐,0表示右对齐
    enable 设置是否 enable DMA mode,1表示 enable,0表示 disable
    size 设置用于存储ADC数据的内存大小,单位Byte。例如设为100时,表示0x100
  • 返回值

    • 成功则返回 ok()

3.6.37. setPwmAdcIntervalConfig

  • 功能

    设置采样间隔相关的配置。

  • 语法

    setPwmAdcIntervalConfig(int32_t count, int32_t time)
    
  • 参数

    参数 描述
    count 设置每个通道的采样次数,支持四档的采样次数设置,0:1 time;1:4 times;2:8 times;3:16 times
    time 设置每个通道的采样的时间:time * 167 ns
  • 返回值

    • 成功则返回 ok()

3.6.38. setPwmAdcRegularConfig

  • 功能

    设置 PWM-ADC 的 Regular Channel 采样相关的配置。

  • 语法

    setPwmAdcRegularConfig(const AdcConfig& attr)
    
  • 参数

    参数 描述
    config PWM-ADC 采样相关的配置,AdcConfig 内容如下,其中关于 Inject Channel 采样的项可以不用配置
    /**
    * Set pwm adc channel.
    * Format: total number, channel number, ...
    */
    char[] injectSequence;
    char[] regularSequence;
    
    /**
    * Set adc trigger mode.
    * 0~11 = PWM_PN trigger, 12 = sw trigger
    * 13 = externel trigger, 14 = freerun
    */
    int triggerMode;
    
    /**
    * Set adc trigger method.
    * 1 = one sequence per time
    * 0 = one channel per time
    */
    int triggerMethod;
    
    /**
    * Set adc sampling mode.
    * 0 = single mode , 1 = continuous mode
    */
    int regularContinuous;
    int injectContinuous;
    
    /**
    * Whether channel sampling starts or ends.
    * 1 = begin sampling , 0 = end sampling
    */
    int regularStart;
    int injectStart;
    
    /**
    * When trigger mode equal sw sw trigger,
    * set input channel number to trigger sampling.
    */
    int swTrigger;
    
  • 返回值

    • 成功则返回 ok()

3.6.39. setPwmAdcInjectConfig

  • 功能

    设置 PWM-ADC 的 Inject Channel 采样相关的配置。

  • 语法

    setPwmAdcInjectConfig(const AdcConfig& attr)
    
  • 参数

    参数 描述
    config PWM-ADC 采样相关的配置,AdcConfig 内容参考 setPwmAdcRegularConfig 接口描述,其中关于 Regular Channel 采样的项可以不用配置
  • 返回值

    • 成功则返回 ok()

3.6.40. setPwmAdcRefvol

  • 功能

    设置 PWM-ADC 的参考电压档位,参考电压有两个档位,1表示 3.3V,0表示 1.5V。当参考电压为 3.3V 的时候,需要输入外部电阻的阻值,单位为 Ohm。

  • 语法

    setPwmAdcRefvol(int32_t channel, int32_t level, int32_t rext)
    
  • 参数

    参数 描述
    channel 设置的 PWM-ADC 参考电压档位的通道号
    level 1表示 3.3V,0表示 1.5V
    rext 当参考电压为 3.3V 的时候,需要输入外部电阻的阻值,单位为 Ohm
  • 返回值

    • 成功则返回 ok()

3.6.51. getPwmAdcConfig

  • 功能

    获取 PWM-ADC 的参考电压档位。

  • 语法

    getPwmAdcConfig(int32_t* _aidl_return)
    
  • 参数

    参数 描述
    channel 获取到 1 表示 1.5V 档位,获取到 3 表示 3.3V 的档位
  • 返回值

    • 成功则返回 ok()

3.6.52. getPwmAdcValue

  • 功能

    输入 PWM-ADC 采样的通道号,获取 PWM-ADC 采样的值。

  • 语法

    getPwmAdcValue(int32_t adcNo, int32_t* _aidl_return)
    
  • 参数

    参数 描述
    adcNo PWM-ADC 采样的通道号
    value PWM-ADC 采样获取的值
  • 返回值

    • 成功则返回 ok()

3.6.53. setSarAdcChannel

  • 功能

    设置 SAR-ADC 的 Channel,SAR-ADC 有 2 个 Channel , Channel 0 和 Channel 1。

  • 语法

    setSarAdcChannel(int32_t adcNo)
    
  • 参数

    参数 描述
    adcNo 设置的 SAR-ADC 的通道号,0 表示 Channel 0,1 表示 Channel 1。
  • 返回值

    • 成功则返回 ok()

3.6.54. setSarAdcRefvol

  • 功能

    设置 SAR-ADC 的参考电压档位,参考电压有两个档位,分别为1.8V 和1.0V。

  • 语法

    setSarAdcRefvol(int32_t level)
    
  • 参数

    参数 描述
    level 设置的 SAR-ADC 参考电压档位,1 表示 1.8V,0 表示 1.0V
  • 返回值

    • 成功则返回 ok()

3.6.55. getSarAdcConfig

  • 功能

    获取 SAR-ADC 的参考电压档位,参考电压有两个档位,分别为1.8V和1.0V。

  • 语法

    getSarAdcConfig(int32_t* _aidl_return)
    
  • 参数

    参数 描述
    config 获取 SAR-ADC 参考电压档位,1 表示 1.8V,0 表示 1.0V
  • 返回值

    • 成功则返回 ok()

3.6.56. getSarAdcValue

  • 功能

    获取 SAR-ADC 的采样后的值。

  • 语法

    getSarAdcValue(int32_t* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return 获取的 SAR-ADC 的采样后的值,获取到的值范围在 0~0x3ff 之间。
  • 返回值

    • 成功则返回 ok()

3.7. PQ 设置相关接口介绍

3.7.1. setColorSpaceTransform

  • 功能

    设置指定屏幕的色域效果

  • 语法

    setColorSpaceTransform(DisplayId displayId, ColorSpaceTransform transform)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    transform 色域类型,分为 USER / BT601_L_TO_RGB_F / BT709_L_TO_RGB_F / BT2020_L_TO_RGB_F / BT601_F_TO_RGB_F / BT709_F_TO_RGB_F / BT2020_F_TO_RGB_F / BT601_L_TO_RGB_L / BT709_L_TO_RGB_L / BT2020_L_TO_RGB_L
  • 返回值

    • 成功则返回 ok()

3.7.2. getColorSpaceTransform

  • 功能

    获取指定屏幕生效的色域类型

  • 语法

    getColorSpaceTransform(DisplayId displayId, ColorSpaceTransform* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回当前设置的色域类型
  • 返回值

    • 成功则返回 ok()

3.7.3. enableDlc

  • 功能

    使能特定屏幕的 DLC 功能

  • 语法

    enableDlc(DisplayId displayId, bool enable)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    enable true 或者 false,选择是否使能
  • 返回值

    • 成功则返回 ok()

3.7.4. isDlcEnable

  • 功能

    判断指定屏幕的 DLC 功能是否生效

  • 语法

    isDlcEnable(DisplayId displayId, bool* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回bool类型
  • 返回值

    • 成功则返回 ok()

3.7.5. setDlcCurve

  • 功能

    设置指定屏幕的 DLC 曲线

  • 语法

    setDlcCurve(DisplayId displayId, DlcCurve curve)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    curve DLC 曲线类型,分为 LOW / MEDIUM / HIGH
  • 返回值

    • 成功则返回 ok()

3.7.6. getDlcCurve

  • 功能

    获取指定屏幕生效的 DLC 曲线

  • 语法

    getDlcCurve(DisplayId displayId, DlcCurve* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回当前设置的 DLC 曲线
  • 返回值

    • 成功则返回 ok()

3.7.7. enablePQBypass

  • 功能

    使能特定屏幕的 PQ bypass 功能

  • 语法

    enablePQBypass(DisplayId displayId, bool enable)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    enable true 或者 false,选择是否使能
  • 返回值

    • 成功则返回 ok()

3.7.8. isPQBypassEnable

  • 功能

    判断指定屏幕的 PQ bypass 功能是否生效

  • 语法

    isPQBypassEnable(DisplayId displayId, bool* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回bool类型
  • 返回值

    • 成功则返回 ok()

3.7.9. setPQBin

  • 功能

    设置指定屏幕所加载的 PQ.bin 文件索引

  • 语法

    setPQBin(DisplayId displayId, PQBin index)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    index PQ.bin 文件索引,INDEX_0
  • 返回值

    • 成功则返回 ok()

3.7.10. getPQBin

  • 功能

    获取指定屏幕生效的 PQ.bin 文件索引

  • 语法

    getPQBin(DisplayId displayId, PQBin* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回当前设置的 PQ.bin 文件索引
  • 返回值

    • 成功则返回 ok()

3.7.11. setGammaCurve

  • 功能

    设置指定屏幕的 gamma 曲线

  • 语法

    setGammaCurve(DisplayId displayId, GammaCurve curve)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    curve gamma 曲线类型,分为 CURVE_0 / CURVE_1 / CURVE_2 / CURVE_3 / CURVE_4 / CURVE_5 / CURVE_6 / CURVE_7 / CURVE_8
  • 返回值

    • 成功则返回 ok()

3.7.12. getGammaCurve

  • 功能

    获取指定屏幕生效的 gamma 曲线

  • 语法

    getGammaCurve(DisplayId displayId, GammaCurve* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回当前设置的 gamma 曲线
  • 返回值

    • 成功则返回 ok()

3.7.13. setHsyCurve

  • 功能

    设置指定屏幕的 HSY 曲线

  • 语法

    setHsyCurve(DisplayId displayId, HsyCurve curve)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    curve HSY 曲线类型,分为 HSY_CURVE_TYPE_STANDARD / HSY_CURVE_TYPE_BRIGHTNESS / HSY_CURVE_TYPE_SOFT / HSY_CURVE_TYPE_NATURAL / HSY_CURVE_TYPE_MOVE / HSY_CURVE_TYPE_USER / HSY_CURVE_TYPE_SPORT / HSY_CURVE_TYPE_GAME
  • 返回值

    • 成功则返回 ok()

3.7.14. getHsyCurve

  • 功能

    获取指定屏幕生效的 HSY 曲线

  • 语法

    getHsyCurve(DisplayId displayId, HsyCurve* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回当前设置的 HSY 曲线
  • 返回值

    • 成功则返回 ok()

3.7.15. getLumaInfo

  • 功能

    获取指定屏幕画面的最小亮度、最大亮度以及平均亮度

  • 语法

    getLumaInfo(DisplayId displayId, LumaInfo* _aidl_return)
    
  • 参数

    参数 描述
    displayId 屏幕类型,分为 PRIMARY / SECONDARY
    _aidl_return 返回当前画面的最小亮度、最大亮度以及平均亮度
  • 返回值

    • 成功则返回 ok()

3.8. 其他接口介绍

3.8.1. setEnvString

  • 功能

    设置环境变量,如果 value 为空字符且 var 变量存在,意为删除改变量及其内容。

  • 语法

    setEnvString(const std::string& var, const std::string& value)
    
  • 参数

    参数 描述
    var 环境变量名
    value 设置环境变量对应的内容,可以为空字符
  • 返回值

    • 成功则返回 ok()

3.8.2. getEnvString

  • 功能

    获取环境变量,如果 var 变量为空字符,则返回全部环境变量内容。

  • 语法

    getEnvString(const std::string& var, const std::string* _aidl_return)
    
  • 参数

    参数 描述
    var 环境变量名
    _aidl_return 返回环境变量对应的内容
  • 返回值

    • 成功则返回 ok()

3.8.3. setUartSwitch

  • 功能

    设置 Uart0 串口开关,可选是否打印串口信息。

  • 语法

    setUartSwitch(bool state)
    
  • 参数

    参数 描述
    state truefalse
  • 返回值

    • 成功则返回 ok()

3.8.4. getUartSwitch

  • 功能

    获取 Uart0 串口开关状态。

  • 语法

    getUartSwitch(bool* _aid1_return)
    
  • 参数

    参数 描述
    _aid1_return truefalse
  • 返回值

    • 成功则返回 ok()

3.8.5. setPowerOnMode

  • 功能

    设置开机模式,可选直接开机/待机模式。

  • 语法

    setPowerOnMode(PowerOnMode mode)
    
  • 参数

    参数 描述
    mode 开机模式,STANDBYIMMEDIACY
  • 返回值

    • 成功则返回 ok()

3.8.6. getPowerOnMode

  • 功能

    获取开机模式。

  • 语法

    getPowerOnMode(PowerOnMode* _aid1_return)
    
  • 参数

    参数 描述
    _aid1_return 开机模式,STANDBYIMMEDIACY
  • 返回值

    • 成功则返回 ok()

3.8.7. setSuspendMode

  • 功能

    设置 STR 开关。

  • 语法

    setSuspendMode(SuspendMode mode)
    
  • 参数

    参数 描述
    mode STR 开关,ONOFF
  • 返回值

    • 成功则返回 ok()

3.8.8. getSuspendMode

  • 功能

    获取 STR 开关状态。

  • 语法

    getSuspendMode(SuspendMode* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return STR 开关,ONOFF
  • 返回值

    • 成功则返回 ok()

3.8.9. enableCecWakeUp

  • 功能

    使能 PM51 cec wakeup 功能。

  • 语法

    enableCecWakeUp(bool on)
    
  • 参数

    参数 描述
    on cec wakeup 开关,bool 类型
  • 返回值

    • 成功则返回 ok()

3.8.10. isCecWakeUpEnable

  • 功能

    判断 PM51 cec wakeup 功能是否使能。

  • 语法

    isCecWakeUpEnable(bool* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return cec wakeup 开关,ONOFF
  • 返回值

    • 成功则返回 ok()

3.8.11. getWakeupSource

  • 功能

    获取 PM51 唤醒源。

  • 语法

    getWakeupSource(WakeupSource* _aidl_return)
    
  • 参数

    参数 描述
    _aidl_return 唤醒源,分为 IR / CEC / GPIO / SAR
  • 返回值

    • 成功则返回 ok()

3.8.12. setDeviceInfoToFactory

  • 功能

    设置 factory_raw 分区特定位置的数据。

  • 语法

    setDeviceInfoToFactory(DeviceInfoIndex index, const std::vector<uint8_t>& data)
    
  • 参数

    参数 描述
    index factory_raw 分区索引,分为 SN / LAN0 / LAN1 / HDCP14 / HDCP22
    data 要写入的数据
  • 返回值

    • 成功则返回 ok()

3.8.13. getDeviceInfoFromFactory

  • 功能

    获取 factory_raw 分区特定位置的数据。

  • 语法

    getDeviceInfoFromFactory(DeviceInfoIndex index, std::vector<uint8_t>* data)
    
  • 参数

    参数 描述
    index factory_raw 分区索引,分为 SN / LAN0 / LAN1 / HDCP14 / HDCP22
    data 要获取的数据
  • 返回值

    • 成功则返回 ok()

4. SystemControl HAL 数据存储介绍

system_control_factory_configuration.xml 和 system_control_user_configuration.xml 文件用于存放系统画面、声音等配置数据。

文件路径:system_control_factory_configuration.xml 位于 device/sigmastar/pioneer5/factory 路径下,system_control_factory_configuration.xml 位于 vendor/sigmastar/hardware/systemcontrol 路径下

板端路径:其中 system_control_factory_configuration.xml 文件预置在 factory 分区,即 mnt/factory 路径,备份位于 /vendor/etc/system_control 位置。 system_control_factory_configuration.xml 待 SystemControl HAL 服务首次启动后从 /vendor/etc/system_control 复制到可读写的 /data/vendor/hardware/systemcontrol 位置。

system_control_user_configuration.xml 主要存放图像、色温、音频等相关数据,其中图像和色温数据需要区分主屏和副屏,文件结构如下:

<?xml version='1.0' encoding='utf-8'?>
<configuration>
    <!-- user configuration -->
    <user>
        <picture_mode_item>
            <display_id displayId="PRIMARY">
                <input_source source="HDMI">
                    <!-- the value corresponds to the following picture quality -->
                    <!-- "BRIGHTNESS","CONTRAST","SATURATION","SHARPNESS","HUET-->
                    <picture_mode mode="STANDARD">50,50,50,50,50</picture_mode>
                    <picture_mode mode="FILM">50,50,50,50,50</picture_mode>
                    <picture_mode mode="DYNAMIC">50,50,50,50,50</picture_mode>
                    <picture_mode mode="SOFT">50,50,50,50,50</picture_mode>
                    <picture_mode mode="GAME">50,50,50,50,50</picture_mode>
                    <picture_mode mode="CUSTOMIZED">50,50,50,50,50</picture_mode>
                </input_source>
                <input_source source="VGA">
                ...
                <input_source source="MEDIA">
                ...
            <display_id displayId="SECONDARY">
            ...
            </display_id>
        </picture_mode_item>

       <!-- the value of picture mode corresponds to the following input source -->
       <!-- "HDMI","VGA","MEDIA" -->
       <active_picture_mode>STANDARD,STANDARD,STANDARD</active_picture_mode>

        <color_temperature_item>
            <display_id displayId="PRIMARY">
                <input_source source="HDMI">
                    <!-- the value corresponds to the following white balance information -->
                    <!-- "R_GAIN","G_GAIN","B_GAIN","R_OFFSET","G_OFFSET","B_OFFSET" -->
                    <color_temperature_mode mode="WARM">128,128,128,0,0,0</color_temperature_mode>
                    <color_temperature_mode mode="COOL">128,128,128,0,0,0</color_temperature_mode>
                    <color_temperature_mode mode="NATURE">128,128,128,0,0,0</color_temperature_mode>
                    <color_temperature_mode mode="CUSTOMIZED">128,128,128,0,0,0</color_temperature_mode>
                </input_source>
                <input_source source="VGA">
                ...
                <input_source source="MEDIA">
                ...
            <display_id displayId="SECONDARY">
            ...
            </display_id>
        </color_temperature_item>

        <!-- the value of color temperature mode corresponds to the following input source -->
        <!-- "HDMI","VGA","MEDIA" -->
        <active_color_temperature_mode>NATURE,NATURE,NATURE</active_color_temperature_mode>

        <audio_output_device>SPEAKER</audio_output_device>
        <audio_balance>0</audio_balance>
        <spdif_mode>PCM</spdif_mode>
        <sound_mode>STANDARD</sound_mode>
        <audio_bass>0</audio_bass>
        <audio_treble>0</audio_treble>
        <audio_eq>
            <!-- the value corresponds to the audio equalizer frequency(Hz) and gain : -->
            <filter_index index="INDEX_0">120,0</filter_index>
            <filter_index index="INDEX_1">500,0</filter_index>
            <filter_index index="INDEX_2">1500,0</filter_index>
            <filter_index index="INDEX_3">5000,0</filter_index>
            <filter_index index="INDEX_4">10000,0</filter_index>
        </audio_eq>
        <audio_drc_enable>true</audio_drc_enable>
    </user>
</configuration>

system_control_factory_configuration.xml 主要存放非线性度、展频、音频等工厂菜单设置项数据,其中展频需要区分主屏和副屏,文件结构如下:

<?xml version='1.0' encoding='utf-8'?>
    <configuration>
        <!--factory configuration -->
        <factory>
            <nonlinearity_item>
                <!-- the value corresponds to the following nonlinearity point -->
                <!-- P0INT_0","P0INT_25","P0INT_58","P0INT_75","P0INT_100" -->
                <nonlinearity_type type="BACKLIGHT">0,25,50,75,100</nonlinearity_type>
                <nonlinearity_type type="BRIGHTNESS">0,25,50,75,100</nonlinearity_type>
                <nonlinearity_type type="CONTRAST">0,25,50,75,100</nonlinearity_type>
                <nonlinearity_type type="SATURATION">0,25,50,75,100</nonlinearity_type>
                <nonlinearity_type type="SHARPNESS">0,25,50,75,100</nonlinearity_type>
                <nonlinearity_type type="HUE">0,25,50,75,100</nonlinearity_type>
                <nonlinearity_type type="VOLUME_CURVE">0,25,50,75,100</nonlinearity_type>
            </nonlinearity_item>

            <video_mute_color>0</video_mute_color>
            <video_pattern>0</video_pattern>

            <spread_spectrum_item>
                <display_id displayId="PRIMARY">
                    <spread_spectrum_type type="PANEL">
                        <enable>false</enable>
                        <spread_parameter para="RADIO">0</spread_parameter>
                        <spread_parameter para="FREQ">0</spread_parameter>
                    </spread_spectrum_type>
                    <spread_spectrum_type type="DDRAM">
                    ...
                <display_id displayId="SECONDARY">
                ...
                </display_id>
            </spread_spectrum_item>

            <hdmi_drive_current>0</hdmi_drive_current>
            <lvds_drive_current>0</lvds_drive_current>
            <software_watch_dog_enable>false</software_watch_dog_enable>
            <hdmi_mute_threshold>0</hdmi_mute_threshold>
            <suspend_mode>OFF</suspend_mode>

            <apcs>
                ... ...
            </apcs>
            <aecs>
                ... ...
            </aecs>
            <anrs>
                ... ...
            </anrs>
            <eps>
                ... ...
            </eps>
            <hpfs>
                ... ...
            </hpfs>
            <agcs>
                ... ...
            </agcs>
            <drcs>
                ... ...
            </drcs>
        <factory>
    </configuration>

SystemControl.cpp 中运用 tinyxml2 库对 XML 文件进行解析,XML 文件本质是一种树形结构,通过遍历方式访问根节点下的子节点,实现检索、创建、修改功能。如果用户需要修改或增删 XML 文件内容,要注意数据格式对齐,相应的解析代码也需要修改。

5. SystemControl HAL 开机初始化流程介绍

SystemControl HAL 开机初始化流程图如下:

picture4.1.png

(1)SystemControl HAL 服务启动时,首先在其构造函数中将system_control_factory_configuration.xml 和 system_control_user_configuration.xml 文件中存储的数据读取出来,用于初始化成员变量。

(2)其次,获取 IComposerTransmission 服务。由于 HWC HAL 服务的启动时间比 SystemControl HAL 晚,需要重复调用 getservice() 4 次确保在 20s 内能获取到服务,否则获取失败。获取服务成功后,调用 IComposerTransmissiongetDrmFileDesriptor 接口获取 DRM 文件描述符 fd_ , 作为后续调用 DRM 驱动的传参。代码实现如下:

//SystemControl.cpp
status_t error;
int32_t retryCount = 1;

const String16 instance = BnComposerTransmission::descriptor + String16("/default");
do {
    error = getservice<IComposerTransmission>(instance, &composerTransmission_);
    retryCount++;
} while (retryCount < 4 || error != OK);
if (error != OK) {
    LOG(ERROR) << "get service IComposerTransmission failed";
    return;
}

auto status = composerTransmission_->getDrmFileDescriptor(&fd_);
...

(3)最后,初始化图像、色温和展频设置,使用的是上次关机前保存在 system_control_user_configuration.xml 和 system_control_factory_configuration.xml 文件中的数据。如果存在多个屏幕,则每个屏幕的图像设置都要初始化一次,代码实现如下:

//SystemControl.cpp
for (const auto& displayId : ndk::enum_range<DisplayId>()) {
    auto resId = getDrmResource(displayId);
    if (resId.first > 0 && resId.second > 0) {
        ndk::ScopedAStatus status;

        PictureModeItem pictureModeItem;
        pictureModeItem.displayId = displayId;
        pictureModeItem.source = activeInputSource_;
        pictureModeItem.mode = activePictureModeMap_[activeInputSource_];
        status = setPictureQuality(displayId, pictureModeItem.quality,
                                    pictureModeItemMap_[pictureModeItem]);
        if (!status.isOk()) {
            LOG(ERROR) << "picture quality initialization failed";
        }

        ColorTemperatureItem colorTemperatureItem;
        colorTemperatureItem.displayId = displayId;
        colorTemperatureItem.source = activeInputSource_;
        colorTemperatureItem.mode = activeColorTemperatureModeMap_[activeInputSource_];
        status setWhiteBalance(displayId, colorTemperatureItem.info,
                                       colorTemperatureItemMap_[colorTemperatureItem]);
        if (!status.isok()) {
            LOG(ERROR) << "color temperature initialization failed";
        }

        SpreadSpectrumItem spreadspectrumItem;
        spreadSpectrumItem.displayId = displayId;
        spreadSpectrumItem.type = activeSpreadSpectrumType_;
        status setSpreadspectrumItem(spreadSpectrumItem,
                                     spreadspectrumItemMap_[spreadSpectrumItem]);
        if (!status.isok()) {
            LOG(ERROR) << "spread spectrum initialization failed";
        }
}

(4)SStarFactoryMenu 和 SStarCustomizedMenu APK 启动之后,会调用 SystemControl Service 的接口从 SystemControl HAL 分别获取 factory xml 和 usre xml 内容,将参数显示到 UI 界面上

后续用户如果在 UI 界面上修改了 SStarFactoryMenu 和 SStarCustomizedMenu APK 的参数设置,都将通过 SystemControl Service ->SystemControl HAL ->libdrm (或 libperipherals),或 SystemControl Service -> Audio Service ->Audio HAL (或 SystemControl HAL) ->底层(或 xml) 将参数设置到底层

6. SystemControl HAL 图像设置实现逻辑介绍

6.1. 图像参数设置逻辑介绍

图像参数设置对应的接口是 setPictureQuality ,实现的是设置屏幕的亮度、对比度、饱和度、锐度或色调数值的功能,代码逻辑如下:

(1)首先将 value 从线性值映射成非线性值,先从保存非线性度的成员变量 nonlinearityItemMap_ 中读取 POINT_0POINT_25POINT_50POINT_75POINT_100 五个档的数值,如果数值不是从小到大排序,则不进行映射,如果符合要求则根据 value 所在区间进行计算。假设 value = 70,落在 POINT_50 = 80 、POINT_75 = 90 区间内,则计算出的 nonValue = 80 + (90 - 80) / (75 - 50) * (70 - 50) = 88。

(2)将非线性转换后的 value 保存在 system_control_user_configuration.xml 文件中 ,开机初始化时可以直接从 system_control_user_configuration.xml 文件中读取上次保留的值,不受到设备断电的影响。

(3)填充 drm_sstar_picture_quality 结构体中,调用 DRM 驱动的 drmIoctl 实现功能。相关宏定义和结构体的定义如下:

// sstar_drm.h
#define DRM_SSTAR_PICTURE_QUALITY 0X03

#define DRM_IOCTL_SSTAR_PICTURE_QUALITY \
    DRM_IOWR(DRM_COMMAND_BASE + DRM_SSTAR_PICTURE_QUALITY, struct drm_sstar_picture_quality)

///< Define sstar operation type
enum sstar_op {
    SSTAR_OP_GET = 0,
    SSTAR_OP_SET = 1,
};

///< Define CSC matrix type
typedef enum drm_sstar_csc_matrix_type
{
    SSTAR_CSC_MATRIX_BYPASS = 0, ///< Do not change color space

    SSTAR_CSC_MATRIX_BT601_TO_BT709, ///< Change color space from BT.601 to BT.709
    SSTAR_CSC_MATRIX_BT709_TO_BT601, ///< Change color space from BT.709 to BT.601

    SSTAR_CSC_MATRIX_BT601_TO_RGB_PC, ///< Change color space from BT.601 to RGB
    SSTAR_CSC_MATRIX_BT709_TO_RGB_PC, ///< Change color space from BT.709 to RGB

    SSTAR_CSC_MATRIX_RGB_TO_BT601_PC, ///< Change color space from RGB to BT.601
    SSTAR_CSC_MATRIX_RGB_TO_BT709_PC, ///< Change color space from RGB to BT.709
    SSTAR_CSC_MATRIX_USER, ///< Change color space fromPQbin

    SSTAR_CSC_MATRIX_MAX
} SSTAR_CSC_MATRIX_E;

///< Define color space transform information
typedef struct
{
    SSTAR_CSC_MATRIX_E cscMatrix;  ///< CSC matrix type
    uint32_t           luma;       ///< Adjustment of luminance, Range : 0 ~ 100
    uint32_t           contrast;   ///< Adjustment of contrast, Range : 0 ~ 100
    uint32_t           hue;        ///< Adjustment of Hue, Range : 0 ~ 100
    uint32_t           saturation; ///< Adjustment of saturation, Range : 0 ~ 100
} SSTAR_CSC_T;

struct drm_sstar_picture_quality
{
    uint32_t    crtcId;      ///< crtc id
    uint32_t    connectorId; ///< connector id
    SSTAR_OP_T  op;          ///< get or set parameter
    SSTAR_CSC_T csc;         ///< Adjustment of CSC
    uint32_t    sharpness;   ///< Adjustment of sharpness
    uint32_t    gain;        ///< Adjustment of driving current, only for VGA
};

setPictureQuality 接口代码实现如下:

// SystemControl.cpp
ndk::ScopedAStatus SystemControl::setPictureQuality(DisplayId displayId, PictureQuality quality,
int32_t value){
    std:vector<int32_t> nonPoint;

    // 非线性度转换
    for (auto nonItemMap : nonlinearityItemMap_){
        NonlinearityItem nonItem = nonItemMap.first;
        if (toString(nonItem.type) == toString(quality)){
            nonPoint.emplace_back(nonlinearityItemMap_[nonItem]);
        }
    }

    if (std::is_sorted(nonPoint.begin(),nonPoint.end())){
        int32_t step = 25;
        int32_t num = xmlGetEnumSize<Nonlinearity>();
        int32_t nonValue = 0;

        if (value == step * (num - 1))
            nonValue = nonPoint.at(num -1);
        } else {
            nonValue = (nonPoint.at((value / step) +  1) - nonPoint.at(value / step)) / (float)step
                       * (value - (value / step) * step) + nonPoint.at(value / step);
        value = nonValue;
    }

    ...
    // 数据保存到XML文件中
    XMLElement* elem = xmlFindChildElement(
            5,rootElem, "user",nullptr, nullptr,"picture_mode_item", nullptr,nullptr,
            "display_id","displayId", toString(pictureModeItem.displayId).c_str(), "input_source",
            "source", toString(pictureModeItem.source).c_str(), "picture_mode", "mode",
            toString(pictureModeItem.mode).c_str());

    if (elem) {
        xmlSetElement<PictureQuality>(elem, static_cast<int>(pictureModeItem.quality),
                                      std:to_string(value));
    }

    ...
    // DRM功能实现
    struct drm_sstar_picture_quality pictureQuality;
    pictureQuality.op = SSTAR_OP_SET;
    pictureQuality.csc.cscMatrix = SSTAR_CSC_MATRIX_BT709_TO_RGB_PC;
    auto resId = getDrmResource(displayId);
    if (resId.first < 0 || resId.second < 0) {
        LOG(ERROR) << "can not get connector id or crtc id";
        return ndk::ScopedAStatus(AStatus_fromStatus(STATUS_FAILED_TRANSACTION));
    }
    pictureQuality.connectorId = static_cast<uint32_t>(resId.first);
    pictureQuality.crtcId = static_cast<uint32_t>(resId.second);
    pictureQuality.csc.luma =
            static_cast<uint32_t>(PQValues.at(static_cast<int>(PictureQuality:BRIGHTNESS)));
    pictureQuality.csc.contrast =
            static_cast<uint32_t>(PQValues.at(static_cast<int>(PictureQuality:CONTRAST)));
    pictureQuality.csc.saturation =
            static_cast<uint32_t>(PQValues.at(static_cast<int>(PictureQuality:SATURATION)));
    pictureQuality.sharpness =
            static_cast<uint32_t>(PQValues.at(static_cast<int>(PictureQuality:SHARPNESS)));
    pictureQuality.csc.hue =
            static_cast<uint32_t>(PQValues.at(static_cast<int>(PictureQuality:HUE)));
    pictureQuality.gain = 0;

    int32_t ret = drmIoctl(fd_, DRM_IOCTL_SSTAR_PICTURE_QUALITY, &pictureQuality);
    if(ret < 0) {
        LOG(ERROR) << "set " << pictureModeItem.toString() << " value :"<< value
                   << " failed, error = " << ret;
        return ndk::ScopedAStatus(AStatus_fromStatus(STATUS_INVALID_OPERATION));
    }
    ...
}

需要注意的点如下:

  • SSTAR_OP_T 决定 drm_sstar_picture_quality 的方向性,SSTAR_OP_GET 是设置结构体参数,SSTAR_OP_GET 是获取结构体参数,但要指定 connector idcrtc id

  • 传入 displayId 绑定的 connector idcrtc id 是从 HWC HAL 获取的,如果获取失败返回 STATUS_FAILED_TRANSACTION

  • drm_sstar_picture_quality 结构体所包含的参数需要一同设置,DRM 驱动不支持缺省设置。如果 drmIoctl 调用失败,会返回 STATUS_INVALID_OPERATION 及打印drmIoctl 的返回值。

客户端可以通过 getPictureQuality 接口获取当前屏幕的画面参数对应的数据,返回的是保存在 pictureModeItemMap_ 成员变量中的值。

// SystemControl.cpp
ndk::ScopedAStatus SystemControl::getPictureQuality(DisplayId displayId, PictureQuality quality,
                                                     int32_t* _aidl_return) {
    PictureModeItem item;
    item.displayId = displayId;
    item.source = activeInputSource_;
    item.mode = activePictureModeMap_[activeInputSource_];
    item.quality = quality;
    *_aidl_return = pictureModeItemMap_[item];

    LOG(INFO) << "get " << item.toString() << " value : " << *_aidl_return;

    return ndk::ScopedAStatus::ok();
}

6.2. 图像模式设置逻辑介绍

图像模式设置对应的接口是 setPictureMode ,实现切换标准、电影、动态、柔和、游戏和自定义模式的功能,随即生效的是上一次该模式下各个图像参数所保存的值。其实现逻辑与 setPictureQuality 类似,都是先将 mode 参数存入system_control_user_configuration.xml 文件中,再将 displayIdmode 参数对应的 图像参数读取出来,通过 DRM 驱动设置到底层寄存器中。如果 drmIoctl 调用失败,会返回 STATUS_INVALID_OPERATION 及打印 drmIoctl 的返回值。代码实现如下:

// SystemControl.cpp
ndk::ScopedAStatus Systemcontrol::setPictureMode(DisplayId displayId, PictureMode mode){

    ...
    // 数据保存到XML文件中
    XMLElement* rootElem = xmlDoc.RootElement();
    XMLElement* elem = xmlFindchildElement(2, rootElem, "user", nullptr, nullptr,
                                          "active_picture_mode", nullptr, nullptr);
    if (elem){
        xmlSetElement<PictureQuality>(elem, static_cast<int>(activeInputSource_),tostring(mode));
    }

    ...
    // DRM功能实现
    int32 t ret = drmIoctl(fd_, DRM_IOCTL_SSTAR_PICTURE_QUALITY, &pictureQuality);
    if (ret < 0){
        ...
        return ndk::ScopedAStatus(AStatus_fromStatus(STATUS_INVALID_OPERATION));
    }
    ...
}

客户端可以通过 getPictureMode 接口获取当前屏幕指定的图像参数对应的数据,返回的是保存在 activePictureModeMap_ 成员变量中的值。

// SystemControl.cpp
ndk::ScopedAStatus SystemControl::getPictureMode(DisplayId displayId, PictureMode* _aidl_return) {
    *_aidl_return = activePictureModeMap_[activeInputSource_];

    LOG(INFO) << "get display picture mode ( source : " << toString(source)
              << " mode : " << toString(*_aidl_return) << " )";

    return ndk::ScopedAStatus::ok();
}

7. SystemControl HAL 色温设置实现逻辑介绍

7.1. 色温参数设置逻辑介绍

setCWhiteBalance 接口的功能是实现屏幕的色温调节,可以设置 RGB 及其 offset 值,代码逻辑如下:

(1)将设置的 value 保存在 system_control_user_configuration.xml 文件中 ,开机初始化时可以直接从 system_control_user_configuration.xml 文件中读取上次保留的值,不受到设备断电的影响。

(2)填充到 drm_sstar_white_balance 结构体中,调用 DRM 驱动的 drmIoctl 实现功能,相关宏定义和结构体定义如下:

// sstar_drm.h
#define DRM_SSTAR_SET_WHITE_BALANCE 0x02

#define DRM_IOCTL_SSTAR_SET_WHITE_BALANCE \
    DRM_IOWR(DRM_COMMAND_BASE + DRM_SSTAR_SET_WHITE_BALANCE, struct drm_sstar_set_white_balance)

struct drm_sstar_set_white_balance {
    uint32_t crtcId;       ///< crtc id
    uint16_t redOffset;    ///< Offset of color R
    uint16_t greenOffset;  ///< offset of color G
    uint16_t blueOffset;   ///< Offset of color B
    uint16_t redColor;     ///< Gain of Color R
    uint16_t greenColor;   ///< Gain of Color G
    uint16_t blueColor;    ///< Gain of Color B
}

setCWhiteBalance 接口代码实现如下:

// SystemControl.cpp
ndk:ScopedAStatus Systemcontrol::setWhiteBalance(DisplayId displayId, WhiteBalanceInfo info,
                                                int32_t value){
    ...
    //数据保存到XML中
    XMLElement* elem = xmlFindChildElement(
            5, rootElem, "user", nullptr, nullptr, "color_temperature_item", nullptr, nullptr,
            "display_id", "displayId", toString(colorTemperatureItem.displayId).c_str(), "input_source", "source",
            toString(colorTemperatureItem.source).c_str(), "color_temperature_mode", "mode",
            tostring(colorTemperatureItem.mode).c_str());
    if (elem) {
         xmlSetElement<ColorTemperatureMode>(elem, static_cast<int>(colorTemperatureItem.info),
                                             std::to_string(value));
    }

    ...
    //DRM功能实现
    struct drm_sstar_set_white_balance whiteBalance;
    auto resId = getDrmResource(displayId);
    if (resId.second < 0){
        LOG(ERROR) << "can not get crtc id";
        return ndk::ScopedAStatus(AStatus_fromStatus(STATUS_FAILED_TRANSACTION));
    }
    whiteBalance.crtcId = static_cast<uint32_t>(resId.second);
    whiteBalance.redColor =
            static_cast<uint16_t>(WBValues.at(static_cast<int>(WhiteBalanceInfo::R_GAIN)));
    whiteBalance.greenColor =
            static_cast<uint16_t>(WBValues.at(static_cast<int>(WhiteBalanceInfo::G_GAIN)));
    whiteBalance.blueColor =
            static_cast<uint16_t>(WBValues.at(static_cast<int>(WhiteBalanceInfo::B_GAIN)));
    whiteBalance.redoffset =
            static_cast<uint16_t>(WBValues.at(static_cast<int>(WhiteBalanceInfo::R_OFFSET)));
    whiteBalance.greenoffset =
            static_cast<uint16_t>(WBValues.at(static_cast<int>(WhiteBalanceInfo::G_OFFSET)));
    whiteBalance.blueoffset =
            static_cast<uint16_t>(WBValues.at(static_cast<int>(WhiteBalanceInfo::B_OFFSET)));

    int32_t ret = drmIoctl(fd_, DRM_IOCTL_SSTAR_SET_WHITE_BALANCE, &whiteBalance);
    if (ret < 0){
        LOG(ERROR) << "set " << colorTemperatureItem.toString() << " value : " << value
                   << " failed, error = " << ret;
        return ndk::ScopedAStatus(AStatus_fromStatus(STATUS_INVALID_OPERATION));
    }
    ...
}

需要注意的点如下:

  • 传入 displayId 绑定的 和 crtc id 是从 HWC HAL 获取的,如果获取失败返回 STATUS_FAILED_TRANSACTION

  • drm_sstar_white_balance 结构体所包含的参数需要一同设置,DRM 驱动不支持缺省设置。如果 drmIoctl 调用失败,会返回STATUS_INVALID_OPERATION 及打印drmIoctl 的返回值。

客户端可以通过 getWhiteBalance 接口获取当前屏幕的色温参数对应的数据,返回的是上次保存在 colorTemperatureItemMap_ 成员变量中的值。

// SystemControl.cpp
ndk::ScopedAstatus systemcontrol::getWhiteBalanceInfo(DisplayId displayId, WhiteBalanceInfo info,
                                                   int32_t* _aidl_return) {
    ColorTemperatureItem item;
    item.displayId = displayId;
    item.source = activeInputsource_;
    item.mode = activeColorTemperatureModeMap_[activeInputsource_];
    item.info = info;
    *_aidl_return = colorTemperatureItemMap_[item];

    LOG(INFO) << "get " << item.toString() << "value " << *_aidl_return;

    return ndk::ScopedAStatus::ok();
}

7.2. 色温模式设置逻辑介绍

setColorTemperatureMode 接口的功能是实现屏幕色温模式的切换,有暖色、冷色和自然色三种模式,切换色温模式时画面效果也会随之变化。其实现逻辑与setColorTemperature 类似,都是先将 mode 参数存入system_control_user_configuration.xml 文件中,再将 displayIdmode 参数对应的 色温参数读取出来,通过 DRM 驱动设置到底层寄存器中。如果 drmIoctl 调用失败,会返回STATUS_INVALID_OPERATION 及打印 drmIoctl 的返回值。代码实现如下:

// SystemControl.cpp
ndk::scopedAstatus systemcontrol::setColorTemperatureMode(DisplayId displayId, colorTemperatureMode mode) {
    ....
    //保存到XML文件中
    XMLElement* elem = xmlFindchildElement(2, rootElem, "user", nullptr, nullptr,
                                          "active_color_temperature_mode", nullptr, nullptr);
    ...
    //DRM功能实现
    int32_t ret = drmIoctl(fd, DRM IOCTL_SSTAR SET_WHITE BALANCE, &whiteBalance);
    if (ret < 0){
        ...
        return ndk::ScopedAStatus (AStatus_fromstatus(STATUS_INVALID_OPERATION));
    }
    ...
}

客户端可以通过 getColorTemperatureMode 接口获取当前屏幕的色温模式对应的数据,返回的是上次保存在 activeColorTemperatureModeMap_ 成员变量中的值。

// SystemControl.cpp
ndk::ScopedAstatus Systemcontrol::getColorlemperaturemode(DisplayId displayId, ColorTemperatureMode* _aidl_return) {
    *_aidl_return = activeColorTemperatureModeMap_[activeInputsource_];

    LOG(INFO) << "get display color temperature mode source :" << tostring(activeInputsource_)
              << "mode " << toString(*_aidl_return) << ")";

    return ndk::ScopedAStatus::ok();
}

8. SystemControl HAL 音频设置实现逻辑介绍

SystemControlService.java 中,initAudioConfiguration 方法是用于初始化音频设置,首先通过 SystemControl AIDL 提供的方法来获取保存在 system_control_user_configuration.xml 文件中的参数值,包括 soundModeaudioBalancespdifModeoutputDevice

获取到的参数值通过 AudioManagersetParameters 方法以键值对方式, 例如 sound_mode=0audio_balance=0spdif_mode=0 来设置各自的属性值。

private void initAudioConfiguration() {
    try {
        int soundModeId = mServicestub.getSoundMode();
        int audioBalance = mServiceStub.getAudioBalance();
        int spdifModeId = mServicestub.getspdifMode();
        int outputDevice = mServiceStub.getAudioOutputDevice();

        mAudioManager.setParameters("sound_mode=" + soundModeId);
        mAudioManager.setParameters("audio_balance=" + audioBalance);
        mAudioManager.setParameters("spdif_mode=" + spdifModeId);

        // 获取 audio effect 数据并进行相应使能或设置,包括 APC、AEC、ANR、EQ、HPF、AGC、DRC
        initAudioEffectParams();

        // 应用 UI 音频输出设备策略
        applyAudioOutputPolicy(outputDevice);
        ... ...
}

在 audio_hw.c 中,str_parms_create_str 方法以 [key, value] 键值对的形式解析入参 kvpairs 。通过str_parms_get_int 方法获取 sound_modeaudio_balancespdif_mode 属性值,依次设置到 audio_hw_device_t 的相关变量中。

#define AUDIO_PARAMETER_SOUND_MODE "sound_mode"
#define AUDIO_PARAMETER_BALANCE "audio_balance"
#define AUDIO_PARAMETER_SPDIF_MODE "spdif_mode"

static int audio_device_set_parameters(audio_hw_device_t* dev, const char* kvpairs) {
    ALOGI("device.set_parameters(%s)", kvpairs);

    audio_device_private_t* priv_dev = (audio_device_private_t*)dev;
    struct str_parms* parms = NULL;
    int int_value = 0;
    int ret = -EINVAL;
    if (kvpairs == NULL || kvpairs[0] == 0){
        return 0;
    }

    parms str_parms_create_str(kvpairs);
    if (NULL == parms) {
        ALOGE("parms is null in device.set_parameters()");
        return -ENOMEM;
    }

    // for set audio balance
    ret = str_parms_get_int(parms, AUDIO_PARAMETER_BALANCE, &int_value);
    if (ret >= 0) {
        priv_dev->balance = int_value;
        set_device_port_volume(priv_dev, PORT_TYPE_SPEAKER, priv_dev->master_volume);;
    }

    ...
    // for set spdif mode
    ret = str_parms_get_int(parms, AUDIO_PARAMETER_SPDIF_MODE, &int_value);
    if (ret >= 0) {
        priv_dev->spdif_mode = int_value;
    }

    // for set sound mode
    ret = str_parms_get_int(parms, AUDIO_PARAMETER_SOUND_MODE, &int_value);
    if (ret >= 0) {
        enum SoundMode soundmode = (enum SoundMode)(int_value + 1);
        audio_extn_effect_set_sound_mode((enum SoundMode)soundmode);
    }
    ...
}

另外,SystemControlService.java 中调用 applyAudioOutputPolicy(outputDevice) 设置音频输出设备, 来应用 UI 音频输出设备策略。

//
private void applyAudioOutputPolicy(int dev) {
    int audioDevice = getoutputDeviceForUIDevice(dev);
    switch (audioDevice) {
        case AudioSystem.DEVICE_OUT_SPDIF:
            AudioSystem.setForceUse(AudioSystem.FOR_DOCK, AudioSystem.FORCE_DIGITAL_DOCK);
            break;
        case AudioSystem.DEVICE_OUT_SPEAKER:
        default:
            AudioSystem.setForceUse(AudioSystem.FOR_DOCK, AudioSystem.FORCE_NONE);
            break;
    }
}

因为 AOSP 音频输出设备策略中默认是支持 SPDIF 和 SPEAKER 可以同时输出。 UI 菜单中如果选择 DEVICE_OUT_SPDIF 类型的输出设备,则调用 setForceUseAudioSystem.FOR_DOCK 分配 AudioSystem.FORCE_DIGITAL_DOCK config 的策略,

setForceUse相关的 usagesdevice categories 定义在 AudioSystemLegacy.h 中:

// device categories used for setForceUse()
enum forced_config {
    FORCE NONE,
    FORCE SPEAKER,
    FORCE HEADPHONES,
    FORCE_BT_SCO,
    FORCE_BT_A2DP,
    FORCE_WIRED_ACCESSORY,
    FORCE_BTCAR_DOCK,
    FORCE_BT_DESK_DOCK,
    FORCE_ANALOG_DOCK,
    FORCE_DIGITAL_DOCK,
    FORCE_NO_BT_A2DP,
    FORCE_SYSTEM_ENFORCED,
    NUM FORCE_CONFIG,
    FORCE_DEFAULT FORCE_NONE
};

// usages used for setForceUse()
enum force_use {
    FOR COMMUNICATION,
    FOR_MEDIA,
    FOR_RECORD,
    FOR_DOCK,
    FOR_SYSTEM,
    NUM FORCEUSE
};

setForceUse 设置需要配合客制化 audioPolicyEngine 一起使用,关联到 Engine.cpp 中,通过音频策略获取到对应的输出设备。

DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
                                              DeviceVector availableOutputDevices,
                                              const SwAudioOutputCollection &outputs) const
{
   ...
#ifdef SSTAR_CUSTOMIZED
        // SPDIF can not co-exist with others for custom UI output device.
        if ((devices2.isEmpty()) &&
                (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_DIGITAL_DOCK)) {
            if (strategy == STRATEGY_MEDIA) {
                devices2 = availableOutputDevices.getDevicesFromTypes({AUDIO_DEVICE_OUT_SPDIF});
            }
        }
#endif /* SSTAR_CUSTOMIZED */
   ...
}

9. SystemControl HAL 工厂模式参数设置实现逻辑介绍

工厂模式由 SStarFactoryMenu APK 设计实现,通过 SystemControlService 服务调用 SystemControl AIDL 接口实现各个工厂选项功能。所有的选项参数保存在system_control_factory_configuration.xml 文件中,以下将对各个选项设置实现展开描述。

9.1. Picture Quality

该选项的功能是调节图像模式 (标准、电影、动态、柔和、游戏) 各个模式下 (亮度、对比度、饱和度、锐度或色调) 的参数值。用户菜单只能对 customized 模式进行参数调节,标准、电影、动态、柔和、游戏 模式都是在工厂菜单具体设置,用户菜单只能进行图像模式切换。相关接口为 setPictureQualitysetPictureMode 等, 详见SystemControl HAL 图像设置实现逻辑介绍

9.2. NonLinearity

9.2.1. PQ NonLinearity

该选项的功能是设置 Picture Quality 相关参数的非线性度,包括亮度、对比度、饱和度、清晰度和色调非线性类型,每个类型曲线都对应五个档位 POINT_0 / POINT_25 / POINT_50 / POINT_75 / POINT_100 ,默认值档位值为 0 / 25 / 50 / 75 / 100,即将非线性区间划分为 [ 0, 25 ]、[ 25, 50 ]、[ 50, 75 ]、[ 75, 100 ] 四个区间。如果用户不对此参数进行调节,便不进行非线性映射。如果调节了参数,需要注意的是 ,档位值需要从小到大递增,才能确保非线性调节符合增长趋势。

对应 SystemControl AIDL 的非线性值调节接口为 setNonlinearityItem , 也可通过 getNonlinearityItem 获取特定曲线的档位值,对应的代码逻辑如下所示。但是非线性度计算都是在设置 Picture Quality 参数的各自接口实现的,比如设置亮度的非线性度后,在调用 setPictureModeltem 接口后非线性映射才会生效,详见SystemControl HAL 图像设置实现逻辑介绍

ndk::ScopedAStatus SystemControl::setNonlinearityItem(const NonlinearityItem& item, int32_t value) {
    nonlinearityItemMap_[item] = value;
    ...
    XMLElement*rootElem = xmlDoc.RootElement();
    XMLElement*elem xmlFindChildElement(
            3, rootElem, "factory", nullptr, nullptr, "nonlinearity_item", nullptr, nullptr,
            "nonlinearity_type", "type", toString(item.type).c_str());
    if (elem) {
        xmlSetElement<Nonlinearity>(elem, static_cast<int>(item.point), std:to_string(value));
    }
    ...
}

ndk::ScopedAStatus SystemControl::getNonlinearityItem(const NonlinearityItem& item,
               int32_t*_aidl_return){
    *_aidl_return = nonlinearityItemMap_[item];
    ...
}

9.2.2. AQ NonLinearity

该选项的功能是设置 Audio Quality 的非线性度,调节的是音量的非线性曲线。该选项的默认区间值、设置接口与 Picture Quality 选项一致,不在此赘述。但是音量曲线的非线性度计算由 Audio HAL 实现,在 audio_hw.c 中的代码逻辑如下:

// audio_hw.c
static int calculate_volume(audio_device_private_t* priv_dev, volume_port_t volume_port,
                            uint32_t volume_index, uint32_t* volume_gain) {
    ...
    // 判断是 SPEAKER 还是 HEADPHONE 类型曲线
    switch (volume_port) {
        case VOLUME_PORT_SPEAKER:
            volume_curve_point = priv_dev->volume_curve_info.speaker;
            break;
        case VOLUME_PORT_HEADPHONE:
            volume_curve_point = priv_dev->volume_curve_info.headphone;
            break;
        case VOLUME_PORT_SPDIF:
        default:
            ALOGE("not support port type(%d)\n", volume_port);
            return -EINVAL;
    }
    ...
    // 非线性计算
    if (volume_index < volume_curve_point[MAX_VOLUME_CURVE_POINT - 1].index &&
        volume_index >= volume_curve_point[0].index) {
        for (int i = 0; i < MAX_VOLUME_CURVE_POINT - 1; i++) {
            if (volume_index >= volume_curve_point[i].index &&
                volume_index < volume_curve_point[i + 1].index) {
                *volume_gain =
                        ((volume_index - volume_curve_point[i].index) *
                         (volume_curve_point[i + 1].value - volume_curve_point[i].value)) /
                                (volume_curve_point[i + 1].index - volume_curve_point[i].index) +
                        volume_curve_point[i].value;
            }
        }
    }
    ...
}

calculate_volume 接口是将 INDEX_0 / INDEX_1 / INDEX_2 / INDEX_3 / INDEX_4 五个档位的用户设定值均转换成 0 - 1023 区间数值。

9.3. White Balance

该选项的功能是调节画面的白平衡,暖色、冷色、自然色模式下各对应一组 R GAIN / G GAIN / B GAIN / R offset / G offset / B offset 参数,色彩值为用户自定义,范围均为 0 - 255。用户菜单只能对 customized 模式进行参数调节,暖色、冷色、自然色模式都是在 工厂菜单具体设置,用户菜单只能进行图像模式切换。相关的接口为 setColorTemperatureItemsetColorTemperatureMode 等,详见SystemControl HAL 图像设置实现逻辑介绍

9.4. Spread Spectrum

该选项是控制 PANEL 和 DDRAM 的展频开闭,以及展频步长、范围设定,但目前功能只针对 PANEL 。开闭展频的接口是 enableSpreadSpectrum , 如果选择开启状态,那么上次设定的 stepspan 也会一同生效。代码逻辑是先将 on 状态保存到 XML 文件中,再调用 drmIoctl 实现功能,代码实现如下:

ndk::ScopedAStatus SystemControl::enableSpreadSpectrum(DisplayId displayId, SpreadSpectrumType type,
                                                bool on) {
    ...
    //数据保存到XML文件中
    XMLElement* elem = xmlFindChildElement(5, rootElem, "factory", nullptr, nullptr,
                                          "spread_spectrum_item", nullptr, nullptr, "display_id",
                                          "displayId", "PRIMARY", "spread_spectrum_type", "type",
                                          toString(type).c_str(), "enable", nullptr, nullptr);
    if (elem) {
        elem->SetText(on);
    }
    ...

    // DRM功能实现
    if (type == SpreadSpectrumType::PANEL) {
        struct drm_sstar_set_spread_spectrum_spreadspectrum;
        ....
        spreadSpectrum.connectorId = static_cast<uint32_t>(resId.first);
        spreadSpectrum.crtcId = static_cast<uint32_t>(resId.second);
        spreadSpectrum.enable = on;
        spreadSpectrum.step = static_cast<uint32_t>(
                spreadSpectrumValues.at(static_cast<int>(SpreadSpectrumParameter::RADIO)));
        spreadSpectrum.span = static_cast<uint32_t>(
                spreadSpectrumValues.at(static_cast<int>(SpreadSpectrumParameter::FREQ)));
        int32_t ret = drmIoctl(fd_, DRM_IOCTL_SSTAR_SET_SPREAD_SPECTRUM, &spreadSpectrum);
        ...
    }
}

设置 stepspan 的接口为 setSpreadSpectrumItem ,逻辑与上述接口基本一致,代码实现如下:

ndk::ScopedAStatus Systemcontrol::setSpreadSpectrumItem(const SpreadSpectrumItem& item,
                                                 int32_t value) {
    ...
    //数据保存到XML文件中
    XMLElement* elem = xmlFindChildElement(
            5, rootElem, "factory", nullptr, nullptr, "spread_spectrum_item", nullptr, nullptr,
            "display_id", "displayId", toString(item.displayId).c_str(), "spread_spectrum_type",
            "type", toString(item.type).c_str(), "spread_parameter", "para",
            toString(item.para).c_str());
    if (elem){
        elem->SetText(value);
    }
    ...

    // DRM功能实现
    if (type == SpreadSpectrumType::PANEL) {
        ...
        int32_t ret = drmIoctl(fd_, DRM_IOCTL_SSTAR_SET_SPREAD_SPECTRUM, &spreadSpectrum);
        ...
    }
}

9.5. Parametric EQualizer

该选项的功能是调节音频参数均衡器,声音模式分为 STANDARD / MOVIE / NEWS / SPORTS / MUSIC ,每个模式下都可以调节 enable 状态和 frequency 。相同地,在工厂菜单中设置每个模式的详细参数,在用户菜单中切换模式。

9.6. Other Options

9.6.1. Power On Mode

此选项设置的是系统的开机模式,分为 STANDBYIMMEDIACY 两种模式,代表直接开机或进入待机模式,设置后会在下一次开机时生效。主要逻辑是设置环境变量,"bootcmd=boota" 代表直接开机,"bootcmd=pm;boota" 代表待机模式,代码逻辑如下:

ndk::ScopedAStatus SystemControl::setPowerOnMode(PowerOnMode mode) {
    std::string envVar = "bootcmd";
    std::string pmStr = "pm;";
    ... ...

    // 获取 bootcmd 环境变量的内容
    auto ret = sstar_get_env(envVar.c_str(), buffer);
    envStr = buffer;
    if (ret < 0 || envStr.size() == 0) {
        LOG(ERROR) << "can not get bootcmd string";
        return ndk::ScopedAStatus(AStatus_fromStatus(STATUS_BAD_VALUE));
    }

    // 判断环境变量内容,如果与 mode 状态一致,直接返回 ok
    // 如果不一致,根据 mode 选择增加 "pm" 或去掉 "pm" 字符
    if ((envStr.find(pmStr) != std::string::npos && mode == PowerOnMode::STANDBY) ||
        (envStr.find(pmStr) == std::string::npos && mode == PowerOnMode::IMMEDIACY)) {
        /* if power on mode has no change */
        LOG(INFO) << "set power on mode : " << toString(mode) << " success";
        return ndk::ScopedAStatus::ok();
    } else {
        /* if power on mode switch to standby, add pm, otherwise remove pm */
        mode == PowerOnMode::STANDBY ? envStr.insert(envStr.find("=") + 1, pmStr)
                                     : envStr.erase(envStr.find(pmStr), pmStr.size());
    }

    // 写入到 env 文件中
    envStr.erase(envStr.find("bootcmd="), sizeof("bootcmd=") - 1);
    ret = sstar_set_env(envVar.c_str(), envStr.c_str());
    ... ...

也可通过 getPowerOnMode 接口获取当前的开机状态。

9.6.2. Uart Enable

此选项是选择是否输出系统日志,可选 onoff 。代码逻辑与 Power On Mode 基本一致,即如果选择开启日志,则在环境变量 "bootargs" 后加上 "uart=on" 字符,关闭则改为 "uart=off" 字符。

9.6.3. Enable STR

此选项为 STR 开关,可选 onoff 。STR是一种可以快速恢复系统运行状态的待机模式,系统在待机前将程序的运行上下文保存在内存中,待机时主芯片下电,内存进入自刷新模式(Self-Refresh)状态以降低功耗,唤醒后再将程序运行上下文恢复,以此实现迅速恢复到待机前运行状态的功能。STR 为 on 时,短按 power 键系统进入 suspend mode;STR 为 off 时,短按 power 键系统进入熄屏。

进入 STR 待机状态命令:

echo mem > /sys/power/state

退出 STR 待机状态命令:

echo off > /sys/power/state

查看 STR 状态命令:

cat sys/power/state

9.6.4. Test Pattern

此选项提供了一些测试图案,包括纯色图案、彩条图案、灰阶图案、渐变图案等,主要用于测试显示效果和图像质量。

9.6.5. HDMIRX Auto EQ

此选项用于为 HDMIRX Auto EQ debug 开关,可选 onoff 。当打开此开关时,在命令行输入以下命令:

echo 0x101180a > /sys/devices/virtual/mstar/hdmirx/hdmirxdbg

可查看 DRV_HDMIRX_IF_ProcessEQ 相关 debug 信息。

10. SystemControl HAL PQ 相关接口调试方法介绍

color space,DLC curve, gamma curve, HSY curve,luma Info 等 PQ 相关接口使用时,可以通过一些 debug 方法查看是否设置正确,或者直接通过写入驱动节点方式达到预期效果,各个接口的 debug 方法介绍如下。

10.1. color space 调试方法

color space 设置接口为 setColorSpaceTransform,可选色域有 USER / BT601_L_TO_RGB_F / BT709_L_TO_RGB_F / BT2020_L_TO_RGB_F / BT601_F_TO_RGB_F / BT709_F_TO_RGB_F / BT2020_F_TO_RGB_F / BT601_L_T0_RGB_L / BT709_L_T0_RGB_L / BT2020_L_T0_RGB_L 。以上十组色域对应的 Matrix 值为:

enum value
USER 0x0730, 0x04AC, 0x0000, 0x1223, 0x04AC, 0x10DA, 0x0000, 0x04AC, 0x0878
BT601_L_TO_RGB_F 0x0667, 0x04AC, 0x0000, 0x1343, 0x04AC, 0x1192, 0x0000, 0x04AC, 0x0818
BT709_L_TO_RGB_F 0x0730, 0x04AC, 0x0000, 0x1223, 0x04AC, 0x10DA, 0x0000, 0x04AC, 0x0878
BT2020_L_TO_RGB_F 0x06BC, 0x04AC, 0x0000, 0x129C, 0x04AC, 0x10C0, 0x0000, 0x04AC, 0x0898
BT601_F_TO_RGB_F 0x059C, 0x0400, 0x0000, 0x12DB, 0x0400, 0x1160, 0x0000, 0x0400, 0x0717
BT709_F_TO_RGB_F 0x064D, 0x0400, 0x0000, 0x11DF, 0x0400, 0x10C0, 0x0000, 0x0400, 0x076C
BT2020_F_TO_RGB_F 0x05E6, 0x0400, 0x0000, 0x1249, 0x0400, 0x10A9, 0x0000, 0x0400, 0x0787
BT601_L_T0_RGB_L 0x057C, 0x0400, 0x0000, 0x12CB, 0x0400, 0x1159, 0x0000, 0x0400, 0x06EE
BT709_L_T0_RGB_L 0x0629, 0x0400, 0x0000, 0x11D5, 0x0400, 0x10BB, 0x0000, 0x0400, 0x0742
BT2020_L_T0_RGB_L 0x05C4, 0x0400, 0x0000, 0x123C, 0x0400, 0x10A5, 0x0000, 0x0400, 0x075C

查看 bank 0x1161、offset 0x3d~0x45 寄存器,可判断当前选择的是哪个色域:

riu_r 0x1161

picture10.1.png

10.2. DLC curve 调试方法

设置 setDlcCurve 之前需调用 enableDlc 接口使能 DLC。查看 DLC 是否使能:

cat /sys/class/mstar/mdisp/pq

picture10.2.1.png

写入 0 为 disable DLC,写入 1 为 enable DLC,命令如下:

echo 0 / 1 > /proc/sstar_drm/dlcActive

查看当前选择的哪条 DLC 曲线 或 DLC 曲线数据,需要在播放视频时打开 dbgmg:

echo 10000 > /sys/class/mstar/mdisp/dbgmg
cat /proc/kmsg | grep gMode

picture10.2.2.png

gMode0Param.g_curveSel 为 DLC id,0 / 1 / 2 / 分别为低/中/高曲线。

10.3. gamma curve、HSY curve、 luma info 调试方法

gamma curve、HSY curve、 luma info 的设置内容都可以通过以下命令查看:

cat /sys/class/mstar/mdisp/pq

picture10.3.png

/sys/class/mstar/mdisp/pq 节点会显示当前屏幕画面最大亮度、最小亮度、平均亮度,以及显示当前使用的 gamma curve id、HSY curve id