Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2cf1d18f authored by Alex Buynytskyy's avatar Alex Buynytskyy
Browse files

Incremental apps removal on data loader failures.

Test: adb install --incremental megacity.apk over USB2.0, remove usb connection
after installed.
Bug: b/15041101

Change-Id: Ib848640dbe49c76021f7cf544de4413599c2c763
parent 962b460f
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -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);
+24 −3
Original line number Diff line number Diff line
@@ -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;
+8 −9
Original line number Diff line number Diff line
@@ -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());
            if (mRequestedFiles.insert(fileIdx).second &&
                !sendRequest(mOutFd, PREFETCH, fileIdx, blockIdx)) {
                mRequestedFiles.erase(fileIdx);
                    mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION);
                }
            }
            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);
+4 −8
Original line number Diff line number Diff line
@@ -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;