OpenHarmony底座升级指南(3.2升级4.0)

前言

本文旨在帮助开发者完成底座升级,文中主要以OpenHarmony 3.2 release 升级至OpenHarmony 4.0 release为模板描述。

一、流程概览:

1.1 准备工作

在准备阶段,需要完整收集所有的定制化修改,明确修改人;并且要将模块责任田细化明确,确保每个模块都有相应责任人。

1.2 切换阶段

在切换阶段,以编译构建与屏幕点亮的工作量最大,难度最高。

小版本(如4.0 beta切换至4.0 release)切换较为简单:可以在直接拉取社区4.0 release分支后,将在4.0 beta上的定制化修改一次性合入;解决合入冲突并且编译即可。

大版本(如3.2 release切换至4.0 release)切换相对复杂:需要在拉取社区4.0 release分之后,完成与点亮相关的几个关键仓库的修改与适配(kernel、device_xxx、vendor_xxx),并结合至新分支其他子系统,整编通过,实现点亮。所有其他子系统的定制化修改,需要再点亮完成后再进行。

  • 注意事项:关键仓的切换策略会影响整个基线切换进程和后期维护难度。通常来讲,有两种可行策略:1.使用当前产品化版本(3.2 release)中的关键仓库直接在4.0 release中进行替换;然后参考社区在4.0 release中的改动,进行接口适配。2.直接使用社区版本(4.0 release),并根据产品特性的修改记录,进行新一轮适配。

1.3 验证阶段

与常规项目类似,即开发自验证与测试验证,确保升级后的各功能质量。

二、编译问题处理

整体编译产品,执行编译命令后,处理编译报错问题。易现的编译问题:

1、未适配的产品模块容易出现编译报错。
2、新增的白名单规则导致的编译报错。
3、更严格的模块依赖规范导致的编译报错。
4、产品组件编译后并未安装到out下的产品目录导致运行错误。
5、更严格的语法检查规范容易导致语法检查错误。

2.1 屏蔽非点亮模块编译

在碰到编译中暂时无法解决的错误,如非产品点亮相关,可暂时屏蔽改模块的编译。

1、屏蔽产品组件,修改BUILD.gn文件,例如从group属性中删除某组件

文件路径:vendor/[manufacturerName]/产品名/modules/BUILD.gn

文件路径:vendor/[manufacturerName]/产品名/modules/BUILD.gn

