Triển khai dịch vụ

Để chuẩn bị cho việc triển khai HAL, bạn có thể tạo mã giao diện ConfigStore cơ bản, sau đó sửa đổi mã đó để đáp ứng nhu cầu của mình.

Tạo mã giao diện

Để tạo mã nguyên mẫu cho giao diện này, hãy chạy hidl-gen. Ví dụ: để tạo mã cho surfaceflinger:

hidl-gen -o hardware/interfaces/configstore/1.0/default \
    -Lc++-impl \
    -randroid.hardware:hardware/interfaces \
    -randroid.hidl:system/libhidl/transport \
    android.hardware.config@1.0::ISurfaceFlingerConfigs

Sửa đổi Android.mk

Tiếp theo, hãy sửa đổi tệp Android.mk để thêm tệp triển khai (<modulename>Configs.cpp) vào LOCAL_SRC_FILES và ánh xạ cờ bản dựng vào các định nghĩa macro. Ví dụ: bạn có thể sửa đổi surfaceflinger trong hardware/interface/configstore/1.0/default/Android.mk:

LOCAL_SRC_FILES += SurfaceFlingerConfigs.cpp
ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),)
    LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS)
endif

ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true)
    LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK
endif

Nếu Android.mk bao gồm một số khối ifeq-endif, hãy cân nhắc di chuyển mã vào một tệp mới (tức là surfaceflinger.mk), sau đó đưa tệp đó vào từ Android.mk.

Triển khai hàm

Để điền các hàm triển khai HAL, hãy gọi lại hàm _hidl_cb với các giá trị khác nhau (được điều chỉnh dựa trên cờ bản dựng). Ví dụ: bạn có thể điền các hàm cho surfaceflinger trong hardware/interfaces/configstore/1.0/default/SurfaceFlingerConfigs.cpp:

Return<void> SurfaceFlingerConfigs::numFramebufferSurfaceBuffers(
        numFramebufferSurfaceBuffers_cb _hidl_cb) {
    #if NUM_FRAMEBUFFER_SURFACE_BUFFERS 2
    _hidl_cb(NumBuffers.TWO);
    #else if NUM_FRAMEBUFFER_SURFACE_BUFFERS 3
    _hidl_cb(NumBuffers.THREE);
    #else
    _hidl_cb(NumBuffers.USE_DEFAULT);
    #endif
}

Return<void> SurfaceFlingerConfigs::runWithoutSyncFramework(
        runWithoutSyncFramework_cb _hidl_cb) {
    #ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK
    _hidl_cb({true /* specified */, true /* value */});
    #else
    // when macro not defined, we can give any value to the second argument.
    // It will simply be ignored in the framework side.
    _hidl_cb({false /* specified */, false /* value */});
    #endif
}

Hãy đảm bảo rằng quá trình triển khai không chứa hàm có tên HIDL_FETCH_interface-name (ví dụ: HIDL_FETCH_ISurfaceFlingerConfigs). Đây là hàm cần thiết cho chế độ truyền qua HiDL, vốn không được configstore sử dụng (và bị cấm). ConfigStore phải luôn chạy ở chế độ liên kết.

Đăng ký dưới dạng dịch vụ

Cuối cùng, hãy đăng ký tất cả cách triển khai giao diện cho dịch vụ configstore. Ví dụ: bạn có thể đăng ký hoạt động triển khai surfaceflinger trong hardware/interfaces/configstore/1.0/default/service.cpp:

configureRpcThreadpool(maxThreads, true);
sp<ISurfaceFlingerConfigs> surfaceFlingerConfigs = new SurfaceFlingerConfigs;
status_t status = surfaceFlingerConfigs->registerAsService();

sp<IBluetoothConfigs> bluetoothConfigs = new BluetoothConfigs;
status = bluetoothConfigs->registerAsService();

// register more interfaces here
joinRpcThreadpool();

Đảm bảo quyền tiếp cận sớm

Để đảm bảo rằng một mô-đun khung có thể truy cập sớm vào dịch vụ HAL, dịch vụ HAL (Cấu hình) nên bắt đầu càng sớm càng tốt, ngay sau khi hwservicemanager sẵn sàng. Vì dịch vụ HAL cấu hình không đọc tệp bên ngoài, nên dịch vụ này dự kiến sẽ sẵn sàng nhanh chóng sau khi khởi chạy.