From 6e0c0102aeb382f3fde5772361d291a26f687292 Mon Sep 17 00:00:00 2001 From: Alex Deymo Date: Fri, 30 Sep 2016 19:00:40 -0700 Subject: [PATCH 1/3] boot_control: Define the boot_control HIDL interface. Bug: 31864052 Merged-In: I9222b140ff51c4d3846b86b03719e2c8e9b7fe47 Change-Id: I9222b140ff51c4d3846b86b03719e2c8e9b7fe47 --- Android.bp | 2 + boot/1.0/Android.bp | 46 +++++++++++++ boot/1.0/Android.mk | 136 ++++++++++++++++++++++++++++++++++++++ boot/1.0/IBootControl.hal | 104 +++++++++++++++++++++++++++++ boot/1.0/types.hal | 41 ++++++++++++ 5 files changed, 329 insertions(+) create mode 100644 boot/1.0/Android.bp create mode 100644 boot/1.0/Android.mk create mode 100644 boot/1.0/IBootControl.hal create mode 100644 boot/1.0/types.hal diff --git a/Android.bp b/Android.bp index 2c113d5747..85ab629a99 100644 --- a/Android.bp +++ b/Android.bp @@ -2,6 +2,8 @@ subdirs = [ "benchmarks/msgq/1.0", "bluetooth/1.0", + "boot/1.0", + "boot/1.0/default", "nfc/1.0", "nfc/1.0/default", "radio/1.0", diff --git a/boot/1.0/Android.bp b/boot/1.0/Android.bp new file mode 100644 index 0000000000..98341ef3d0 --- /dev/null +++ b/boot/1.0/Android.bp @@ -0,0 +1,46 @@ +// This file is autogenerated by hidl-gen. Do not edit manually. + +genrule { + name: "android.hardware.boot@1.0_genc++", + tool: "hidl-gen", + cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.boot@1.0", + srcs: [ + "types.hal", + "IBootControl.hal", + ], + out: [ + "android/hardware/boot/1.0/types.cpp", + "android/hardware/boot/1.0/BootControlAll.cpp", + ], +} + +genrule { + name: "android.hardware.boot@1.0_genc++_headers", + tool: "hidl-gen", + cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.boot@1.0", + srcs: [ + "types.hal", + "IBootControl.hal", + ], + out: [ + "android/hardware/boot/1.0/types.h", + "android/hardware/boot/1.0/IBootControl.h", + "android/hardware/boot/1.0/IHwBootControl.h", + "android/hardware/boot/1.0/BnBootControl.h", + "android/hardware/boot/1.0/BpBootControl.h", + "android/hardware/boot/1.0/BsBootControl.h", + ], +} + +cc_library_shared { + name: "android.hardware.boot@1.0", + generated_sources: ["android.hardware.boot@1.0_genc++"], + generated_headers: ["android.hardware.boot@1.0_genc++_headers"], + export_generated_headers: ["android.hardware.boot@1.0_genc++_headers"], + shared_libs: [ + "libhidl", + "libhwbinder", + "libutils", + "libcutils", + ], +} diff --git a/boot/1.0/Android.mk b/boot/1.0/Android.mk new file mode 100644 index 0000000000..bb19a797a5 --- /dev/null +++ b/boot/1.0/Android.mk @@ -0,0 +1,136 @@ +# This file is autogenerated by hidl-gen. Do not edit manually. + +LOCAL_PATH := $(call my-dir) + +################################################################################ + +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.boot@1.0-java +LOCAL_MODULE_CLASS := JAVA_LIBRARIES + +intermediates := $(local-generated-sources-dir) + +HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX) + +# +# Build types.hal (BoolResult) +# +GEN := $(intermediates)/android/hardware/boot/1.0/BoolResult.java +$(GEN): $(HIDL) +$(GEN): PRIVATE_HIDL := $(HIDL) +$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal +$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) +$(GEN): PRIVATE_CUSTOM_TOOL = \ + $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ + -Ljava -randroid.hardware:hardware/interfaces \ + android.hardware.boot@1.0::types.BoolResult + +$(GEN): $(LOCAL_PATH)/types.hal + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) + +# +# Build types.hal (CommandResult) +# +GEN := $(intermediates)/android/hardware/boot/1.0/CommandResult.java +$(GEN): $(HIDL) +$(GEN): PRIVATE_HIDL := $(HIDL) +$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal +$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) +$(GEN): PRIVATE_CUSTOM_TOOL = \ + $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ + -Ljava -randroid.hardware:hardware/interfaces \ + android.hardware.boot@1.0::types.CommandResult + +$(GEN): $(LOCAL_PATH)/types.hal + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) + +# +# Build IBootControl.hal +# +GEN := $(intermediates)/android/hardware/boot/1.0/IBootControl.java +$(GEN): $(HIDL) +$(GEN): PRIVATE_HIDL := $(HIDL) +$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IBootControl.hal +$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal +$(GEN): $(LOCAL_PATH)/types.hal +$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) +$(GEN): PRIVATE_CUSTOM_TOOL = \ + $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ + -Ljava -randroid.hardware:hardware/interfaces \ + android.hardware.boot@1.0::IBootControl + +$(GEN): $(LOCAL_PATH)/IBootControl.hal + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) +include $(BUILD_JAVA_LIBRARY) + + +################################################################################ + +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.boot@1.0-java-static +LOCAL_MODULE_CLASS := JAVA_LIBRARIES + +intermediates := $(local-generated-sources-dir) + +HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX) + +# +# Build types.hal (BoolResult) +# +GEN := $(intermediates)/android/hardware/boot/1.0/BoolResult.java +$(GEN): $(HIDL) +$(GEN): PRIVATE_HIDL := $(HIDL) +$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal +$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) +$(GEN): PRIVATE_CUSTOM_TOOL = \ + $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ + -Ljava -randroid.hardware:hardware/interfaces \ + android.hardware.boot@1.0::types.BoolResult + +$(GEN): $(LOCAL_PATH)/types.hal + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) + +# +# Build types.hal (CommandResult) +# +GEN := $(intermediates)/android/hardware/boot/1.0/CommandResult.java +$(GEN): $(HIDL) +$(GEN): PRIVATE_HIDL := $(HIDL) +$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal +$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) +$(GEN): PRIVATE_CUSTOM_TOOL = \ + $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ + -Ljava -randroid.hardware:hardware/interfaces \ + android.hardware.boot@1.0::types.CommandResult + +$(GEN): $(LOCAL_PATH)/types.hal + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) + +# +# Build IBootControl.hal +# +GEN := $(intermediates)/android/hardware/boot/1.0/IBootControl.java +$(GEN): $(HIDL) +$(GEN): PRIVATE_HIDL := $(HIDL) +$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IBootControl.hal +$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal +$(GEN): $(LOCAL_PATH)/types.hal +$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) +$(GEN): PRIVATE_CUSTOM_TOOL = \ + $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ + -Ljava -randroid.hardware:hardware/interfaces \ + android.hardware.boot@1.0::IBootControl + +$(GEN): $(LOCAL_PATH)/IBootControl.hal + $(transform-generated-source) +LOCAL_GENERATED_SOURCES += $(GEN) +include $(BUILD_STATIC_JAVA_LIBRARY) + + + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/boot/1.0/IBootControl.hal b/boot/1.0/IBootControl.hal new file mode 100644 index 0000000000..2024f1fc60 --- /dev/null +++ b/boot/1.0/IBootControl.hal @@ -0,0 +1,104 @@ +/* + * Copyright 2016 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. + */ + +package android.hardware.boot@1.0; + +/** + * The Boot Control HAL is designed to allow for managing sets of redundant + * partitions, called slots, that can be booted from independently. Slots + * are sets of partitions whose names differ only by a given suffix. + * They are identified here by a 0 indexed number and associated with their + * suffix, which is appended to the base name for any particular partition + * to find the one associated with that slot. + * The primary use of this set up is to allow for background updates while + * the device is running, and to provide a fallback in the event that the + * update fails. + */ +interface IBootControl { + /** + * getNumberSlots() returns the number of available slots. + * For instance, a system with a single set of partitions must return + * 1, a system with A/B must return 2, A/B/C -> 3 and so on. A system with + * less than two slots doesn't support background updates, for example if + * running from a virtual machine with only one copy of each partition for the + * purpose of testing. + */ + getNumberSlots() generates (uint32_t numSlots); + + /** + * getCurrentSlot() returns the slot number of that the current boot is booted + * from, for example slot number 0 (Slot A). It is assumed that if the current + * slot is A, then the block devices underlying B can be accessed directly + * without any risk of corruption. + * The returned value is always guaranteed to be strictly less than the + * value returned by getNumberSlots. Slots start at 0 and finish at + * getNumberSlots() - 1. The value returned here must match the suffix passed + * from the bootloader, regardless of which slot is active or successful. + */ + getCurrentSlot() generates (Slot slot); + + /** + * markBootSuccessful() marks the current slot as having booted successfully. + * + * Returns whether the command succeeded. + */ + markBootSuccessful() generates (CommandResult error); + + /** + * setActiveBootSlot() marks the slot passed in parameter as the active boot + * slot (see getCurrentSlot for an explanation of the "slot" parameter). This + * overrides any previous call to setSlotAsUnbootable. + * Returns whether the command succeeded. + */ + setActiveBootSlot(Slot slot) generates (CommandResult error); + + /** + * setSlotAsUnbootable() marks the slot passed in parameter as + * an unbootable. This can be used while updating the contents of the slot's + * partitions, so that the system must not attempt to boot a known bad set up. + * Returns whether the command succeeded. + */ + setSlotAsUnbootable(Slot slot) generates (CommandResult error); + + /** + * isSlotBootable() returns if the slot passed in parameter is bootable. Note + * that slots can be made unbootable by both the bootloader and by the OS + * using setSlotAsUnbootable. + * Returns TRUE if the slot is bootable, FALSE if it's not, and INVALID_SLOT + * if slot does not exist. + */ + isSlotBootable(Slot slot) generates (BoolResult bootable); + + /** + * isSlotMarkedSucessful() returns if the slot passed in parameter has been + * marked as successful using markBootSuccessful. Note that only the current + * slot can be marked as successful but any slot can be queried. + * Returns TRUE if the slot has been marked as successful, FALSE if it has + * not, and INVALID_SLOT if the slot does not exist. + */ + isSlotMarkedSuccessful(Slot slot) generates (BoolResult successful); + + /** + * getSuffix() returns the string suffix used by partitions that correspond to + * the slot number passed in as a parameter. The bootloader must pass the + * suffix of the currently active slot either through a kernel command line + * property at androidboot.slot_suffix, or the device tree at + * /firmware/android/slot_suffix. + * Returns the empty string "" if slot does not match an existing slot. + */ + getSuffix(Slot slot) generates (string slotSuffix); +}; + diff --git a/boot/1.0/types.hal b/boot/1.0/types.hal new file mode 100644 index 0000000000..87f61099d1 --- /dev/null +++ b/boot/1.0/types.hal @@ -0,0 +1,41 @@ +/* + * Copyright 2016 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. + */ + +package android.hardware.boot@1.0; + +/** + * A command result encapsulating whether the command succeeded and + * an error string. + */ +struct CommandResult { + bool success; + string errMsg; +}; + +/** + * An identifier for a slot number. + */ +typedef uint32_t Slot; + +/** + * A result encapsulating whether a function returned true, false or + * failed due to an invalid slot number + */ +enum BoolResult : int32_t { + FALSE = 0, + TRUE = 1, + INVALID_SLOT = -1 +}; From fe25fd88c80f033470e1851dde779a49f76bae44 Mon Sep 17 00:00:00 2001 From: Connor O'Brien Date: Mon, 10 Oct 2016 12:31:37 -0700 Subject: [PATCH 2/3] Add boot_control HIDL default implementation Create basic implementation that passes commands through to the old HAL implementation. Bug: 31864052 Test: Ran and compared output to old implementation Change-Id: I01f4450dc3a1893e13b8fb325ea40cf9c98297be Signed-off-by: Connor O'Brien --- boot/1.0/default/Android.mk | 17 ++++++ boot/1.0/default/BootControl.cpp | 98 ++++++++++++++++++++++++++++++++ boot/1.0/default/BootControl.h | 46 +++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 boot/1.0/default/Android.mk create mode 100644 boot/1.0/default/BootControl.cpp create mode 100644 boot/1.0/default/BootControl.h diff --git a/boot/1.0/default/Android.mk b/boot/1.0/default/Android.mk new file mode 100644 index 0000000000..563f1883ee --- /dev/null +++ b/boot/1.0/default/Android.mk @@ -0,0 +1,17 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.boot@1.0-impl +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_SRC_FILES := \ + BootControl.cpp \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libhidl \ + libhwbinder \ + libhardware \ + libutils \ + android.hardware.boot@1.0 \ + +include $(BUILD_SHARED_LIBRARY) diff --git a/boot/1.0/default/BootControl.cpp b/boot/1.0/default/BootControl.cpp new file mode 100644 index 0000000000..4c34168696 --- /dev/null +++ b/boot/1.0/default/BootControl.cpp @@ -0,0 +1,98 @@ +#define LOG_TAG "android.hardware.boot@1.0-impl" +#include + +#include +#include +#include "BootControl.h" + +namespace android { +namespace hardware { +namespace boot { +namespace V1_0 { +namespace implementation { + +BootControl::BootControl(boot_control_module_t *module) : mModule(module){ +} + +// Methods from ::android::hardware::boot::V1_0::IBootControl follow. +Return BootControl::getNumberSlots() { + return mModule->getNumberSlots(mModule); +} + +Return BootControl::getCurrentSlot() { + return mModule->getCurrentSlot(mModule); +} + +Return BootControl::markBootSuccessful(markBootSuccessful_cb _hidl_cb) { + int ret = mModule->markBootSuccessful(mModule); + struct CommandResult cr; + cr.success = (ret == 0); + cr.errMsg = strerror(-ret); + _hidl_cb(cr); + return Void(); +} + +Return BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) { + int ret = mModule->setActiveBootSlot(mModule, slot); + struct CommandResult cr; + cr.success = (ret == 0); + cr.errMsg = strerror(-ret); + _hidl_cb(cr); + return Void(); +} + +Return BootControl::setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) { + int ret = mModule->setSlotAsUnbootable(mModule, slot); + struct CommandResult cr; + cr.success = (ret == 0); + cr.errMsg = strerror(-ret); + _hidl_cb(cr); + return Void(); +} + +Return BootControl::isSlotBootable(uint32_t slot) { + int32_t ret = mModule->isSlotBootable(mModule, slot); + if (ret < 0) { + return BoolResult::INVALID_SLOT; + } + return ret ? BoolResult::TRUE : BoolResult::FALSE; +} + +Return BootControl::isSlotMarkedSuccessful(uint32_t slot) { + int32_t ret = mModule->isSlotMarkedSuccessful(mModule, slot); + if (ret < 0) { + return BoolResult::INVALID_SLOT; + } + return ret ? BoolResult::TRUE : BoolResult::FALSE; +} + +Return BootControl::getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) { + hidl_string ans; + const char *suffix = mModule->getSuffix(mModule, slot); + if (suffix) { + ans = suffix; + } + _hidl_cb(ans); + return Void(); +} + + +IBootControl* HIDL_FETCH_IBootControl(const char* hal) { + int ret = 0; + boot_control_module_t* module = NULL; + hw_module_t **hwm = reinterpret_cast(&module); + ret = hw_get_module(hal, const_cast(hwm)); + if (ret) + { + ALOGE("hw_get_module %s failed: %d", hal, ret); + return nullptr; + } + module->init(module); + return new BootControl(module); +} + +} // namespace implementation +} // namespace V1_0 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/boot/1.0/default/BootControl.h b/boot/1.0/default/BootControl.h new file mode 100644 index 0000000000..73af4f4f11 --- /dev/null +++ b/boot/1.0/default/BootControl.h @@ -0,0 +1,46 @@ +#ifndef HIDL_GENERATED_android_hardware_boot_V1_0_BootControl_H_ +#define HIDL_GENERATED_android_hardware_boot_V1_0_BootControl_H_ + +#include +#include + +#include +namespace android { +namespace hardware { +namespace boot { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::boot::V1_0::BoolResult; +using ::android::hardware::boot::V1_0::CommandResult; +using ::android::hardware::boot::V1_0::IBootControl; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; + +struct BootControl : public IBootControl { + BootControl(boot_control_module_t* module); + // Methods from ::android::hardware::boot::V1_0::IBootControl follow. + Return getNumberSlots() override; + Return getCurrentSlot() override; + Return markBootSuccessful(markBootSuccessful_cb _hidl_cb) override; + Return setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) override; + Return setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) override; + Return isSlotBootable(uint32_t slot) override; + Return isSlotMarkedSuccessful(uint32_t slot) override; + Return getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) override; +private: + boot_control_module_t* mModule; +}; + +extern "C" IBootControl* HIDL_FETCH_IBootControl(const char* name); + +} // namespace implementation +} // namespace V1_0 +} // namespace boot +} // namespace hardware +} // namespace android + +#endif // HIDL_GENERATED_android_hardware_boot_V1_0_BootControl_H_ From cd0d29d4afd1910b584fb374265548adaf3f46ef Mon Sep 17 00:00:00 2001 From: Connor O'Brien Date: Mon, 10 Oct 2016 14:41:35 -0700 Subject: [PATCH 3/3] Add android.hardware.boot_control@1.0 service. Bug: 31864052 Change-Id: I982077d71a81c0bc8d081f0cc7e83180b97f2b87 Signed-off-by: Connor O'Brien --- boot/1.0/default/Android.mk | 17 +++++++ .../android.hardware.boot@1.0-service.rc | 4 ++ boot/1.0/default/service.cpp | 44 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 boot/1.0/default/android.hardware.boot@1.0-service.rc create mode 100644 boot/1.0/default/service.cpp diff --git a/boot/1.0/default/Android.mk b/boot/1.0/default/Android.mk index 563f1883ee..50fd1e4ac3 100644 --- a/boot/1.0/default/Android.mk +++ b/boot/1.0/default/Android.mk @@ -15,3 +15,20 @@ LOCAL_SHARED_LIBRARIES := \ android.hardware.boot@1.0 \ include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_MODULE := android.hardware.boot@1.0-service +LOCAL_INIT_RC := android.hardware.boot@1.0-service.rc +LOCAL_SRC_FILES := \ + service.cpp + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libhwbinder \ + libhardware \ + libhidl \ + libutils \ + android.hardware.boot@1.0 \ + +include $(BUILD_EXECUTABLE) diff --git a/boot/1.0/default/android.hardware.boot@1.0-service.rc b/boot/1.0/default/android.hardware.boot@1.0-service.rc new file mode 100644 index 0000000000..57c1aff31c --- /dev/null +++ b/boot/1.0/default/android.hardware.boot@1.0-service.rc @@ -0,0 +1,4 @@ +service boot-hal-1-0 /system/bin/hw/android.hardware.boot@1.0-service + class hal + user system + group system readproc diff --git a/boot/1.0/default/service.cpp b/boot/1.0/default/service.cpp new file mode 100644 index 0000000000..b059f9a24b --- /dev/null +++ b/boot/1.0/default/service.cpp @@ -0,0 +1,44 @@ +#define LOG_TAG "android.hardware.boot@1.0-service" +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +using android::sp; + +using android::hardware::IPCThreadState; +using android::hardware::ProcessState; + +using ::android::hardware::boot::V1_0::IBootControl; + +int main (int /* argc */, char * /* argv */ []) { + ALOGI("Service is starting."); + const char instance[] = "bootctrl"; + ALOGI("Retrieving default implementation of instance %s.", + instance); + + sp service = IBootControl::getService(instance, true /* getStub */); + + if (service.get() == nullptr) { + ALOGE("IBootControl::getService returned NULL, exiting"); + return -1; + } + + LOG_FATAL_IF(service->isRemote(), "Implementation is REMOTE!"); + + ALOGI("Registering instance %s.", instance); + service->registerAsService(instance); + ALOGI("Ready."); + + ProcessState::self()->setThreadPoolMaxThreadCount(0); + ProcessState::self()->startThreadPool(); + IPCThreadState::self()->joinThreadPool(); +}