group("modules") {
  deps = [
    ":[manufacturerName]_wlan_combo",
#    ":sc2355_sdio_wlan",
    ":[manufacturerName]bt_tty",
    ":wifi_board_config",
    ":bt_configure_pskey",
    ":bt_configure_rf",
    ":bt_configure_pskey_aa",
    ":bt_configure_rf_aa",
    ":wcnmodem",
#    ":gnssmodem",
    ":build_modules",        
#    "wcn/bluetooth/hal:libbt_vendor",    //编译报错,从编译中屏蔽蓝牙模块
    ":vpu",
    ":nvt_nt36xxx_spi_ts",
    ":novatek_ts_fw",
    ":mali_kbase",

2、屏蔽产品部件,从ohos.build中删除产品部件,也可能需要在config.json中关联的productdefine中的产品配置中删除关联配置

文件路径:vendor/[manufacturerName]/[productName]/ohos.build
{
  "parts": {
    "product_[productName]": {
      "module_list": [
        "//device/board/[manufacturerName]/[productName]:[productName]_group",
        ...
      ]
    },
#################可从该文件中删除modem、radio部件等不影响亮屏的部件##################    
#    "modem":{
#      "module_list": [
#        "//vendor/[manufacturerName]/[productName]/modem:modem"
#      ]
#    },
#    "radio":{
#      "module_list": [
#        "//vendor/[manufacturerName]/[productName]/telephony:radio"
#      ]
#    }
#  },
#####################################################################################
  "subsystem": "product_[productName]"
}

2.2 白名单问题处理

开发者手机项目中以前用的代码底座是3.2release的,当前要切换社区4.0release的代码位底座,切换后,新增的部分代码报了很多依赖错误,未改动的模块也报了很多依赖问题,如:

2.2.1. 对于未改动的模块报的依赖错误

已确定不影响当前功能,没必要改,可待后续代码升级时自动修复;若需修改,可参考下面的修改方法

2.2.2 对于开发手机修改或添加的相关代码的依赖报错
2.2.2.1 修改适配位置//device/soc
  1. 当前适配了新芯片,位置在//device/soc/[manufacturerName]/[productName]/hardware,可在//build/subsystem_config.json添加新子系统的配置如:
  "soc_[manufacturerName]": {
    "path": "device/soc/[manufacturerName]/[productName]/hardware",
    "name": "soc_[productName]"
  }

其中,soc_[manufacturerName]代表子系统名称,soc_[productName]代表部件名称

  1. 在device/soc/[manufacturerName]/[productName]/hardware目录下,没特殊情况时各gni,gn文件中配置的子系统名称,部件名称改为上一步配置的名称,如:
  subsystem_name = "soc_[manufacturerName]"
  part_name = "soc_[productName]"
  1. 新增部件(一个部件只能属于一个子系统)定义文件//device/soc/[manufacturerName]/[productName]/hardware/bundle.json
{
    "name": "@ohos/soc_[productName]",
    "description": "device [productName] soc components",
    "homePage": "",
    "version": "3.1",
    "license": "Apache License 2.0",
    "repository": "",
    "publishAs": "code-segment",
    "segment": {
        "destPath": "device/soc/[manufacturerName]/[productName]/hardware"
    },
    "dirs": {},
    "scripts": {},
    "component": {
        "name": "soc_[productName]",
        "subsystem": "soc_[manufacturerName]",
        "syscap": [],
        "adapted_system_type": [
            "standard"   //适配标准系统
        ],
        "rom": "",
        "ram": "",
        "hisysevent_config": [],
        "deps": {
            "components": [ //各子组件依赖的库,依据gn文件中的external_deps,deps数据
                "hilog",
                "graphic_2d",
                ...
            ],
            "third_party": [ //第三方依赖
              "libdrm"
            ]
        },
        "build": {
            "sub_component": [ //要参与编译的子组件,有的是group,group下可能再包含group,只需添加最上层grou即可
                "//device/soc/[manufacturerName]/[productName]/hardware:hardware_group",
                "//device/soc/[manufacturerName]/[productName]/hardware/aosp/hardware/interfaces/graphics/common:common-impl",
                "//device/soc/[manufacturerName]/[productName]/hardware/omx_il:lib_omx"
              ],
              "inner_kits": [ //如果其他部件有依赖本部件(soc_[productName])中的子组件,如动态库等,需要在此添加如下配置,外部才能引用;----注意:如果外部未引用,而在此添加本部件中的某组件,会导致此组件异常。
                {
                  "header": {
                    "header_base": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libdmabufheap/include",
                    "header_files": [
                      "BufferAllocator/BufferAllocator.h",
                      "BufferAllocator/BufferAllocatorWrapper.h",
                      "BufferAllocator/dmabufheap-defs.h"
                    ]
                  },
                  "name": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libdmabufheap:libaosp_dmabufheap"
                },
                ...
                {
                  "header": {
                    "header_base": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libmemion/include",
                    "header_files": [
                      "C2UnisocDmaBuffer.h",
                      "dmaphyaddr-defs.h",
                      "VideoMemAllocator.h"
                    ]
                  },
                  "name": "//device/soc/[manufacturerName]/[productName]/hardware/aosp/system/memory/libmemion:libmemion"
                }
              ],
              "test": []
        }
    }
}
  1. 添加//device/soc/[manufacturerName]/[productName]/hardware/ohos.build文件,定义子系统包含的部件,编译入口配置文件
{
    "subsystem": "soc_[manufacturerName]", //子系统名
    "parts": {
        "soc_[productName]": {    //部件名称
            "module_list": [ //部件包含模块的gn目标
                "//device/soc/[manufacturerName]/[productName]/hardware:hardware_group",
                "//device/soc/[manufacturerName]/[productName]/hardware/omx_il:lib_omx"
            ]
        }
    }
}
2.2.2.2 修改适配位置//device/board
  1. 修改//device/board/[manufacturerName]/[productName]/BUILD.gn,去掉group(“[productName]_group”)下deps中的//device/soc/[manufacturerName]/[productName]/hardware:hardware_group,此编译目标已在上一步定义过,此处不在需要;

  2. 添加//device/board/[manufacturerName]/[productName]/bundle.json部件定义文件(以前没这个文件,当前版本代码不添加这个文件的话,如gn文件中用到了init组件,不在bundle.json中deps下添加的话会报错)

  {
    "name": "@ohos/device_[productName]",
    "description": "device board",
    "version": 3.2,
    "license": "Apache License 2.0",
    "publishAs": "code-segment",
    "segment": {
      "destPath": "device/board/[manufacturerName]/[productName]"
    },
    "dirs": {},
    "scripts": {},
    "component": {
      "name": "device_[productName]",
      "subsystem": "device_[productName]",
      "syscap": [],
      "features": [],
      "adapted_system_type": [ "standard" ],
      "hisysevent_config": [],
      "rom": "",
      "ram": "",
      "deps": {
        "components": [
          "init"    //当前部件中gn文件用到了init组件
        ],
        "third_party": []
      },
      "build": {
        "sub_component": [
            "//device/board/[manufacturerName]/[productName]:[productName]_group"
        ],
        "test": []
      }
    }
  }
  1. 根据上一步定义的子系统名和部件名device_[productName],修改本部件下各gn中的子系统名和部件名的相关配置

  2. 修改//device/board/[manufacturerName]/[productName]/ohos.build

{
    "subsystem": "device_[productName]",
    "parts": {
        "device_[productName]": {
            "module_list": [ // ${product_name} 当前就是[productName]
                "//device/board/[manufacturerName]/${product_name}:[productName]_group"  //改前为"//device/soc/[manufacturerName]/${product_name}/hardware:hardware_group",此模块在前几步已配置
            ],
            "test_list": [
                "//kernel/linux/build/test:linuxkerneltest"
            ]
        }
    }
}
2.2.2.3 修改适配位置vendor
  1. 修改//vendor/[manufacturerName]/[productName]/ohos.build, 去掉module_list下的"//device/board/[manufacturerName]/ p r o d u c t _ n a m e : {product\_name}: product_name:{product_name}_group", 因为前面已配置

  2. 添加//vendor/[manufacturerName]/[productName]/bundle.json,参考前面的方法添加即可

  3. 修改外部依赖错误(编译时这种错误依赖会报错,可以在发现报错时再改,可能是外部依赖放到了deps,也可能内部依赖放到了external_deps中),如下图所示:

  1. 修改部件名称错误,如把不属于此子系统的部件名,配置为了编译目标的部件名,也可在编译报错时再找到对应位置修改

  2. 修改//vendor/[manufacturerName]/[productName]/config.json,添加上诉步骤中新增的子系统,如:

    {
      "subsystem": "soc_[manufacturerName]",
      "components": [
        {
          "component": "soc_[productName]",
          "features": []
        }
      ]
    }
  1. 修改//vendor/[manufacturerName]/[productName]/modules/BUILD.gn中相关子系统名称和部件名称
    因为此文件中相关编译目标所属的group(“modules”)在//device/board/[manufacturerName]/[productName]/BUILD.gn中定义(“//vendor/[manufacturerName]/[productName]/modules:modules”)。
    为何此时,vendor下的子系统名部件名没有配置为product_[productName]也没有报依赖错误?因为此时gn文件中用的是ohos_prebuilt_executable这种,只是用来拷贝文件
2.2.3 临时屏蔽依赖报错,绕过依赖检查,继续编译
        ...
        else:
            raise Exception(_warning_info)

和check_part_deps()和check()函数中的抛异常语句:

        ...
        else:
            raise Exception(message)
  1. 在//build/templates/common/check_external_deps.py 中注释掉check_parts_deps() 函数中的两个抛异常语句

  2. 在//build/templates/common/check_part_subsystem_name.py 中注释掉check()函数第二个抛异常语句

  3. 此方法只能临时使用,后续其他模块的依赖错误或依赖不规范问题也是需要整改的

2.3 基于4.0的模块依赖规范的修改:

1、部件编译文件BUILD.gn中使用的外部依赖(非本部件中的组件)不可放在deps属性中,需移到external_deps中

   external_deps = [
     "c_utils:utils",
     "graphic_chipsetsdk:surface",
     "hdf_core:libhdf_host",
     "hdf_core:libhdf_ipc_adapter",
     "hdf_core:libhdf_utils",
     "hdf_core:libhdi",
     "hilog:libhilog",
     "ipc:ipc_single",
   ]

2、device下产品部件配置文件bundle.json中需添加依赖的系统部件到components下

    "component": {
      "name": "device_[productName]",
      "subsystem": "device_[productName]",
      "syscap": [],
      "features": [],
      "adapted_system_type": [ "standard" ],
      "hisysevent_config": [],
      "rom": "",
      "ram": "",
      "deps": {
        "components": [
          "init",
          "c_utils",
          "hilog"
        ],
        "third_party": []
      },
      "build": {
        "sub_component": [
            "//device/board/[manufacturerName]/[productName]:[productName]_group"
        ],
        "test": []
      }
    }
  }

2.4 产品仓模块编译配置修改

产品仓模块编译后没有安装到对应的产品目录,需确认:

1、 确认模块编译文件BUILD.gn,将部件名和子系统名改为产品目录对应的部件名和子系统名

产品路径:device/board/产品名/camera/vdi_impl/v4l2/BUILD.gn

产品路径:device/board/产品名/camera/vdi_impl/v4l2/BUILD.gn

ohos_shared_library("camera_host_vdi_impl_1.0") {
  ...
  install_enable = true
  part_name = "device_laphone"        //这里改为产品部件名
  subsystem_name = "device_laphone"    //这里改为产品子系统名
}

group("camera_board_vdi_impl") {    //包含在group
  deps = [
    ":camera_host_vdi_impl_1.0",
    ":chipset_build",
  ]
}

group("[productName]_group") {
  deps = [
    ...
    "//device/board/[manufacturerName]/[productName]/camera/vdi_impl/v4l2:camera_board_vdi_impl",    //group被包含在另一个group
    "//third_party/alsa-lib:libasound",
    "//third_party/alsa-utils:alsa-utils",
  ]
  if (is_standard_system) {
    deps += [ "startup/reboot_loader:rebootloader" ]
  }
}

2、确认vendor下产品的ohos.build的配置是否关联了该模块的编译

文件路径:device/board/[manufacturerName]/***/bundle.json
    ...
    "component": {
      "name": "device_[productName]",
      "subsystem": "device_[productName]",
      "syscap": [],
      "features": [],
      "adapted_system_type": [ "standard" ],
      "hisysevent_config": [],
      "rom": "",
      "ram": "",
      "deps": {
        "components": [
          "init",
          "c_utils",
          "hilog"
        ],
        "third_party": []
      },
      "build": {
        "sub_component": [
            "//device/board/[manufacturerName]/[productName]:[productName]_group"    //包含了上1、中的group
        ],
        "test": []
      }
    }
  }
  1. feature配置问题:

vendor产品config.json中的feature特性名变更导致的报错,需要确认gni头文件中的变量是否一致。

文件:vendor/[manufacturerName]/产品名/config.json
    {
      "subsystem": "hdf",
      "components": [
        {
          "component": "drivers_interface_audio",
          "features": []
        },
        {
          "component": "drivers_peripheral_audio",
          "features": [
            "drivers_peripheral_audio_feature_full_test_suite = true",
            "drivers_peripheral_audio_feature_alsa_lib = true"
          ]
        },
        {
          "component": "drivers_peripheral_codec",
          "features": []
        }
      ]
    }
    
feature对应gni头文件:drivers/peripheral/audio/audio.gni
declare_args() {
  drivers_peripheral_audio_feature_mono_to_stereo = false
  drivers_peripheral_audio_feature_hal_notsupport_pathselect = false
  drivers_peripheral_audio_feature_hdf_proxy_stub = true
  drivers_peripheral_audio_feature_user_mode = false
  drivers_peripheral_audio_feature_full_test_suite = false
  drivers_peripheral_audio_feature_policy_config = true
  drivers_peripheral_audio_feature_alsa_lib = true
  drivers_peripheral_audio_feature_rich_device = false
  drivers_peripheral_audio_feature_community = true
  drivers_peripheral_audio_feature_effect = false
}

2.5 解决部分编译报错问题

语法问题导致的编译警告报错:

1、未使用的临时变量,执行语法屏蔽或删除操作;

2、c代码中定义的无参函数需增加默认参数void;

​ 其他代码也要按语法规范书写,要么通过cflags,cflags_c,cflags_cc等属性添加-Wnoerror类参数屏蔽警告错误。

​ 针对c++使用cflags、cflags_cc 参考:

  cflags_cc = [
    "-Wall",
    "-Wextra",
    "-Werror",
    "-Wno-error",
    "-DGST_DISABLE_DEPRECATED",
    "-DHAVE_CONFIG_H",
    "-DCOLORSPACE=\"videoconvert\"",
    "-fno-strict-aliasing",
    "-Wno-sign-compare",
    "-Wno-builtin-requires-header",
    "-Wno-unused-variable",
    "-Wno-unused-label",
    "-Wno-implicit-function-declaration",
    "-Wno-format",
    "-Wno-int-conversion",
    "-Wno-unused-function",
    "-Wno-thread-safety-attributes",
    "-Wno-inconsistent-missing-override",
    "-fno-rtti",
    "-fno-exceptions",
    "-ffunction-sections",
    "-fdata-sections",
  ]

针对c使用cflags_c参考:

  cflags_c = [
    "-Wall",
    "-Wextra",
    "-Werror",
    "-Wno-predefined-identifier-outside-function",
    "-Wno-macro-redefined",
    "-Wno-format",
    "-Wno-unused-parameter",
    "-Wno-unused-variable",
    "-fsigned-char",
    "-fno-common",
    "-fno-strict-aliasing",
  ]

三、屏幕点亮

4.0相对于3.2,在OpenHarmony 4.0图形HDI基础适配及点屏上存在较大差异,所以应先了解差异点再进行点亮。

3.1 进程调用关系变化

3.1.1 进程数量变化

新增加两个uhdf进程。allocator_host进程及composer_host进程。

删除了disp_gralloc_host 进程,并使用allocator_host替换。

uhdf添加进程配置如下:

display_composer :: host {
    hostName = "composer_host";
    priority = 40;
    processPriority = -8;
    threadPriority = 1;
    caps = ["SYS_NICE"];
    uid = ["composer_host"];
    gid = ["composer_host", "graphics", "vendor_mpp_driver"];
    composer_device :: device {
        device0 :: deviceNode {
            policy = 2;
            priority = 160;
            moduleName = "libdisplay_composer_driver_1.0.z.so";
            serviceName = "display_composer_service";
        }
    }
}
allocator :: host {
    hostName = "allocator_host";
    priority = 40;
    allocator_device :: device {
        device0 :: deviceNode {
            policy = 2;
            priority = 160;
            moduleName = "liballocator_driver_1.0.z.so";
            serviceName = "allocator_service";
        }
    }
}
3.1.2 拉起关系变化
  • composer

以前版本composer由render_service通过单例拉起,现在通过composer service拉起接口实现层libdisplay_composer_vdi_impl.z.so,对外提供标准的IPC服务.

  • allocator

进程名字由disp_gralloc_host变更成allocator_host。通过allocator_service拉起接口实现层libdisplay_buffer_vdi_impl.z.so,对外提供标准的IPC服务。

3.2 接口协议更新

3.2.1 接口更新

结构体定义由原来的.h变为接口描述语言IDL代替,在协议升级过程中,会遇到大量结构体命名空间不一样的冲突,总体解决思路就是去掉原有的.h头文件依赖,增加新的接口头文件即可。

  • allocator_host

    头文件更新:由display_type.h 更新成v1_0/display_buffer_type.h。由DisplayBufferType.idl生成在out下

    接口协议更新:

    由原来的display_gralloc.cpp中提供的接口更换成OHOS::HDI::Display::Buffer::V1_0::IDisplayBufferVdi,并新建接口实现文件:

    display_buffer_vdi_impl.cpp/.h。

    参考drivers/peripheral/display/hal/default_standard/src/display_gralloc/display_buffer_vdi_impl.cpp中的接口,并按自己的实际情况完成实现。

  • composer_host

    头文件更新:由display_type.h 更新成v1_0/display_composer_type.h。由DisplayComposerType.idl生成在out下

    由原来的hdi_session.cpp中提供的接口更换成OHOS::HDI::Display::Composer::V1_0::IDisplayComposerVdi,并新建接口实现文件:

    display_composer_vdi_impl.cpp/.h

    参考drivers/peripheral/display/hal/default_standard/src/display_device/display_composer_vdi_impl.cpp中的接口,并按自己的实际情况完成实现。

3.2.2 其它头文件更新
  • BufferHandle

新结构体去掉了key,如果代码中有用到,需要让以下定义保持一致:

drivers/hdf_core/interfaces/inner_api/hdi/base/buffer_handle.h
drivers/peripheral/base/buffer_handle.h
foundation/graphic/graphic_2d/frameworks/surface/include/buffer_handle.h
  • 其它头文件:

drivers/peripheral/display/interfaces/include下的头文件与device_type.h有关联。要解耦,不要使用。

3.3 开机动画

在4.0中,开机动画默认使用的是播放视频,对点屏不友好,建议修改成原图片播放方式,修改方法如下:

frameworks/bootanimation/include/boot_animationconfig.h

@@ -33,7 +33,7 @@ public:
    bool IsBootVideoEnabled();
private:
    BootCustomConfig custConfig_;
-   bool bootVideoEnabled_ = true;
+   bool bootVideoEnabled_ = false; //不使用视频开机动画模式
};
} // namespace OHOS

