Android UpdateEngine 模块分析(一)模块编译介绍

前言

本章节分析 UpdateEngine 模块中编译文件 Android.mk,从整体去分析 UpdateEngine 所生成的模块,依赖以及功能。

下一篇:Android UpdateEngine 模块分析(二)UpdateEngine 服务启动

正文

UpdateEngine 模块是 Android 中的升级模块,其主要的核心功能是系统的 A/B 升级,理解了 UpdateEngine 就理解了在 Android 中 A/B 升级是如何运行的。那么接下来对 UpdateEngine 进行分析,首先分析它的编译结构,再基于编译出的相关模块分析各模块的核心操作。代码路径:system/update_engine/

1、UpdateEngine编译结构分析

1.1 UpdateEngine编译架构

下图是 UpdateEngine 模块所编译出的文件模块,包括 filegroup、genrule、cc_defaults、cc_library_static、cc_library_shared、cc_binary_host、cc_binary、cc_test、cc_prebuilt_binary 模块。

简单介绍:

filegroup 和 genrule,文件组和规则文件,将有相关性的文件定义在一起,供后续模块直接使用;

cc_defaults,默认模块,给后续的静态库、动态库等提供依赖;

cc_library_static 和 cc_library_shared,静态库和动态库,将特有的功能文件封装,提供可执行模块依赖;

cc_binary_host 和 cc_binary,可执行文件,较为重要,是模块功能的输出形式,系统会通过此可执行文件启动模块服务;

cc_test,测试模块,Google单元测试,测试模块的功能是否符合预期;

cc_prebuilt_binary,预编译可执行文件,编译复制脚本 brillo_update_payload 到 host 下面,给差分包制作脚本提供支持;

扫描二维码关注公众号,回复: 17213107 查看本文章

在这里插入图片描述

对于 UpdateEngine 模块的编译,输出的二进制可执行文件是最终产物,对于模块的分析,需要从这里入手,下面列出可执行文件的编译依赖:

UpdateEngine:

在这里插入图片描述

update_engine_sideload:
在这里插入图片描述

update_engine_client:
在这里插入图片描述

delta_generator:
在这里插入图片描述

1.2 UpdateEngine编译模块表

编号 模块类型 模块名 依赖
1 filegroup libupdate_engine_aidl
2 filegroup things_update_engine_aidl
3 cc_defaults ue_defaults [static_libs : libgtest_prod] [shared_libs : libbrillo-stream, libbrillo, libchrome]
4 cc_defaults update_metadata-protos_exports [shared_libs : libprotobuf-cpp-lite]
5 cc_defaults libpayload_consumer_exports [defaults : update_metadata-protos_exports] [static_libs : update_metadata-protos, libxz, libbz, libbspatch, libbrotli, libfec_rs, libpuffpatch, libverity_tree] [shared_libs : libbase, libcrypto, libfec]
6 cc_defaults libupdate_engine_boot_control_exports [defaults : update_metadata-protos_exports] [static_libs : update_metadata-protos] [shared_libs : libbootloader_message, libfs_mgr, libhwbinder, libhidlbase, liblp, libutils, [email protected]]
7 cc_defaults libupdate_engine_android_exports [defaults : ue_defaults, libpayload_consumer_exports, libupdate_engine_boot_control_exports] [static_libs : libpayload_consumer, libupdate_engine_boot_control] [shared_libs : libandroid_net, libbase, libbinder, libbinderwrapper, libbootloader_message, libbrillo-binder, libcurl, libcutils, liblog, libmetricslogger, libssl, libutils]
8 cc_defaults libpayload_generator_exports [defaults : libpayload_consumer_exports, update_metadata-protos_exports] [static_libs : libavb, libbrotli, libbsdiff, libdivsufsort, libdivsufsort64, liblzmaliblzma, libpayload_consumer, libpuffdiff, libverity_tree, update_metadata-protos] [shared_libs : libbase, libext2fs]
9 cc_library_static update_metadata-protos
10 cc_library_static libpayload_consumer [defaults : ue_defaults, libpayload_consumer_exports]
11 cc_library_static libupdate_engine_boot_control [defaults : ue_defaults, libupdate_engine_boot_control_exports]
12 cc_library_static libupdate_engine_android [defaults : ue_defaults, libupdate_engine_android_exports]
13 cc_library_static libpayload_generator [defaults : ue_defaults, libpayload_generator_exports]
14 cc_library_shared libupdate_engine_client [shared_libs : libchrome, libbrillo, libbinder, libbrillo-binder, libutils]
15 cc_binary update_engine [defaults : ue_defaults, libupdate_engine_android_exports]
16 cc_binary update_engine_sideload [defaults : ue_defaults, update_metadata-protos_exports, libupdate_engine_boot_control_exports, libpayload_consumer_exports] [shared_libs : libbase, liblog] [static_libs : libpayload_consumer, libupdate_engine_boot_control, update_metadata-protos, libevent, libmodpb64, libgtest_prod, libprotobuf-cpp-lite, libbrillo-stream, libbrillo, libchrome]
17 cc_binary update_engine_client [defaults : ue_defaults] [shared_libs : libbinder, libbinderwrapper, libbrillo-binder, libutils]
18 cc_binary_host delta_generator [defaults : ue_defaults, libpayload_generator_exports, libpayload_consumer_exports] [static_libs : libavb_host_sysdeps, libpayload_consumer, libpayload_generator]
19 cc_test ue_unittest_delta_generator [defaults : ue_defaults, libpayload_generator_exports, libpayload_consumer_exports] [static_libs : libpayload_consumer, libpayload_generator]
20 cc_test test_http_server [defaults : ue_defaults]
21 cc_test test_subprocess [defaults : ue_defaults]
22 cc_test update_engine_unittests [defaults : ue_defaults, libpayload_generator_exports, libupdate_engine_android_exports] [static_libs : libpayload_generator, libbrillo-test-helpers, libgmock, libchrome_test_helpers, libupdate_engine_android] [shared_libs : libhidltransport]
23 genrule ue_unittest_keys
24 genrule ue_unittest_disk_imgs
25 cc_prebuilt_binary brillo_update_payload

