diff options
4 files changed, 37 insertions, 23 deletions
diff --git a/core/java/android/content/pm/IDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl index 5011faafa2f7..9819b5d4eeb9 100644 --- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl +++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl @@ -31,9 +31,7 @@ oneway interface IDataLoaderStatusListener { const int DATA_LOADER_IMAGE_READY = 4; const int DATA_LOADER_IMAGE_NOT_READY = 5; - const int DATA_LOADER_SLOW_CONNECTION = 6; - const int DATA_LOADER_NO_CONNECTION = 7; - const int DATA_LOADER_CONNECTION_OK = 8; + const int DATA_LOADER_UNRECOVERABLE = 6; /** Data loader status callback */ void onStatusChanged(in int dataLoaderId, in int status); diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 45a25a04e971..9edc88674a7d 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -1487,6 +1487,18 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return e; } + private void onDataLoaderUnrecoverable() { + final PackageManagerService packageManagerService = mPm; + final String packageName = mPackageName; + mHandler.post(() -> { + if (packageManagerService.deletePackageX(packageName, + PackageManager.VERSION_CODE_HIGHEST, UserHandle.USER_SYSTEM, + PackageManager.DELETE_ALL_USERS) != PackageManager.DELETE_SUCCEEDED) { + Slog.e(TAG, "Failed to uninstall package with failed dataloader: " + packageName); + } + }); + } + /** * If session should be sealed, then it's sealed to prevent further modification. * If the session can't be sealed then it's destroyed. @@ -2564,11 +2576,20 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { IDataLoaderStatusListener listener = new IDataLoaderStatusListener.Stub() { @Override public void onStatusChanged(int dataLoaderId, int status) { - try { - if (status == IDataLoaderStatusListener.DATA_LOADER_DESTROYED) { + switch (status) { + case IDataLoaderStatusListener.DATA_LOADER_STOPPED: + case IDataLoaderStatusListener.DATA_LOADER_DESTROYED: return; - } + case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE: + onDataLoaderUnrecoverable(); + return; + } + if (mDestroyed || mDataLoaderFinished) { + return; + } + + try { IDataLoader dataLoader = dataLoaderManager.getDataLoader(dataLoaderId); if (dataLoader == null) { mDataLoaderFinished = true; diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp index 29b2cd650565..5f0c8fe3f1f7 100644 --- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp +++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp @@ -598,6 +598,9 @@ private: // IFS callbacks. void onPendingReads(dataloader::PendingReads pendingReads) final { std::lock_guard lock{mOutFdLock}; + if (mOutFd < 0) { + return; + } CHECK(mIfs); for (auto&& pendingRead : pendingReads) { const android::dataloader::FileId& fileId = pendingRead.id; @@ -611,13 +614,9 @@ private: android::incfs::toString(fileId).c_str()); continue; } - if (mRequestedFiles.insert(fileIdx).second) { - if (!sendRequest(mOutFd, PREFETCH, fileIdx, blockIdx)) { - ALOGE("Failed to request prefetch for fileid=%s. Ignore.", - android::incfs::toString(fileId).c_str()); - mRequestedFiles.erase(fileIdx); - mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION); - } + if (mRequestedFiles.insert(fileIdx).second && + !sendRequest(mOutFd, PREFETCH, fileIdx, blockIdx)) { + mRequestedFiles.erase(fileIdx); } sendRequest(mOutFd, BLOCK_MISSING, fileIdx, blockIdx); } @@ -634,7 +633,7 @@ private: } if (res < 0) { ALOGE("Failed to poll. Abort."); - mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION); + mStatusListener->reportStatus(DATA_LOADER_UNRECOVERABLE); break; } if (res == mEventFd) { @@ -644,7 +643,7 @@ private: } if (!readChunk(inout, data)) { ALOGE("Failed to read a message. Abort."); - mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION); + mStatusListener->reportStatus(DATA_LOADER_UNRECOVERABLE); break; } auto remainingData = std::span(data); diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index 4da0091af0db..e24b76ccaaba 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -1248,14 +1248,6 @@ binder::Status IncrementalService::IncrementalDataLoaderListener::onStatusChange } switch (newStatus) { - case IDataLoaderStatusListener::DATA_LOADER_NO_CONNECTION: { - // TODO(b/150411019): handle data loader connection loss - break; - } - case IDataLoaderStatusListener::DATA_LOADER_CONNECTION_OK: { - // TODO(b/150411019): handle data loader connection loss - break; - } case IDataLoaderStatusListener::DATA_LOADER_CREATED: { if (startRequested) { incrementalService.startDataLoader(mountId); @@ -1277,6 +1269,10 @@ binder::Status IncrementalService::IncrementalDataLoaderListener::onStatusChange case IDataLoaderStatusListener::DATA_LOADER_IMAGE_NOT_READY: { break; } + case IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE: { + // Nothing for now. Rely on externalListener to handle this. + break; + } default: { LOG(WARNING) << "Unknown data loader status: " << newStatus << " for mount: " << mountId; |