3.4 hello_composer编译报错

合入如下修改解决:

diff --git a/rosen/samples/composer/hello_composer.cpp b/rosen/samples/composer/hello_composer.cpp
index a907af7db..520da2e38 100644
--- a/rosen/samples/composer/hello_composer.cpp
+++ b/rosen/samples/composer/hello_composer.cpp
@@ -74,7 +74,7 @@ void HelloComposer::Run(const std::vector<std::string> &runArgs)
     sleep(1);
     std::shared_ptr<OHOS::AppExecFwk::EventRunner> runner = OHOS::AppExecFwk::EventRunner::Create(false);
     mainThreadHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
-    g_receiver = new VSyncReceiver(vsyncConnection, mainThreadHandler_);
+    g_receiver = new VSyncReceiver(vsyncConnection, nullptr, mainThreadHandler_);
     g_receiver->Init();
     mainThreadHandler_->PostTask(std::bind(&HelloComposer::RequestSync, this));
     runner->Run();
@@ -473,6 +473,7 @@ void HelloComposer::DoPrepareCompleted(sptr<Surface> surface, const struct Prepa
             clientCount++;
         }
     }
+    LOGI("clientCount:%{public}d");

     auto addr = static_cast<uint8_t *>(fbBuffer->GetVirAddr());
     if (hasClient) {

3.5 问题列举

本次实战主要是把产品从3.2.3-Release升级到4.0-Release。中间看到这些变化,心里有点慌,从而记录下来,并提供给大家参考。框架上遇到的一些问题,前面几节已经给大家说明了,以下是一些升级的步骤及建议。

1、添加接口协议文件、gn编译、hcs配置。

为composer添加display_composer_vdi_impl.cpp/.h

为gralloc添加display_buffer_vdi_impl.cpp/.h。

在gn中添加目标libdisplay_composer_vdi_impl和libdisplay_buffer_vdi_impl。

在device_info.hcs中添加进程配置。

2、编译修改。

这个是工作量比较大的地方。原则上就是去掉drivers/peripheral/display/interfaces/include下的头文件依赖,并添加

#include “v1_0/display_composer_type.h”

 #include "v1_0/display_buffer_type.h"

以及命名空间:

using namespace OHOS::HDI::Display::Composer::V1_0;

using namespace OHOS::HDI::Display::Buffer::V1_0;

当然gn中也要添加相应的依赖。

3、调试。

主要使用hello_composer调试,关注hdi_backend.cpp中Repaint函数执行流程,并在hilog中搜索关键命令字:REQUEST_CMD,一个完整的流程必须包含以下命令:

REQUEST_CMD_PREPARE_DISPAY_LATERS
REQUEST_CMD_SET_DISPLAY_CLIENT_DAMAGE
REQUEST_CMD_SET_DISPLAY_CLENT_BUFFER
REQUEST_CMD_COMMIT

如果so没有正常加载,也可以在以下文件中添加打印:

drivers/peripheral/display/buffer/hdi_service/src/allocator_service.cpp
drivers/peripheral/display/composer/hdi_service/src/display_composer_service.cpp

可以为dlopen添加详细错误信息,默认没有添加:

if (libHandle_ == NULL) {
        error = dlerror();
        DISPLAY_LOGE("composer load path%{public}s, dlopen err=%{public}s", DISPLAY_COMPOSER_VDI_LIBRARY, error);
        return HDF_FAILURE;
    }

四、合入其他模块修改

其他模块的合入,需要各个责任田单独负责。后续将有关于audio与camera相关的升级指导。

为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙 (Harmony OS)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. ……

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门?:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/297875.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript 基础通关

快速熟悉 JavaScript 的基础语法&#xff0c;比较高级的比如事件放在后面的笔记中。 JavaScript 1. JavaScript 介绍 1.1 JavaScript 基本介绍 JavaScript 是一门运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;实现人机交互的效果。实现网页特效、表单验…

计算机中的数据运算

放上计算机中的数据的表示方法 计算机中的数据表示方法-CSDN博客 补码的运算&#xff1a; 连同符号位一起相加&#xff0c;符号位产生的进位自然丢掉&#xff0c;这里要特别注意机器数的位数&#xff0c;计算数的位数决定了可以存放的数据的大小&#xff0c;加减产生的数据的…

【LeetCode:2807. 在链表中插入最大公约数 | 链表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

构建异地企业网络互联的高效路径

在当今数字化浪潮中&#xff0c;企业的业务拓展已不再受限于地理位置。为了在全球竞争中立于不败之地&#xff0c;越来越多的企业选择在不同城市设立分支机构&#xff0c;构建异地网络&#xff0c;实现高效的协同办公。本文将深入探讨在北上广等经济发达地区&#xff0c;如何通…

Nginx 访问控制

目录 1. 传输层禁止访问 2. 应用层访问控制 访问控制有两个方式&#xff0c;一种是在OSI模型的四层传输层&#xff0c;一种是在第七层应用层。 主机防火墙就是在四层传输控制&#xff0c;nginx就是在七层应用控制。 1. 传输层禁止访问 在进行访问控制前&#xff0c;先开启防…

力扣2807.在链表中插入最大公约数

思路&#xff1a;遍历链表&#xff0c;对于每一个结点求出它与下一个结点的最大公约数并插入到俩个结点之间 代码&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}…

详细平稳解

1.详细平衡 定义&#xff1a;一个在高斯白噪声激励下的动力学系统在状态空间中如果用如下运动方程描述&#xff1a; d d t X j \frac{d}{dt}\mathbf{X}_{j} dtd​Xj​ f j ( X ) f_{j}(\mathbf{X}) fj​(X) ∑ l 1 m g j l ( X ) W l ( t ) \sum_{l1}^{m}g_{jl}(\mathbf{X})W…

大语言模型的幻觉:解析、成因及解决方法

目录 前言1 大语言模型的幻觉现象解析1.1 输入冲突幻觉&#xff08;Input-conflicting&#xff09;1.2 上下文冲突幻觉&#xff08;Context-conflicting&#xff09;1.3 事实冲突幻觉&#xff08;Fact-conflicting&#xff09; 2 幻觉产生的原因2.1 数据偏差和模型缺陷2.2 知识…

1-02VS的安装与测试

一、概述 对于一名C语言程序员而言&#xff0c;进行C语言程序的开发一般需要一个文本编辑器加上一个编译器就足够了。但为了方便起见&#xff0c;我们选择使用集成开发环境——Visual Studio&#xff08;简称VS&#xff09;。安装Visual Studio 下面讲一下如何安装VS&#xff0…

计算机网络(8):因特网上的音频/视频服务

概述 计算机网络最初是为传送数据设计的。因特网 IP 层提供的 “尽最大努力交付” 服务以及每一个分组独立交付的策略&#xff0c;对传送数据信息十分合适。因特网使用的 TCP 协议可以很好地解决P层不能提供可靠交付这一问题。 音频/视频常称为多媒体信息 多媒体信息&#xff…

Linux第17步_安装SSH服务

secure shell protocol简称SSH。 目的&#xff1a;在进行数据传输之前&#xff0c;SSH先对联级数据包通过加密技术进行加密处理&#xff0c;然后再进行数据传输&#xff0c;确保数据传输安全。 1、在安装前&#xff0c;要检查虚拟机可以上网&#xff0c;否则可能会导致安装失…

常见Mysql数据库操作语句

-- DDL创建数据库结构 -- 查询所有数据库 show databases ; -- 修改数据库字符集 alter database db02 charset utf8mb4; -- 创建字符编码为utf——8的数据库 create database db05 DEFAULT CHARACTER SET utf8;-- 创建表格 create table tb_user(id int auto_increment primar…

【docker】数据卷和数据卷容器

目录 一、如何管理docker容器中的数据&#xff1f; 二、数据卷 1、数据卷原理 2、数据卷的作用 3、数据卷案例 三、数据卷容器 1、数据卷容器作用 2、数据卷容器案例 四、容器互连&#xff08;centos镜像&#xff09; 一、如何管理docker容器中的数据&#xff1f; 二、…

Apple M2 Pro芯片 + docker-compose up + mysql、elasticsearch pull失败问题的解法

背景 &#xff08;1&#xff09;从github上git clone了一个基于Spring Boot的Java项目&#xff0c;查看readme&#xff0c;发现要在项目的根目录下&#xff0c;执行“docker-compose up”。&#xff08;2&#xff09;执行“docker-compose up”的前提是&#xff0c;在macos上要…

编译原理笔记(三)

一、词法分析程序的设计 1、词法分析程序的输出 在识别出下一个单词同时验证其词法正确性之后&#xff0c;词法分析程序将结果以单词符号的形式发送至语法分析程序以回应其请求。 单词符号一般分下列5类&#xff1a; 关键字&#xff1a;如&#xff1a;begin、end、if、whil…

Spring Boot学习随笔- 集成MyBatis-Plus(二)条件查询QueryWrapper、聚合函数的使用、Lambda条件查询

学习视频&#xff1a;【编程不良人】Mybatis-Plus整合SpringBoot实战教程,提高的你开发效率,后端人员必备! 查询方法详解 普通查询 // 根据主键id去查询单个结果的。 Test public void selectById() {User user userMapper.selectById(1739970502337392641L);System.out.print…

opencv007 图像运算——加减乘除

今天学习图像处理的基础——加减乘除&#xff0c;总体来说比较好理解&#xff0c;不过生成的图片千奇百怪哈哈哈哈 opencv中图像的运算本质是矩阵的运算 加法 做加法之前要求两张图片形状&#xff0c;长宽&#xff0c;通道数完全一致 cv2.add(img1, img2) add的规则是两个图…

MySQL之视图内连接、外连接、子查询

一、视图 1.1 含义 虚拟表&#xff0c;和普通表一样使用 视图&#xff08;view&#xff09;是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。但是&#xff0c;数据库中只存放了视图的定义&#xff0c;而并没有存放…

Visio导出eps格式图片

Visio导出eps格式图片 文章目录 Visio导出eps格式图片1. Visio中使用Adobe Acrobat虚拟打印2. Adobe Acrobat中裁剪并另存为eps格式 如何使用Visio绘图然后导出.eps格式的图片呢&#xff1f;这个过程需要用到Adobe Acrobat&#xff0c;使用Adobe Acrobat的虚拟打印功能&#xf…

JVM知识总结(简单且高效)

1. JVM内存与本地内存 JVM内存&#xff1a;受虚拟机内存大小的参数控制&#xff0c;当大小超过参数设置的大小时会报OOM。本地内存&#xff1a;本地内存不受虚拟机内存参数的限制&#xff0c;只受物理内存容量的限制&#xff1b;虽然不受参数的限制&#xff0c;如果所占内存超过…
最新文章