1.3 UpdateEngine编译文件

//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// AIDL interface between libupdate_engine and framework.jar
filegroup {
    name: "libupdate_engine_aidl",
    srcs: [
        "binder_bindings/android/os/IUpdateEngine.aidl",
        "binder_bindings/android/os/IUpdateEngineCallback.aidl",
    ],
    path: "binder_bindings",
}

cc_defaults {
    name: "ue_defaults",

    cflags: [
        "-DBASE_VER=576279",
        "-DUSE_BINDER=1",
        "-DUSE_CHROME_NETWORK_PROXY=0",
        "-DUSE_CHROME_KIOSK_APP=0",
        "-DUSE_HWID_OVERRIDE=0",
        "-DUSE_MTD=0",
        "-DUSE_OMAHA=0",
        "-D_FILE_OFFSET_BITS=64",
        "-D_POSIX_C_SOURCE=199309L",
        "-Wa,--noexecstack",
        "-Wall",
        "-Werror",
        "-Wextra",
        "-Wformat=2",
        "-Wno-psabi",
        "-Wno-unused-parameter",
        "-ffunction-sections",
        "-fstack-protector-strong",
        "-fvisibility=hidden",
    ],
    cppflags: [
        "-Wnon-virtual-dtor",
        "-fno-strict-aliasing",
    ],
    include_dirs: ["system"],
    local_include_dirs: ["client_library/include"],
    static_libs: ["libgtest_prod"],
    shared_libs: [
        "libbrillo-stream",
        "libbrillo",
        "libchrome",
    ],
    ldflags: ["-Wl,--gc-sections"],

    product_variables: {
        pdk: {
            enabled: false,
        },
    },

    target: {
        android: {
            cflags: [
                "-DUSE_FEC=1",
            ],
        },
        host: {
            cflags: [
                "-DUSE_FEC=0",
            ],
        },
        darwin: {
            enabled: false,
        },
    },
}

// update_metadata-protos (type: static_library)
// ========================================================
// Protobufs.
cc_defaults {
    name: "update_metadata-protos_exports",

    shared_libs: ["libprotobuf-cpp-lite"],
}

cc_library_static {
    name: "update_metadata-protos",
    host_supported: true,
    recovery_available: true,

    srcs: ["update_engine/update_metadata.proto"],
    cflags: [
        "-Wall",
        "-Werror",
    ],
    proto: {
        canonical_path_from_root: false,
        export_proto_headers: true,
    },
}

// libpayload_consumer (type: static_library)
// ========================================================
// The payload application component and common dependencies.
cc_defaults {
    name: "libpayload_consumer_exports",
    defaults: ["update_metadata-protos_exports"],

    static_libs: [
        "update_metadata-protos",
        "libxz",
        "libbz",
        "libbspatch",
        "libbrotli",
        "libfec_rs",
        "libpuffpatch",
        "libverity_tree",
    ],
    shared_libs: [
        "libbase",
        "libcrypto",
        "libfec",
    ],
}

cc_library_static {
    name: "libpayload_consumer",
    defaults: [
        "ue_defaults",
        "libpayload_consumer_exports",
    ],
    host_supported: true,
    recovery_available: true,

    srcs: [
        "common/action_processor.cc",
        "common/boot_control_stub.cc",
        "common/clock.cc",
        "common/constants.cc",
        "common/cpu_limiter.cc",
        "common/error_code_utils.cc",
        "common/file_fetcher.cc",
        "common/hash_calculator.cc",
        "common/http_common.cc",
        "common/http_fetcher.cc",
        "common/hwid_override.cc",
        "common/multi_range_http_fetcher.cc",
        "common/platform_constants_android.cc",
        "common/prefs.cc",
        "common/proxy_resolver.cc",
        "common/subprocess.cc",
        "common/terminator.cc",
        "common/utils.cc",
        "payload_consumer/bzip_extent_writer.cc",
        "payload_consumer/cached_file_descriptor.cc",
        "payload_consumer/delta_performer.cc",
        "payload_consumer/download_action.cc",
        "payload_consumer/extent_reader.cc",
        "payload_consumer/extent_writer.cc",
        "payload_consumer/file_descriptor.cc",
        "payload_consumer/file_descriptor_utils.cc",
        "payload_consumer/file_writer.cc",
        "payload_consumer/filesystem_verifier_action.cc",
        "payload_consumer/install_plan.cc",
        "payload_consumer/mount_history.cc",
        "payload_consumer/payload_constants.cc",
        "payload_consumer/payload_metadata.cc",
        "payload_consumer/payload_verifier.cc",
        "payload_consumer/postinstall_runner_action.cc",
        "payload_consumer/verity_writer_android.cc",
        "payload_consumer/xz_extent_writer.cc",
        "payload_consumer/fec_file_descriptor.cc",
    ],
}

