Lifecycle: detecting blocked and unhealthy.
Part 1: interfaces and PM implementation.
Bug: 153874006
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest
Change-Id: I312dd919d2bb552bea3d72fb49fd1579882da14b
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index f0dca77..b03d1ea 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -410,9 +410,12 @@
}
}
-StorageId IncrementalService::createStorage(
- std::string_view mountPoint, DataLoaderParamsParcel&& dataLoaderParams,
- const DataLoaderStatusListener& dataLoaderStatusListener, CreateOptions options) {
+StorageId IncrementalService::createStorage(std::string_view mountPoint,
+ content::pm::DataLoaderParamsParcel&& dataLoaderParams,
+ CreateOptions options,
+ const DataLoaderStatusListener& statusListener,
+ StorageHealthCheckParams&& healthCheckParams,
+ const StorageHealthListener& healthListener) {
LOG(INFO) << "createStorage: " << mountPoint << " | " << int(options);
if (!path::isAbsolute(mountPoint)) {
LOG(ERROR) << "path is not absolute: " << mountPoint;
@@ -545,8 +548,8 @@
// Done here as well, all data structures are in good state.
secondCleanupOnFailure.release();
- auto dataLoaderStub =
- prepareDataLoader(*ifs, std::move(dataLoaderParams), &dataLoaderStatusListener);
+ auto dataLoaderStub = prepareDataLoader(*ifs, std::move(dataLoaderParams), &statusListener,
+ std::move(healthCheckParams), &healthListener);
CHECK(dataLoaderStub);
mountIt->second = std::move(ifs);
@@ -1254,7 +1257,7 @@
dataLoaderParams.arguments = loader.arguments();
}
- prepareDataLoader(*ifs, std::move(dataLoaderParams), nullptr);
+ prepareDataLoader(*ifs, std::move(dataLoaderParams));
CHECK(ifs->dataLoaderStub);
std::vector<std::pair<std::string, metadata::BindPoint>> bindPoints;
@@ -1338,14 +1341,18 @@
IncrementalService::DataLoaderStubPtr IncrementalService::prepareDataLoader(
IncFsMount& ifs, DataLoaderParamsParcel&& params,
- const DataLoaderStatusListener* externalListener) {
+ const DataLoaderStatusListener* statusListener,
+ StorageHealthCheckParams&& healthCheckParams, const StorageHealthListener* healthListener) {
std::unique_lock l(ifs.lock);
- prepareDataLoaderLocked(ifs, std::move(params), externalListener);
+ prepareDataLoaderLocked(ifs, std::move(params), statusListener, std::move(healthCheckParams),
+ healthListener);
return ifs.dataLoaderStub;
}
void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderParamsParcel&& params,
- const DataLoaderStatusListener* externalListener) {
+ const DataLoaderStatusListener* statusListener,
+ StorageHealthCheckParams&& healthCheckParams,
+ const StorageHealthListener* healthListener) {
if (ifs.dataLoaderStub) {
LOG(INFO) << "Skipped data loader preparation because it already exists";
return;
@@ -1360,7 +1367,8 @@
ifs.dataLoaderStub =
new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel),
- externalListener, path::join(ifs.root, constants().mount));
+ statusListener, std::move(healthCheckParams), healthListener,
+ path::join(ifs.root, constants().mount));
}
template <class Duration>
@@ -1680,19 +1688,24 @@
IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id,
DataLoaderParamsParcel&& params,
FileSystemControlParcel&& control,
- const DataLoaderStatusListener* externalListener,
+ const DataLoaderStatusListener* statusListener,
+ StorageHealthCheckParams&& healthCheckParams,
+ const StorageHealthListener* healthListener,
std::string&& healthPath)
: mService(service),
mId(id),
mParams(std::move(params)),
mControl(std::move(control)),
- mListener(externalListener ? *externalListener : DataLoaderStatusListener()),
+ mStatusListener(statusListener ? *statusListener : DataLoaderStatusListener()),
+ mHealthListener(healthListener ? *healthListener : StorageHealthListener()),
mHealthPath(std::move(healthPath)) {
+ // TODO(b/153874006): enable external health listener.
+ mHealthListener = {};
healthStatusOk();
}
IncrementalService::DataLoaderStub::~DataLoaderStub() {
- if (mId != kInvalidStorageId) {
+ if (isValid()) {
cleanupResources();
}
}
@@ -1710,13 +1723,14 @@
mStatusCondition.wait_until(lock, now + 60s, [this] {
return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
});
- mListener = {};
+ mStatusListener = {};
+ mHealthListener = {};
mId = kInvalidStorageId;
}
sp<content::pm::IDataLoader> IncrementalService::DataLoaderStub::getDataLoader() {
sp<IDataLoader> dataloader;
- auto status = mService.mDataLoaderManager->getDataLoader(mId, &dataloader);
+ auto status = mService.mDataLoaderManager->getDataLoader(id(), &dataloader);
if (!status.isOk()) {
LOG(ERROR) << "Failed to get dataloader: " << status.toString8();
return {};
@@ -1752,15 +1766,15 @@
auto oldStatus = mTargetStatus;
mTargetStatus = status;
mTargetStatusTs = Clock::now();
- LOG(DEBUG) << "Target status update for DataLoader " << mId << ": " << oldStatus << " -> "
+ LOG(DEBUG) << "Target status update for DataLoader " << id() << ": " << oldStatus << " -> "
<< status << " (current " << mCurrentStatus << ")";
}
bool IncrementalService::DataLoaderStub::bind() {
bool result = false;
- auto status = mService.mDataLoaderManager->bindToDataLoader(mId, mParams, this, &result);
+ auto status = mService.mDataLoaderManager->bindToDataLoader(id(), mParams, this, &result);
if (!status.isOk() || !result) {
- LOG(ERROR) << "Failed to bind a data loader for mount " << mId;
+ LOG(ERROR) << "Failed to bind a data loader for mount " << id();
return false;
}
return true;
@@ -1771,9 +1785,9 @@
if (!dataloader) {
return false;
}
- auto status = dataloader->create(mId, mParams, mControl, this);
+ auto status = dataloader->create(id(), mParams, mControl, this);
if (!status.isOk()) {
- LOG(ERROR) << "Failed to start DataLoader: " << status.toString8();
+ LOG(ERROR) << "Failed to create DataLoader: " << status.toString8();
return false;
}
return true;
@@ -1784,7 +1798,7 @@
if (!dataloader) {
return false;
}
- auto status = dataloader->start(mId);
+ auto status = dataloader->start(id());
if (!status.isOk()) {
LOG(ERROR) << "Failed to start DataLoader: " << status.toString8();
return false;
@@ -1793,7 +1807,7 @@
}
bool IncrementalService::DataLoaderStub::destroy() {
- return mService.mDataLoaderManager->unbindFromDataLoader(mId).isOk();
+ return mService.mDataLoaderManager->unbindFromDataLoader(id()).isOk();
}
bool IncrementalService::DataLoaderStub::fsmStep() {
@@ -1852,8 +1866,8 @@
return binder::Status::
fromServiceSpecificError(-EINVAL, "onStatusChange came to invalid DataLoaderStub");
}
- if (mId != mountId) {
- LOG(ERROR) << "Mount ID mismatch: expected " << mId << ", but got: " << mountId;
+ if (id() != mountId) {
+ LOG(ERROR) << "Mount ID mismatch: expected " << id() << ", but got: " << mountId;
return binder::Status::fromServiceSpecificError(-EPERM, "Mount ID mismatch.");
}
@@ -1869,7 +1883,7 @@
mCurrentStatus = newStatus;
targetStatus = mTargetStatus;
- listener = mListener;
+ listener = mStatusListener;
if (mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE) {
// For unavailable, unbind from DataLoader to ensure proper re-commit.
@@ -1877,7 +1891,7 @@
}
}
- LOG(DEBUG) << "Current status update for DataLoader " << mId << ": " << oldStatus << " -> "
+ LOG(DEBUG) << "Current status update for DataLoader " << id() << ": " << oldStatus << " -> "
<< newStatus << " (target " << targetStatus << ")";
if (listener) {