Proper retrying DL installation sessions.
Plus more robust handling of broken DLs.
Bug: 190012477
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest com.google.android.packageinstallerv2proxy.host.gts.IncrementalInstallerHostTest
Change-Id: I5cb037d49cd2b140bed1045c99f072112495acfc
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 47d59b2..757c9de 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -89,6 +89,11 @@
// Max interval after system invoked the DL when readlog collection can be enabled.
static constexpr auto readLogsMaxInterval = 2h;
+
+ // How long should we wait till dataLoader reports destroyed.
+ static constexpr auto destroyTimeout = 60s;
+
+ static constexpr auto anyStatus = INT_MIN;
};
static const Constants& constants() {
@@ -2554,7 +2559,7 @@
mControl = {};
mHealthControl = {};
mHealthListener = {};
- mStatusCondition.wait_until(lock, now + 60s, [this] {
+ mStatusCondition.wait_until(lock, now + Constants::destroyTimeout, [this] {
return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
});
mStatusListener = {};
@@ -2754,8 +2759,16 @@
switch (targetStatus) {
case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: {
switch (currentStatus) {
+ case IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE:
+ case IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE:
+ destroy();
+ // DataLoader is broken, just assume it's destroyed.
+ compareAndSetCurrentStatus(currentStatus,
+ IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
+ return true;
case IDataLoaderStatusListener::DATA_LOADER_BINDING:
- setCurrentStatus(IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
+ compareAndSetCurrentStatus(currentStatus,
+ IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
return true;
default:
return destroy();
@@ -2776,7 +2789,11 @@
case IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE:
// Before binding need to make sure we are unbound.
// Otherwise we'll get stuck binding.
- return destroy();
+ destroy();
+ // DataLoader is broken, just assume it's destroyed.
+ compareAndSetCurrentStatus(currentStatus,
+ IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
+ return true;
case IDataLoaderStatusListener::DATA_LOADER_DESTROYED:
case IDataLoaderStatusListener::DATA_LOADER_BINDING:
return bind();
@@ -2815,6 +2832,11 @@
}
void IncrementalService::DataLoaderStub::setCurrentStatus(int newStatus) {
+ compareAndSetCurrentStatus(Constants::anyStatus, newStatus);
+}
+
+void IncrementalService::DataLoaderStub::compareAndSetCurrentStatus(int expectedStatus,
+ int newStatus) {
int oldStatus, oldTargetStatus, newTargetStatus;
DataLoaderStatusListener listener;
{
@@ -2822,6 +2844,9 @@
if (mCurrentStatus == newStatus) {
return;
}
+ if (expectedStatus != Constants::anyStatus && expectedStatus != mCurrentStatus) {
+ return;
+ }
oldStatus = mCurrentStatus;
oldTargetStatus = mTargetStatus;