// libupdate_engine_boot_control (type: static_library)
// ========================================================
// A BootControl class implementation using Android's HIDL boot_control HAL.
cc_defaults {
    name: "libupdate_engine_boot_control_exports",
    defaults: ["update_metadata-protos_exports"],

    static_libs: ["update_metadata-protos"],
    shared_libs: [
        "libbootloader_message",
        "libfs_mgr",
        "libhwbinder",
        "libhidlbase",
        "liblp",
        "libutils",
        "[email protected]",
    ],
}

cc_library_static {
    name: "libupdate_engine_boot_control",
    defaults: [
        "ue_defaults",
        "libupdate_engine_boot_control_exports",
    ],
    recovery_available: true,

    srcs: [
        "boot_control_android.cc",
        "dynamic_partition_control_android.cc",
    ],
}

// libupdate_engine_android (type: static_library)
// ========================================================
// The main daemon static_library used in Android (non-Brillo). This only has a
// loop to apply payloads provided by the upper layer via a Binder interface.
cc_defaults {
    name: "libupdate_engine_android_exports",
    defaults: [
        "ue_defaults",
        "libpayload_consumer_exports",
        "libupdate_engine_boot_control_exports",
    ],

    static_libs: [
        "libpayload_consumer",
        "libupdate_engine_boot_control",
    ],
    shared_libs: [
        "libandroid_net",
        "libbase",
        "libbinder",
        "libbinderwrapper",
        "libbootloader_message",
        "libbrillo-binder",
        "libcurl",
        "libcutils",
        "liblog",
        "libmetricslogger",
        "libssl",
        "libutils",
    ],
}

cc_library_static {
    name: "libupdate_engine_android",
    defaults: [
        "ue_defaults",
        "libupdate_engine_android_exports",
    ],

    // TODO(deymo): Remove external/cros/system_api/dbus once the strings are moved
    // out of the DBus interface.
    include_dirs: ["external/cros/system_api/dbus"],

    aidl: {
        local_include_dirs: ["binder_bindings"],
        export_aidl_headers: true,
    },

    srcs: [
        ":libupdate_engine_aidl",
        "binder_service_android.cc",
        "certificate_checker.cc",
        "daemon.cc",
        "daemon_state_android.cc",
        "hardware_android.cc",
        "libcurl_http_fetcher.cc",
        "metrics_reporter_android.cc",
        "metrics_utils.cc",
        "network_selector_android.cc",
        "update_attempter_android.cc",
        "update_boot_flags_action.cc",
        "update_status_utils.cc",
    ],
}

// update_engine (type: executable)
// ========================================================
// update_engine daemon.
cc_binary {
    name: "update_engine",
    defaults: [
        "ue_defaults",
        "libupdate_engine_android_exports",
    ],

    static_libs: ["libupdate_engine_android"],
    required: ["cacerts_google"],

    srcs: ["main.cc"],
    init_rc: ["update_engine.rc"],
}

// update_engine_sideload (type: executable)
// ========================================================
// A binary executable equivalent to update_engine daemon that installs an update
// from a local file directly instead of running in the background. Used in
// recovery image.
cc_binary {
    name: "update_engine_sideload",
    defaults: [
        "ue_defaults",
        "update_metadata-protos_exports",
        "libupdate_engine_boot_control_exports",
        "libpayload_consumer_exports",
    ],
    recovery: true,

    cflags: ["-D_UE_SIDELOAD"],
    // TODO(deymo): Remove external/cros/system_api/dbus once the strings are moved
    // out of the DBus interface.
    include_dirs: ["external/cros/system_api/dbus"],

    srcs: [
        "hardware_android.cc",
        "metrics_reporter_stub.cc",
        "metrics_utils.cc",
        "network_selector_stub.cc",
        "sideload_main.cc",
        "update_attempter_android.cc",
        "update_boot_flags_action.cc",
        "update_status_utils.cc",
    ],

    // Use commonly used shared libraries. libprotobuf-cpp-lite.so is filtered out,
    // as it doesn't look beneficial to be installed separately due to its size. Note
    // that we explicitly request their recovery variants, so that the expected files
    // will be used and installed.
    shared_libs: [
        "libbase",
        "liblog",
    ],
    static_libs: [
        "libpayload_consumer",
        "libupdate_engine_boot_control",
        "update_metadata-protos",

        // We add the static versions of the shared libraries that are not installed to
        // recovery image due to size concerns. Need to include all the static library
        // dependencies of these static libraries.
        "libevent",
        "libmodpb64",
        "libgtest_prod",
        "libprotobuf-cpp-lite",
        "libbrillo-stream",
        "libbrillo",
        "libchrome",
    ],
    target: {
        recovery: {
            exclude_shared_libs: [
                "libprotobuf-cpp-lite",
                "libhwbinder",
                "libbrillo-stream",
                "libbrillo",
                "libchrome",
            ],
        },
    },

    required: ["[email protected]"],
}

