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

Commit 7e0a1a8e authored by Alex Buynytskyy's avatar Alex Buynytskyy
Browse files

Unavailable DataLoader status.

This is a temporary failure, does not fail the session, but requires
caller to re-commit. E.g. there are connectivity issues which can be
fixed later.

Bug: b/153874006
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest
Change-Id: I02791a2963130dbecb510c4a7cafcf04f6245761
parent c463e56a
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -40,11 +40,15 @@ oneway interface IDataLoaderStatusListener {
    /** Installation can't continue as DataLoader failed to stream necessary data. */
    /** Installation can't continue as DataLoader failed to stream necessary data. */
    const int DATA_LOADER_IMAGE_NOT_READY = 6;
    const int DATA_LOADER_IMAGE_NOT_READY = 6;


    /** DataLoader instance can't run at the moment, but might recover later.
     *  It's up to system to decide if the app is still usable. */
    const int DATA_LOADER_UNAVAILABLE = 7;

    /** DataLoader reports that this instance is invalid and can never be restored.
    /** DataLoader reports that this instance is invalid and can never be restored.
    *   Warning: this is a terminal status that data loader should use carefully and
    *   Warning: this is a terminal status that data loader should use carefully and
    *            the system should almost never use - e.g. only if all recovery attempts
    *            the system should almost never use - e.g. only if all recovery attempts
    *            fail and all retry limits are exceeded. */
    *            fail and all retry limits are exceeded. */
    const int DATA_LOADER_UNRECOVERABLE = 7;
    const int DATA_LOADER_UNRECOVERABLE = 8;


    /** Data loader status callback */
    /** Data loader status callback */
    void onStatusChanged(in int dataLoaderId, in int status);
    void onStatusChanged(in int dataLoaderId, in int status);
+11 −5
Original line number Original line Diff line number Diff line
@@ -2691,17 +2691,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                            }
                            }
                            break;
                            break;
                        }
                        }
                        case IDataLoaderStatusListener.DATA_LOADER_UNAVAILABLE: {
                            // Don't fail or commit the session. Allow caller to commit again.
                            sendPendingStreaming(mContext, mRemoteStatusReceiver, sessionId,
                                    "DataLoader unavailable");
                            break;
                        }
                        case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
                        case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
                            mDataLoaderFinished = true;
                            mDataLoaderFinished = true;
                            dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
                            dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
                                    "DataLoader reported unrecoverable failure.");
                                    "DataLoader reported unrecoverable failure.");
                            return;
                            break;
                    }
                    }
                } catch (RemoteException e) {
                } catch (RemoteException e) {
                    // In case of streaming failure we don't want to fail or commit the session.
                    // In case of streaming failure we don't want to fail or commit the session.
                    // Just return from this method and allow caller to commit again.
                    // Just return from this method and allow caller to commit again.
                    sendPendingStreaming(mContext, mRemoteStatusReceiver, sessionId,
                    sendPendingStreaming(mContext, mRemoteStatusReceiver, sessionId,
                            new StreamingException(e));
                            e.getMessage());
                }
                }
            }
            }
        };
        };
@@ -3059,13 +3065,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    }
    }


    private static void sendPendingStreaming(Context context, IntentSender target, int sessionId,
    private static void sendPendingStreaming(Context context, IntentSender target, int sessionId,
            Throwable cause) {
            @Nullable String cause) {
        final Intent intent = new Intent();
        final Intent intent = new Intent();
        intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
        intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
        intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_STREAMING);
        intent.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_STREAMING);
        if (cause != null && !TextUtils.isEmpty(cause.getMessage())) {
        if (!TextUtils.isEmpty(cause)) {
            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE,
                    "Staging Image Not Ready [" + cause.getMessage() + "]");
                    "Staging Image Not Ready [" + cause + "]");
        } else {
        } else {
            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
            intent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, "Staging Image Not Ready");
        }
        }
+16 −2
Original line number Original line Diff line number Diff line
@@ -1708,15 +1708,19 @@ bool IncrementalService::DataLoaderStub::setTargetStatus(int newStatus) {
    {
    {
        std::unique_lock lock(mStatusMutex);
        std::unique_lock lock(mStatusMutex);
        oldStatus = mTargetStatus;
        oldStatus = mTargetStatus;
        mTargetStatus = newStatus;
        mTargetStatusTs = Clock::now();
        curStatus = mCurrentStatus;
        curStatus = mCurrentStatus;
        setTargetStatusLocked(newStatus);
    }
    }
    LOG(DEBUG) << "Target status update for DataLoader " << mId << ": " << oldStatus << " -> "
    LOG(DEBUG) << "Target status update for DataLoader " << mId << ": " << oldStatus << " -> "
               << newStatus << " (current " << curStatus << ")";
               << newStatus << " (current " << curStatus << ")";
    return fsmStep();
    return fsmStep();
}
}


void IncrementalService::DataLoaderStub::setTargetStatusLocked(int status) {
    mTargetStatus = status;
    mTargetStatusTs = Clock::now();
}

bool IncrementalService::DataLoaderStub::waitForStatus(int status, Clock::duration duration) {
bool IncrementalService::DataLoaderStub::waitForStatus(int status, Clock::duration duration) {
    auto now = Clock::now();
    auto now = Clock::now();
    std::unique_lock lock(mStatusMutex);
    std::unique_lock lock(mStatusMutex);
@@ -1782,6 +1786,9 @@ bool IncrementalService::DataLoaderStub::fsmStep() {
    }
    }


    switch (targetStatus) {
    switch (targetStatus) {
        case IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE:
            // Do nothing, this is a reset state.
            break;
        case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: {
        case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: {
            return destroy();
            return destroy();
        }
        }
@@ -1796,6 +1803,7 @@ bool IncrementalService::DataLoaderStub::fsmStep() {
        case IDataLoaderStatusListener::DATA_LOADER_CREATED:
        case IDataLoaderStatusListener::DATA_LOADER_CREATED:
            switch (currentStatus) {
            switch (currentStatus) {
                case IDataLoaderStatusListener::DATA_LOADER_DESTROYED:
                case IDataLoaderStatusListener::DATA_LOADER_DESTROYED:
                case IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE:
                    return bind();
                    return bind();
                case IDataLoaderStatusListener::DATA_LOADER_BOUND:
                case IDataLoaderStatusListener::DATA_LOADER_BOUND:
                    return create();
                    return create();
@@ -1825,9 +1833,15 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount
        if (mCurrentStatus == newStatus) {
        if (mCurrentStatus == newStatus) {
            return binder::Status::ok();
            return binder::Status::ok();
        }
        }

        oldStatus = mCurrentStatus;
        oldStatus = mCurrentStatus;
        mCurrentStatus = newStatus;
        mCurrentStatus = newStatus;
        targetStatus = mTargetStatus;
        targetStatus = mTargetStatus;

        if (mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE) {
            // For unavailable, reset target status.
            setTargetStatusLocked(IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
        }
    }
    }


    LOG(DEBUG) << "Current status update for DataLoader " << mId << ": " << oldStatus << " -> "
    LOG(DEBUG) << "Current status update for DataLoader " << mId << ": " << oldStatus << " -> "
+1 −0
Original line number Original line Diff line number Diff line
@@ -187,6 +187,7 @@ private:
        bool destroy();
        bool destroy();


        bool setTargetStatus(int status);
        bool setTargetStatus(int status);
        void setTargetStatusLocked(int status);
        bool waitForStatus(int status, Clock::duration duration);
        bool waitForStatus(int status, Clock::duration duration);


        bool fsmStep();
        bool fsmStep();