美文网首页
LED灯系统架构(基于google源码分析)

LED灯系统架构(基于google源码分析)

作者: 赛非斯 | 来源:发表于2021-10-27 16:19 被阅读0次
    • 假如系统有好几个灯,需要根据id来选择要亮的灯,我们需要修改hal层代码添加一个接口
    hardware/interfaces/light/2.0/default/Light.cpp
    light_state_t legacyState {
            .ledId = state.ledId,
    
    hardware/interfaces/+/474/1/light/2.0/types.hal
    truct LightState {
         uint32_t ledId;
    
    hardware/libhardware/include/hardware/lights.h
    struct light_state_t {
        unsigned int ledId;
    

    这个时候去编译,会编译报错,因为要更新api,根据报错信息修改
    添加接口后会报错
    c++_headers/gen -L c++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.light@2.0
    ERROR: android.hardware.light@2.0::types has hash 6449fbfe75742a10327e8abf89d7f0855ef4c726246f3926078ec8371bb667ec which does not match hash on record. This interface has been frozen. Do not change it!
    ERROR: Could not parse android.hardware.light@2.0::types. Abor
    将刚刚得到的新 hashcode 值更新到 hardware/interfaces/current.txt 重新编译即可

    单独编译模块或者全编译 会出现一个VNDk异常的报错

     make android.hardware.light@2.0 -j24 
    make android.hardware.light@2.0-impl -j24
    
    [ 92% 36/39] //hardware/interfaces/light/2.0:android.hardware.light@2.0 header-abi-diff android.hardware.light@2.0.so.abidiff
    FAILED: out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_kryo300_vendor_shared/android.hardware.light@2.0.so.abidiff
    (prebuilts/clang-tools/linux-x86/bin/header-abi-diff -allow-unreferenced-changes -allow-unreferenced-elf-symbol-changes -lib android.hardware.light@2.0 -arch arm64 -o 'out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_kryo300_vendor_shared/android.hardware.light@2.0.so.abidiff' -new 'out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_kryo300_vendor_shared/android.hardware.light@2.0.so.lsdump' -old prebuilts/abi-dumps/vndk/29/64/arm64_armv8-a/source-based/android.hardware.light@2.0.so.lsdump)|| (echo 'error: Please update ABI references with: $ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py  -l android.hardware.light@2.0' && (mkdir -p $DIST_DIR/abidiffs && cp 'out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_kryo300_vendor_shared/android.hardware.light@2.0.so.abidiff' $DIST_DIR/abidiffs/) && exit 1)
    ******************************************************
    error: VNDK library: android.hardware.light@2.0's ABI has INCOMPATIBLE CHANGES Please check compatibility report at: out/soong/.intermediates/hardware/interfaces/light/2.0/android.hardware.light@2.0/android_arm64_armv8-a_kryo300_vendor_shared/android.hardware.light@2.0.so.abidiff
    ******************************************************
    error: Please update ABI references with: $ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py  -l android.hardware.light@2.0
    15:57:58 ninja failed with: exit status 1
    

    解决:

    development/vndk/tools/header-checker/utils/create_reference_dumps.py -l android.hardware.light@2.0 -products kona
    development/vndk/tools/header-checker/utils/create_reference_dumps.py -product kona

    log:
    Creating dumps for target_arch: arm and variant armv8-2a
    Created abi dump at /prebuilts/abi-dumps/vndk/29/64/arm_armv8-2a/source-based/android.hardware.light@2.0.so.lsdump
    Creating dumps for target_arch: arm64 and variant armv8-a
    Created abi dump at /prebuilts/abi-dumps/vndk/29/64/arm64_armv8-a/source-based/android.hardware.light@2.0.so.lsdump
    再make 还是报错
    问题原因 .soon下面的缓存没clean
    rm -rf out/soong/.intermediates/hardware/interfaces/light 重新编译后正常

    单独模块验证:

    make android.hardware.light@2.0-impl -j24
     make android.hardware.light@2.0 -j24
    adb push system\lib64\vndk-29\android.hardware.light@2.0.so system/lib64/vndk-29/
    adb push  system\lib\vndk-29\android.hardware.light@2.0.so system/lib/vndk-29/
    adb push  vendor\lib\hw\android.hardware.light@2.0-impl.so vendor/lib/hw
    adb push vendor\lib64\hw\android.hardware.light@2.0-impl.so vendor/lib64/hw
    
    
    • liblight的具体实现 代码路径 hardware\qcom\display\liblight
      编译模块 make lights.kona -j24
      从hal接口传下来的ledId 就保存在light_state_t 中
    static struct hw_module_methods_t lights_module_methods = {
        .open =  open_lights,
    };
    
    static int open_lights(const struct hw_module_t* module, char const* name,
            struct hw_device_t** device)
    {
        int (*set_light)(struct light_device_t* dev,
                struct light_state_t const* state);
    
        if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
            g_has_persistence_node = !access(PERSISTENCE_FILE, F_OK);
            set_light = set_light_backlight;
        } else if (0 == strcmp(LIGHT_ID_BATTERY, name))
            set_light = set_light_battery;
    }
    /**
     * The parameters that can be set for a given light.
     *
     * Not all lights must support all parameters.  If you
     * can do something backward-compatible, you should.
     */
    struct light_state_t {
        unsigned int ledId;
        unsigned int batteryState;
    }
    
    

    本文只展示google开源代码,具体实现不便展示

    • hal层代码接口以及实现已经加好了,接下来看上层如何调用
      1、jni 添加接口
    frameworks\base\services\core\jni\com_android_server_lights_LightsService.cpp
    static void setLight_native(
            JNIEnv* /* env */,
            jobject /* clazz */,
            jint light,
            jint ledId,
            jint batteryState,
            jint colorARGB,
            jint flashMode,
            jint onMS,
            jint offMS,
            jint brightnessMode) {
        if (!sLightSupported) {
    

    2、frameworks\base\services\core\java\com\android\server\lights\LightsService.java

      static native void setLight_native(int light,int ledId,int batteryState, int color, int mode,
                int onMS, int offMS, int brightnessMode);
    

    《添加新接口流程已经完结》
    -【扩展】 如何添加一个系统服务管控LED,系统已经有一个服务LightsService.java,我们需要再添加一个对外提供接口
    1、frameworks\base\core\java 目录创建一个全局类XXXX.java
    获取一个上下文,不需要应用传参

     private static Context getContext() {
            ActivityThread thread = ActivityThread.currentActivityThread();
            if (thread != null) {
                return (Context) thread.getApplication();
            } else {
                return null;
            }
        }
    

    2、编写静态接口方法

        public static void xxxx(int eventId) {
            Context context = getContext();
            if (context != null) {
                if(xxxManger==null) {
                    xxxManger= new xxxManger(context);
                }
                    xxxManger.xxxxFun(eventId);
    
            } else {
                Log.e(TAG, "xxx: context is null");
            }
        }
    

    3、xxxManger.java 编写aidl调用方法

    private synchronized IxxxMangerService getService() {
            if (mService == null) {
                mService = IxxxMangerService .Stub.asInterface(
                        ServiceManager.getService("xxxservice"));
                if (mService == null) {
                    Log.w("xxxxManger", "warning: no CWDEIVCE_SERVICE");
                }
            }
            return mService;
        }
      public void xxxxFun(int eventId) {
            try {
                final IxxxMangerService cvc = getService();
                if (cvc != null) {
                    cvc.xxxxFun(eventId);
                }
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    

    4、同目录添加aidl
    frameworks\base\core\java\IxxxMangerService.aidl
    interface IxxxMangerService {
    void xxxxFun(int eventId);
    }
    5、实现aidl的具体方法
    public class xxxMangerService extends IxxxMangerService.Stub{
    }
    6、把此服务开机启动

    frameworks\base\services\java\com\android\server\SystemServer.java
     xxxMangerService = new xxxMangerService (mSystemContext);
                ServiceManager.addService("xxxservice", xxxMangerService );
    

    7、添加权限

    ------------------------------ private/service.te ------------------------------
    index a8ee1955..c8248025 100644
    @@ -5,3 +5,5 @@ type gsi_service,                   service_manager_type;
     type incidentcompanion_service,     system_api_service, system_server_service, service_manager_type;
     type stats_service,                 service_manager_type;
     type statscompanion_service,        system_server_service, service_manager_type;
    +type led_service,     system_api_service, system_server_service, service_manager_type;
    +
    
    --------------------------- private/service_contexts ---------------------------
    index 96d553bf..ee12cbed 100644
    @@ -219,4 +219,5 @@ wificond                                  u:object_r:wificond_service:s0
     wifiaware                                 u:object_r:wifiaware_service:s0
     wifirtt                                   u:object_r:rttmanager_service:s0
     window                                    u:object_r:window_service:s0
    +xxxservice                             u:object_r:led_service:s0
    
    • 【扩展】动态设置电池、数据库的实现原理
    动态设置电池
    dumpsys battery set level 1  (电池电量)
    
    dumpsys battery set status 2  (电池电量)      
    BATTERY_STATUS_INVALID = 0;
    BATTERY_STATUS_UNKNOWN = 1;
    BATTERY_STATUS_CHARGING = 2;
    BATTERY_STATUS_DISCHARGING = 3;
    BATTERY_STATUS_NOT_CHARGING = 4;
    BATTERY_STATUS_FULL = 5;
    
    设置电池温度
    dumpsys battery set temp 560
    动态设置数据库
    adb shell settings put global device_provisioned 1
    adb shell settings put secure user_setup_complete 1
    
    adb shell settings put global device_provisioned 0
    adb shell settings put secure user_setup_complete 0
    
    adb shell settings get global device_provisioned 
    adb shell settings get secure user_setup_complete 
    

    以battery 的命令为例
    frameworks\base\services\core\java\com\android\server\BatteryService.java

    定义一个内部类
            private final class BinderService extends Binder {
                @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
                    if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
    
                    if (args.length > 0 && "--proto".equals(args[0])) {
                        dumpProto(fd);
                    } else {
                        dumpInternal(fd, pw, args);
                    }
                }
    
                @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
                        FileDescriptor err, String[] args, ShellCallback callback,
                        ResultReceiver resultReceiver) {
                    (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
                }
            }
    
    发布
    @Override
        public void onStart() {
            registerHealthCallback();
    
            mBinderService = new BinderService();
            publishBinderService("battery", mBinderService);
    }
    

    相关文章

      网友评论

          本文标题:LED灯系统架构(基于google源码分析)

          本文链接:https://www.haomeiwen.com/subject/gwleoltx.html