// libupdate_engine_client (type: shared_library)
// ========================================================
cc_library_shared {
    name: "libupdate_engine_client",

    cflags: [
        "-Wall",
        "-Werror",
        "-Wno-unused-parameter",
        "-DUSE_BINDER=1",
    ],
    export_include_dirs: ["client_library/include"],
    include_dirs: [
        // TODO(deymo): Remove "external/cros/system_api/dbus" when dbus is not used.
        "external/cros/system_api/dbus",
        "system",
    ],

    aidl: {
        local_include_dirs: ["binder_bindings"],
    },

    shared_libs: [
        "libchrome",
        "libbrillo",
        "libbinder",
        "libbrillo-binder",
        "libutils",
    ],

    srcs: [
        "binder_bindings/android/brillo/IUpdateEngine.aidl",
        "binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl",
        "client_library/client.cc",
        "client_library/client_binder.cc",
        "parcelable_update_engine_status.cc",
        "update_status_utils.cc",
    ],
}

// update_engine_client (type: executable)
// ========================================================
// update_engine console client.
cc_binary {
    name: "update_engine_client",
    defaults: ["ue_defaults"],

    // TODO(deymo): Remove external/cros/system_api/dbus once the strings are moved
    // out of the DBus interface.
    include_dirs: ["external/cros/system_api/dbus"],

    shared_libs: [
        "libbinder",
        "libbinderwrapper",
        "libbrillo-binder",
        "libutils",
    ],

    aidl: {
        local_include_dirs: ["binder_bindings"],
    },

    srcs: [
        ":libupdate_engine_aidl",
        "common/error_code_utils.cc",
        "update_engine_client_android.cc",
        "update_status_utils.cc",
    ],
}

// libpayload_generator (type: static_library)
// ========================================================
// server-side code. This is used for delta_generator and unittests but not
// for any client code.
cc_defaults {
    name: "libpayload_generator_exports",
    defaults: [
        "libpayload_consumer_exports",
        "update_metadata-protos_exports",
    ],

    static_libs: [
        "libavb",
        "libbrotli",
        "libbsdiff",
        "libdivsufsort",
        "libdivsufsort64",
        "liblzma",
        "libpayload_consumer",
        "libpuffdiff",
        "libverity_tree",
        "update_metadata-protos",
    ],
    shared_libs: [
        "libbase",
        "libext2fs",
    ],
}

cc_library_static {
    name: "libpayload_generator",
    defaults: [
        "ue_defaults",
        "libpayload_generator_exports",
    ],
    host_supported: true,

    srcs: [
        "payload_generator/ab_generator.cc",
        "payload_generator/annotated_operation.cc",
        "payload_generator/blob_file_writer.cc",
        "payload_generator/block_mapping.cc",
        "payload_generator/boot_img_filesystem.cc",
        "payload_generator/bzip.cc",
        "payload_generator/cycle_breaker.cc",
        "payload_generator/deflate_utils.cc",
        "payload_generator/delta_diff_generator.cc",
        "payload_generator/delta_diff_utils.cc",
        "payload_generator/ext2_filesystem.cc",
        "payload_generator/extent_ranges.cc",
        "payload_generator/extent_utils.cc",
        "payload_generator/full_update_generator.cc",
        "payload_generator/graph_types.cc",
        "payload_generator/graph_utils.cc",
        "payload_generator/inplace_generator.cc",
        "payload_generator/mapfile_filesystem.cc",
        "payload_generator/payload_file.cc",
        "payload_generator/payload_generation_config_android.cc",
        "payload_generator/payload_generation_config.cc",
        "payload_generator/payload_signer.cc",
        "payload_generator/raw_filesystem.cc",
        "payload_generator/squashfs_filesystem.cc",
        "payload_generator/tarjan.cc",
        "payload_generator/topological_sort.cc",
        "payload_generator/xz_android.cc",
    ],
}

// delta_generator (type: executable)
// ========================================================
// server-side delta generator.
cc_binary_host {
    name: "delta_generator",
    defaults: [
        "ue_defaults",
        "libpayload_generator_exports",
        "libpayload_consumer_exports",
    ],

    static_libs: [
        "libavb_host_sysdeps",
        "libpayload_consumer",
        "libpayload_generator",
    ],

    srcs: ["payload_generator/generate_delta_main.cc"],
}

cc_test {
    name: "ue_unittest_delta_generator",
    defaults: [
        "ue_defaults",
        "libpayload_generator_exports",
        "libpayload_consumer_exports",
    ],

    static_libs: [
        "libpayload_consumer",
        "libpayload_generator",
    ],

    srcs: ["payload_generator/generate_delta_main.cc"],

    gtest: false,
    stem: "delta_generator",
    relative_install_path: "update_engine_unittests",
    no_named_install_directory: true,
}

// test_http_server (type: executable)
// ========================================================
// Test HTTP Server.
cc_test {
    name: "test_http_server",
    defaults: ["ue_defaults"],
    srcs: [
        "common/http_common.cc",
        "test_http_server.cc",
    ],

    gtest: false,
    relative_install_path: "update_engine_unittests",
    no_named_install_directory: true,
}

// test_subprocess (type: executable)
// ========================================================
// Test helper subprocess program.
cc_test {
    name: "test_subprocess",
    defaults: ["ue_defaults"],
    srcs: ["test_subprocess.cc"],

    gtest: false,
    relative_install_path: "update_engine_unittests",
    no_named_install_directory: true,
}

