Only shut down gsid when it has no more consumers.
Consumers of gsiservice must now use IGsid for its top-level interface.
IGsiService can be acquired through IGsid::getClient. When the last
reference to IGsiService is dropped, gsid will cleanly exit. Callers
should no longer stop gsid through init.
Bug: 133528572
Test: gsid cleanly exits after gsi_tool runs
Change-Id: Ie5cb80fa63e61b143f9f27cca96999a5c71dab2c
Merged-In: Ie5cb80fa63e61b143f9f27cca96999a5c71dab2c
diff --git a/gsi_service.cpp b/gsi_service.cpp
index 18f1f4f..f0288f6 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -51,19 +51,44 @@
using android::base::StringPrintf;
using android::base::unique_fd;
-void GsiService::Register() {
- auto ret = android::BinderService<GsiService>::publish();
+android::wp<GsiService> GsiService::sInstance;
+
+void Gsid::Register() {
+ auto ret = android::BinderService<Gsid>::publish();
if (ret != android::OK) {
LOG(FATAL) << "Could not register gsi service: " << ret;
}
}
-GsiService::GsiService() {
+binder::Status Gsid::getClient(android::sp<IGsiService>* _aidl_return) {
+ *_aidl_return = GsiService::Get(this);
+ return binder::Status::ok();
+}
+
+GsiService::GsiService(Gsid* parent) : parent_(parent) {
progress_ = {};
GsiInstaller::PostInstallCleanup();
}
-GsiService::~GsiService() {}
+GsiService::~GsiService() {
+ std::lock_guard<std::mutex> guard(parent_->lock());
+
+ if (sInstance == this) {
+ // No more consumers, gracefully shut down gsid.
+ exit(0);
+ }
+}
+
+android::sp<IGsiService> GsiService::Get(Gsid* parent) {
+ std::lock_guard<std::mutex> guard(parent->lock());
+
+ android::sp<GsiService> service = sInstance.promote();
+ if (!service) {
+ service = new GsiService(parent);
+ sInstance = service.get();
+ }
+ return service.get();
+}
#define ENFORCE_SYSTEM \
do { \
@@ -89,7 +114,7 @@
binder::Status GsiService::beginGsiInstall(const GsiInstallParams& given_params,
int* _aidl_return) {
ENFORCE_SYSTEM;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
// Make sure any interrupted installations are cleaned up.
installer_ = nullptr;
@@ -114,7 +139,7 @@
binder::Status GsiService::commitGsiChunkFromStream(const android::os::ParcelFileDescriptor& stream,
int64_t bytes, bool* _aidl_return) {
ENFORCE_SYSTEM;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (!installer_) {
*_aidl_return = false;
@@ -156,7 +181,7 @@
binder::Status GsiService::commitGsiChunkFromMemory(const std::vector<uint8_t>& bytes,
bool* _aidl_return) {
ENFORCE_SYSTEM;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (!installer_) {
*_aidl_return = false;
@@ -168,7 +193,7 @@
}
binder::Status GsiService::setGsiBootable(bool one_shot, int* _aidl_return) {
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (installer_) {
ENFORCE_SYSTEM;
@@ -188,7 +213,7 @@
binder::Status GsiService::isGsiEnabled(bool* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
std::string boot_key;
if (!GetInstallStatus(&boot_key)) {
*_aidl_return = false;
@@ -200,7 +225,7 @@
binder::Status GsiService::removeGsiInstall(bool* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
// Just in case an install was left hanging.
std::string install_dir;
@@ -221,7 +246,7 @@
binder::Status GsiService::disableGsiInstall(bool* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
*_aidl_return = DisableGsiInstall();
return binder::Status::ok();
@@ -229,7 +254,7 @@
binder::Status GsiService::isGsiRunning(bool* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
*_aidl_return = IsGsiRunning();
return binder::Status::ok();
@@ -237,7 +262,7 @@
binder::Status GsiService::isGsiInstalled(bool* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
*_aidl_return = IsGsiInstalled();
return binder::Status::ok();
@@ -245,7 +270,7 @@
binder::Status GsiService::isGsiInstallInProgress(bool* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
*_aidl_return = !!installer_;
return binder::Status::ok();
@@ -254,7 +279,7 @@
binder::Status GsiService::cancelGsiInstall(bool* _aidl_return) {
ENFORCE_SYSTEM;
should_abort_ = true;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
should_abort_ = false;
installer_ = nullptr;
@@ -265,7 +290,7 @@
binder::Status GsiService::getGsiBootStatus(int* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (!IsGsiInstalled()) {
*_aidl_return = BOOT_STATUS_NOT_INSTALLED;
@@ -304,7 +329,7 @@
binder::Status GsiService::getUserdataImageSize(int64_t* _aidl_return) {
ENFORCE_SYSTEM;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
*_aidl_return = -1;
@@ -337,7 +362,7 @@
binder::Status GsiService::getInstalledGsiImageDir(std::string* _aidl_return) {
ENFORCE_SYSTEM;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (IsGsiInstalled()) {
*_aidl_return = GetInstalledImageDir();
@@ -347,7 +372,7 @@
binder::Status GsiService::wipeGsiUserdata(int* _aidl_return) {
ENFORCE_SYSTEM_OR_SHELL;
- std::lock_guard<std::mutex> guard(lock_);
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (IsGsiRunning() || !IsGsiInstalled()) {
*_aidl_return = IGsiService::INSTALL_ERROR_GENERIC;
@@ -373,7 +398,7 @@
class ImageManagerService : public BinderService<ImageManagerService>, public BnImageManager {
public:
- ImageManagerService(GsiService* parent, std::unique_ptr<ImageManager>&& impl, uid_t uid);
+ ImageManagerService(GsiService* service, std::unique_ptr<ImageManager>&& impl, uid_t uid);
binder::Status createBackingImage(const std::string& name, int64_t size, int flags) override;
binder::Status deleteBackingImage(const std::string& name) override;
binder::Status mapImageDevice(const std::string& name, int32_t timeout_ms,
@@ -383,20 +408,21 @@
private:
bool CheckUid();
- android::sp<GsiService> parent_;
+ android::sp<GsiService> service_;
+ android::sp<Gsid> parent_;
std::unique_ptr<ImageManager> impl_;
uid_t uid_;
};
-ImageManagerService::ImageManagerService(GsiService* parent, std::unique_ptr<ImageManager>&& impl,
+ImageManagerService::ImageManagerService(GsiService* service, std::unique_ptr<ImageManager>&& impl,
uid_t uid)
- : parent_(parent), impl_(std::move(impl)), uid_(uid) {}
+ : service_(service), parent_(service->parent()), impl_(std::move(impl)), uid_(uid) {}
binder::Status ImageManagerService::createBackingImage(const std::string& name, int64_t size,
int flags) {
if (!CheckUid()) return UidSecurityError();
- std::lock_guard<std::mutex> guard(*parent_->lock());
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (!impl_->CreateBackingImage(name, size, flags, nullptr)) {
return BinderError("Failed to create");
@@ -407,7 +433,7 @@
binder::Status ImageManagerService::deleteBackingImage(const std::string& name) {
if (!CheckUid()) return UidSecurityError();
- std::lock_guard<std::mutex> guard(*parent_->lock());
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (!impl_->DeleteBackingImage(name)) {
return BinderError("Failed to delete");
@@ -419,7 +445,7 @@
MappedImage* mapping) {
if (!CheckUid()) return UidSecurityError();
- std::lock_guard<std::mutex> guard(*parent_->lock());
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (!impl_->MapImageDevice(name, std::chrono::milliseconds(timeout_ms), &mapping->path)) {
return BinderError("Failed to map");
@@ -430,7 +456,7 @@
binder::Status ImageManagerService::unmapImageDevice(const std::string& name) {
if (!CheckUid()) return UidSecurityError();
- std::lock_guard<std::mutex> guard(*parent_->lock());
+ std::lock_guard<std::mutex> guard(parent_->lock());
if (!impl_->UnmapImageDevice(name)) {
return BinderError("Failed to unmap");