// Public keys for unittests.
// ========================================================
genrule {
    name: "ue_unittest_keys",
    cmd: "openssl rsa -in $(location unittest_key.pem) -pubout -out $(location unittest_key.pub.pem) &&" +
        "openssl rsa -in $(location unittest_key2.pem) -pubout -out $(location unittest_key2.pub.pem) &&" +
        "openssl rsa -in $(location unittest_key_RSA4096.pem) -pubout -out $(location unittest_key_RSA4096.pub.pem)",
    srcs: [
        "unittest_key.pem",
        "unittest_key2.pem",
        "unittest_key_RSA4096.pem",
    ],
    out: [
        "unittest_key.pub.pem",
        "unittest_key2.pub.pem",
        "unittest_key_RSA4096.pub.pem",
    ],
}

// Sample images for unittests.
// ========================================================
// Extract sample image from the compressed sample_images.tar.bz2 file used by
// the unittests.
genrule {
    name: "ue_unittest_disk_imgs",
    cmd: "tar -jxf $(in) -C $(genDir)/gen disk_ext2_1k.img disk_ext2_4k.img disk_ext2_4k_empty.img disk_ext2_unittest.img",
    srcs: ["sample_images/sample_images.tar.bz2"],
    out: [
        "gen/disk_ext2_1k.img",
        "gen/disk_ext2_4k.img",
        "gen/disk_ext2_4k_empty.img",
        "gen/disk_ext2_unittest.img",
    ],
}

// update_engine_unittests (type: executable)
// ========================================================
// Main unittest file.
cc_test {
    name: "update_engine_unittests",
    defaults: [
        "ue_defaults",
        "libpayload_generator_exports",
        "libupdate_engine_android_exports",
    ],
    required: [
        "test_http_server",
        "test_subprocess",
        "ue_unittest_delta_generator",
    ],

    static_libs: [
        "libpayload_generator",
        "libbrillo-test-helpers",
        "libgmock",
        "libchrome_test_helpers",
        "libupdate_engine_android",
    ],
    shared_libs: [
        "libhidltransport",
    ],

    data: [
        ":ue_unittest_disk_imgs",
        ":ue_unittest_keys",
        "unittest_key.pem",
        "unittest_key2.pem",
        "unittest_key_RSA4096.pem",
        "update_engine.conf",
    ],

    srcs: [
        "boot_control_android_unittest.cc",
        "certificate_checker_unittest.cc",
        "common/action_pipe_unittest.cc",
        "common/action_processor_unittest.cc",
        "common/action_unittest.cc",
        "common/cpu_limiter_unittest.cc",
        "common/fake_prefs.cc",
        "common/file_fetcher_unittest.cc",
        "common/hash_calculator_unittest.cc",
        "common/http_fetcher_unittest.cc",
        "common/hwid_override_unittest.cc",
        "common/mock_http_fetcher.cc",
        "common/prefs_unittest.cc",
        "common/proxy_resolver_unittest.cc",
        "common/subprocess_unittest.cc",
        "common/terminator_unittest.cc",
        "common/test_utils.cc",
        "common/utils_unittest.cc",
        "payload_consumer/bzip_extent_writer_unittest.cc",
        "payload_consumer/cached_file_descriptor_unittest.cc",
        "payload_consumer/delta_performer_integration_test.cc",
        "payload_consumer/delta_performer_unittest.cc",
        "payload_consumer/extent_reader_unittest.cc",
        "payload_consumer/extent_writer_unittest.cc",
        "payload_consumer/fake_file_descriptor.cc",
        "payload_consumer/file_descriptor_utils_unittest.cc",
        "payload_consumer/file_writer_unittest.cc",
        "payload_consumer/filesystem_verifier_action_unittest.cc",
        "payload_consumer/postinstall_runner_action_unittest.cc",
        "payload_consumer/verity_writer_android_unittest.cc",
        "payload_consumer/xz_extent_writer_unittest.cc",
        "payload_generator/ab_generator_unittest.cc",
        "payload_generator/blob_file_writer_unittest.cc",
        "payload_generator/block_mapping_unittest.cc",
        "payload_generator/boot_img_filesystem_unittest.cc",
        "payload_generator/cycle_breaker_unittest.cc",
        "payload_generator/deflate_utils_unittest.cc",
        "payload_generator/delta_diff_utils_unittest.cc",
        "payload_generator/ext2_filesystem_unittest.cc",
        "payload_generator/extent_ranges_unittest.cc",
        "payload_generator/extent_utils_unittest.cc",
        "payload_generator/fake_filesystem.cc",
        "payload_generator/full_update_generator_unittest.cc",
        "payload_generator/graph_utils_unittest.cc",
        "payload_generator/inplace_generator_unittest.cc",
        "payload_generator/mapfile_filesystem_unittest.cc",
        "payload_generator/payload_file_unittest.cc",
        "payload_generator/payload_generation_config_android_unittest.cc",
        "payload_generator/payload_generation_config_unittest.cc",
        "payload_generator/payload_signer_unittest.cc",
        "payload_generator/squashfs_filesystem_unittest.cc",
        "payload_generator/tarjan_unittest.cc",
        "payload_generator/topological_sort_unittest.cc",
        "payload_generator/zip_unittest.cc",
        "testrunner.cc",
        "update_attempter_android_unittest.cc",
    ],
}

// Brillo update payload generation script
// ========================================================
cc_prebuilt_binary {
    name: "brillo_update_payload",
    device_supported: false,
    host_supported: true,

    srcs: ["scripts/brillo_update_payload"],
    required: [
        "delta_generator",
        "shflags",
        "simg2img",
    ],

    target: {
        darwin: {
            enabled: false,
        },
    },
}

// AIDL interface between libupdate_engine and the Things jar.
filegroup {
    name: "things_update_engine_aidl",
    srcs: [
        "binder_bindings/android/brillo/IUpdateEngine.aidl",
        "binder_bindings/android/brillo/IUpdateEngineStatusCallback.aidl",
    ],
}

2、编译模块分析

2.1 filegroup

filegroup 在 BluePrint 文件格式中的编译表示一个 文件组,是功能相对独立的一组源文件集合,可供编译目标 srcs 直接使用。

2.1.1 libupdate_engine_aidl

libupdate_engine_aidl文件组,包含两个源码文件:IUpdateEngine.aidl、IUpdateEngineCallback.aidl。这两个 aidl 文件都在 system/update_engine/binder_bindings/android/os 目录下,是 update_engine 模块的 aidl 文件,上层 UpdateEngine.java 文件通过这里定义的 aidl 接口连接 Framework 与 Hal。提供了升级触发、升级进度、升级结果等功能。

2.1.2 things_update_engine_aidl

things_update_engine_aidl文件组,包含两个源码文件:IUpdateEngine.aidl、IUpdateEngineStatusCallback.aidl。这两个 aidl 文件都在 binder_bindings/android/brillo 目录下,这两个 aidl 文件同样也是定义上层 aidl 服务接口,不过在 Android.bp 文件中仅定义了这个文件组,并没有使用,且上层使用的是 libupdate_engine_aidl 文件组中的 aidl 接口提供功能的,因此这个 文件组是没有提供实际功能的。

2.2 cc_defaults

默认模块,soong提供了一系列 xx_defaults 模块类型,例如:cc_defaults, java_defaults, doc_defaults, stub_defaults等等。模块类型为 xx_defaults 的模块提供了一组可由其他模块集成的属性。其他模块可以通过添加属性 ‘defaults : [“<: default_module_name>”]’ 来指定继承 xx_defaults 类型的模块定义的属性。

2.2.1 ue_defaults

ue_defaults 模块,模块中定义了一些 编译宏,代码中用 宏 控制区分,例如:USE_BINDER=1、USE_OMAHA=0 等在代码中均有编译控制。模块包含头文件目录client_library/include,目录下 client.h 文件定义类 UpdateEngineClient,对应 udpate_engine_client.cc 文件。

2.2.2 update_metadata-protos_exports

update_metadata-protos_exports 模块,其中仅包含了动态库 libprotobuf-cpp-lite。libprotobuf-cpp-lite 是一个 动态库,其定义在路径 android/external/protobuf 路径下。此动态库的作用是将 proto 文件转换成 cpp 格式文件。Protobuf 官方实现了一门语言,专门用来自定义数据结构。protoc 是这门语言的编译工具,额可以编译生成指定编程语言,如 c++、java、golang、python、c#等源码,开发者可以轻松在这些语言中使用该源代码进行编程。

在 UpdateEngine 模块中有两个 proto 文件:update_metadata.proto、update_engine/update_metadata.proto。两个同名文件,从 Android.bp 中确认在编译 update_metadata-protos 静态库时引用了 update_engine/update_metadata.proto 文件,至于 update_metadata.proto 文件在 Android.bp 中没有使用。

2.2.3 libpayload_consumer_exports

libpayload_consumer_exports 模块,引用了 update_metadata-protos_exports 模块,update_metadata-protos 静态库等。

2.2.4 libupdate_engine_boot_control_exports

libupdate_engine_boot_control_exports 模块,引用了 update_metadata-protos_exports 模块,update_metadata-protos 静态库,[email protected] 动态库等。作用是用以实现 Android 中的 boot_control HIDL 模块的功能,这个模块应用在 静态库 libupdate_engine_boot_control 中,编译出带有 boot_control 功能的静态库。

[email protected] 是原生定义的功能接口,并没有提供具体实现,各个厂商可以根据此功能接口,自定义其存储和功能实现,功能接口文件定义在 “android/hardware/interfaces/boot/1.0” 下,从代码中搜索发现,AOSP 代码中包含三个平台的 boot_control 实现。分别是:Google 平台的 Brillo、Inter 平台的 edison、QualComm。

2.2.5 libupdate_engine_android_exports

libupdate_engine_android_exports 模块,引用了ue_defaults、libpayload_consumer_exports、libupdate_engine_boot_control_exports 模块,libpayload_consumer、libupdate_engine_boot_control 静态库。这个模块主要用在 静态库libupdate_engine_android 中,是 update_engine 模块的主要功能模块,在主进程中运行的主要功能来自 libupdate_engine_android 静态库。

2.2.6 libpayload_generator_exports

libpayload_generator_exports 模块,引用了libpayload_consumer_exports、update_metadata-protos_exports 模块,update_metadata-protos 静态库。这个模块主要用在 静态库 libpayload_generator 中,主要是用于 delta_generator 和 ue_unittest_delta_generator 单元测试中。

2.3 cc_library_static

静态库,静态库实际就是一些目标文件(一般是 .o 文件)的集合,静态库文件以 .a 结尾,只用于生成可执行文件阶段。在链接步骤中,连接器将从库文件中取得的所有代码,复制到生成的可执行文件中,这种库称为静态库。特点是可执行文件中包含了库代码的一份完整的拷贝,在编译过程中被载入到应用程序中。缺点是多次使用就会有多份冗余拷贝,并且对程序的更新、部署和发布带来麻烦,如果静态库有更新,那么多有使用它的程序都需要重新编译、发布。

2.3.1 update_metadata-protos

update_metadata-protos 静态库,引用了 update_engine/update_metadata.proto 文件,静态库提供了将 proto 格式文件转换语言的功能。

2.3.2 libpayload_consumer

libpayload_consumer 静态库,引用了 ue_defaults、libpayload_consumer_exports 模块,包含文件大部分为升级过程中所需要的流程文件,应该是封装了升级的部分功能,包括数据验证、下载、读写等操作。与升级具体逻辑步骤相关。

2.3.3 libupdate_engine_boot_control

libupdate_engine_boot_control 静态库,引用了 ue_defaults、libupdate_engine_boot_control_exports 模块,包含了 boot_control_android.cc、dynamic_partition_control_android.cc 文件,静态库提供了 Android boot_control 功能,主要控制系统的启动分区、分区切换等、像是升级后ab分区的状态控制,切换启动控制等。关于 Android 的 BootControl 服务,其 Hal 文件位于 android/hardware/interfaces/boot/1.0 路径下,此路径下实现了 Android 的 BootControl 服务。

2.3.4 libupdate_engine_android

libupdate_engine_android 静态库,引用了 ue_defaults、libupdate_engine_android_exports 模块,libupdate_engine_aidl 文件组,静态库主要提供了 UpdateEngine 模块的 Binder 服务功能。

2.3.5 libpayload_generator

libpayload_generator 静态库,引用了 libpayload_consumer_exports、update_metadata-protos_exports 模块,包含文件主要集中在 payload_generator 路径下,主要用于 delta_generator 编译和 cc_test 单元测试。

2.4 cc_library_shared

动态库,动态库在链接阶段没有被复制到程序中,而是在程序运行时,由系统动态加载到内存中提供程序使用。系统中只需要载入一次动态库,不同的程序可以得到内存中相同的动态库副本,因此节省了很多内存。

动态库与静态库的区别

A:命名上,静态库文件名的命名方式是”libxxx.a“,库名前加”lib“,后缀用”.a“,”xxx“为静态库名;动态库的命名方式与静态库类似,前缀相同为”lib“,后缀为”.so“。

B:链接上,静态库的代码是在编译过程中被载入程序的;动态库在编译的时候并没有被编译进目标代码,而是当你的程序执行到相关函数时才调用到该函数库里的相应函数。

C:更新上,如果所使用的静态库发生更新改变,你的程序必须重新编译;动态库的改变并不影响你的程序,动态函数库升级比较方便。

D:内存上,静态库每一次编译都需要编译静态库代码,内存开销大;系统只需载入一次动态库,不同的程序可以得到内存中相同动态库的副本,内存开销小。

当同一个程序分别使用静态库,动态库两种方式生成两个可执行文件时,静态链接所生成的文件所占用的内存要远远大于动态链接所生成的文件;静态库和程序链接有关和程序运行无关;动态库和程序链接无关和程序运行有关。

2.4.1 libupdate_engine_client

libupdate_engine_client 动态库,包含了 binder_bindings/android/brillo 路径下的两个 aidl 文件 IUpdateEngine.aidl 和 IUpdateEngineStatusCallback.aidl,client_library 路径下的 client.cc 和 client_binder.cc,parcelable_update_engine_status.cc 文件和 update_status_utils.cc 文件。应该是提供了 UpdateEngine 模块 client 客户端的相关功能。

2.5 cc_binary_host

主机可执行文件

2.5.1 delta_generator

delta_generator 文件,引用了 ue_defaults、libpayload_generator_exports、libpayload_consumer_exports 模块,libavb_host_sysdeps、libpayload_consumer、libpayload_generator 静态库,payload_generator/generate_delta_main.cc 文件。可能是提供了 UpdateEngine 服务端的 增量 升级相关的功能。

2.6 cc_binary

可执行文件,Android 编译中生成可执行文件,基本代表了一个模块在 Android 编译系统中的产出形式,在启动过程中,系统会通过可执行文件启动一个模块从而提供模块服务。

2.6.1 update_engine

update_engine 文件,引用了 ue_defaults、libupdate_engine_android_exports 模块,libupdate_engine_android 静态库。提供了 update_engine 整体服务,是系统 update_engine 模块启动的入口。

2.6.2 update_engine_sideload

update_engine_sideload 文件,引用了 ue_defaults、update_metadata-protos_exports、libupdate_engine_boot_control_exports、libpayload_consumer_exports 模块,libpayload_consumer、libupdate_engine_boot_control、update_metadata-protos、libprotobuf-cpp-lite 静态库。update_engine_sideload文件是一个等同于 update_engine 模块文件守护程序的静态二进制文件,用于直接从本地文件进行安装更新。update_engine 是在后台进行。通过 update_engine_sideload 方式进行更新是指使用非系统接口渠道更新,例如使用 adb 工具从本地安装包中安装更新。使用 update_engine_sideload 方式更新系统时,需要设备已经解锁并已启用开发者选项,并且需要有足够的空间存储更新包,若更新不成功,则可能存在网络问题、安装包不完整、系统版本不兼容等原因。

2.6.3 update_engine_client

update_engine_client 文件,引用了 ue_defaults 模块,libupdate_engine_aidl 文件组。update_engine_client 是一个可以用来进行命令行升级的功能文件,当进行系统AB升级的时候,有两种方式可以实现,一种是通过应用层调用 UpdateEngine 的 applyPayload 方法来升级;另一种方式就是直接执行 shell 命令,调用 update_engine_client 模块带参数来实现升级。

update_engine_client 带参升级

update_engine_client 带参升级的 shell 命令具体如下:

update_engine_client --payload=file:///sdcard/payload.bin --update -- headers="FILE_HASH=qeebzpLK4f/FaDAVJ9ilCxnUC/TMO16S5QP39AjsYKc=
FILE_SIZE=445814087
METADATA_HASH=nn9V2c3dQ3yHwQQJW0R0Q+y+OQzWuJ5FZt4HxCiAry0=
METADATA_SIZE=58898"

具体格式:update_engine_client --payload + 文件路径 --update --headers + 参数

2.7 cc_test

本地测试,是基于 Google 测试框架的单元测试。

2.7.1 ue_unittest_delta_generator

ue_unittest_delta_generator 测试,引用了 ue_defaults、libpayload_generator_exports、libpayload_consumer_exports 模块,libpayload_consumer、libpayload_generator 静态库,测试文件是 payload_generator/generate_delta_main.cc。测试模块应该是对 delta 增量升级相关服务的测试。可以基于 generate_delta_main.cc 测试代码进行分析。

2.7.2 test_http_server

test_http_server 测试,引用了 ue_defaults 模块,测试文件包括 common/http_common.cc、test_http_server.cc。测试模块应该是对 Http 服务相关功能的测试,例如测试 Http 网络下载的功能功能、测试更新程序是否可以在连接断开时继续连接、或者处理传输过慢的情况。

2.7.3 test_subprocess

test_subprocess 测试,引用了 ue_defaults 模块,测试文件包括 test_subprocess.cc。测试模块应该是测试 其他模块 与 UpdateEngine 的交互,预置一些指令,并按顺序执行。

2.7.4 update_engine_unittests

update_engine_unittests 测试,引用了 ue_defaults、libpayload_generator_exports、libupdate_engine_android_exports 模块,libpayload_generator、libupdate_engine_android 静态库,测试文件包括文件目录下的 unittest 文件。测试模块是对 UpdateEngine 模块进行测试。

2.8 genrule

规则文件。

2.8.1 ue_unittest_keys

ue_unittest_keys,包含了单元测试中所需要的公钥文件。

2.8.2 ue_unittest_disk_imgs

ue_unittest_disk_imgs,从单元测试中使用的压缩 sample_images.tar.bz2 文件中提取 img。

2.9 cc_prebuilt_binary

预编译可执行文件。

2.9.1 brillo_update_payload

库,测试文件是 payload_generator/generate_delta_main.cc。测试模块应该是对 delta 增量升级相关服务的测试。可以基于 generate_delta_main.cc 测试代码进行分析。

2.7.2 test_http_server

test_http_server 测试,引用了 ue_defaults 模块,测试文件包括 common/http_common.cc、test_http_server.cc。测试模块应该是对 Http 服务相关功能的测试,例如测试 Http 网络下载的功能功能、测试更新程序是否可以在连接断开时继续连接、或者处理传输过慢的情况。

2.7.3 test_subprocess

test_subprocess 测试,引用了 ue_defaults 模块,测试文件包括 test_subprocess.cc。测试模块应该是测试 其他模块 与 UpdateEngine 的交互,预置一些指令,并按顺序执行。

2.7.4 update_engine_unittests

update_engine_unittests 测试,引用了 ue_defaults、libpayload_generator_exports、libupdate_engine_android_exports 模块,libpayload_generator、libupdate_engine_android 静态库,测试文件包括文件目录下的 unittest 文件。测试模块是对 UpdateEngine 模块进行测试。

2.8 genrule

规则文件。

2.8.1 ue_unittest_keys

ue_unittest_keys,包含了单元测试中所需要的公钥文件。

2.8.2 ue_unittest_disk_imgs

ue_unittest_disk_imgs,从单元测试中使用的压缩 sample_images.tar.bz2 文件中提取 img。

2.9 cc_prebuilt_binary

预编译可执行文件。

2.9.1 brillo_update_payload

brillo_update_payload 文件,文件包含一个 shell 脚本 scripts/brillo_update_payload,并且依赖 delta_generator、shflags、simg2img 工具。编译复制脚本 brillo_update_payload 到 host 下面,制作差分包会使用到。

下一篇:Android UpdateEngine 模块分析(二)UpdateEngine 服务启动

猜你喜欢

转载自blog.csdn.net/Yang_Mao_Shan/article/details/131637138