/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <binder/ParcelFileDescriptor.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <utils/Log.h>
#include <utils/String16.h>

#include <chrono>
#include <future>

#include "IncrementalService.h"
#include "IncrementalServiceValidation.h"
#include "Metadata.pb.h"
#include "ServiceWrappers.h"

using namespace testing;
using namespace android::incremental;
using namespace std::literals;
using testing::_;
using testing::Invoke;
using testing::NiceMock;

#undef LOG_TAG
#define LOG_TAG "IncrementalServiceTest"

using namespace android::incfs;
using namespace android::content::pm;
using PerUidReadTimeouts = android::os::incremental::PerUidReadTimeouts;

namespace android::os::incremental {

class MockVoldService : public VoldServiceWrapper {
public:
    MOCK_CONST_METHOD5(mountIncFs,
                       binder::Status(const std::string& backingPath, const std::string& targetDir,
                                      int32_t flags, const std::string& sysfsName,
                                      IncrementalFileSystemControlParcel* _aidl_return));
    MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
    MOCK_CONST_METHOD2(bindMount,
                       binder::Status(const std::string& sourceDir, const std::string& argetDir));
    MOCK_CONST_METHOD4(
            setIncFsMountOptions,
            binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&,
                           bool, bool, const std::string&));

    void mountIncFsFails() {
        ON_CALL(*this, mountIncFs(_, _, _, _, _))
                .WillByDefault(
                        Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
    }
    void mountIncFsInvalidControlParcel() {
        ON_CALL(*this, mountIncFs(_, _, _, _, _))
                .WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
    }
    void mountIncFsSuccess() {
        ON_CALL(*this, mountIncFs(_, _, _, _, _))
                .WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
    }
    void bindMountFails() {
        ON_CALL(*this, bindMount(_, _))
                .WillByDefault(Return(
                        binder::Status::fromExceptionCode(1, String8("failed to bind-mount"))));
    }
    void bindMountSuccess() {
        ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
    }
    void setIncFsMountOptionsFails() const {
        ON_CALL(*this, setIncFsMountOptions(_, _, _, _))
                .WillByDefault(Return(
                        binder::Status::fromExceptionCode(1, String8("failed to set options"))));
    }
    void setIncFsMountOptionsSuccess() {
        ON_CALL(*this, setIncFsMountOptions(_, _, _, _))
                .WillByDefault(Invoke(this, &MockVoldService::setIncFsMountOptionsOk));
    }
    binder::Status getInvalidControlParcel(const std::string& imagePath,
                                           const std::string& targetDir, int32_t flags,
                                           const std::string& sysfsName,
                                           IncrementalFileSystemControlParcel* _aidl_return) {
        _aidl_return = {};
        return binder::Status::ok();
    }
    binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
                                int32_t flags, const std::string& sysfsName,
                                IncrementalFileSystemControlParcel* _aidl_return) {
        _aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
        _aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
        _aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
        return binder::Status::ok();
    }
    binder::Status setIncFsMountOptionsOk(
            const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
            bool enableReadLogs, bool enableReadTimeouts, const std::string& sysfsName) {
        mReadLogsEnabled = enableReadLogs;
        mReadTimeoutsEnabled = enableReadTimeouts;
        return binder::Status::ok();
    }

    bool readLogsEnabled() const { return mReadLogsEnabled; }
    bool readTimeoutsEnabled() const { return mReadTimeoutsEnabled; }

private:
    TemporaryFile cmdFile;
    TemporaryFile logFile;

    bool mReadLogsEnabled = false;
    bool mReadTimeoutsEnabled = true;
};

class MockDataLoader : public IDataLoader {
public:
    MockDataLoader() {
        initializeCreateOk();
        ON_CALL(*this, start(_)).WillByDefault(Invoke(this, &MockDataLoader::startOk));
        ON_CALL(*this, stop(_)).WillByDefault(Invoke(this, &MockDataLoader::stopOk));
        ON_CALL(*this, destroy(_)).WillByDefault(Invoke(this, &MockDataLoader::destroyOk));
        ON_CALL(*this, prepareImage(_, _, _))
                .WillByDefault(Invoke(this, &MockDataLoader::prepareImageOk));
    }
    IBinder* onAsBinder() override { return nullptr; }
    MOCK_METHOD4(create,
                 binder::Status(int32_t id, const DataLoaderParamsParcel& params,
                                const FileSystemControlParcel& control,
                                const sp<IDataLoaderStatusListener>& listener));
    MOCK_METHOD1(start, binder::Status(int32_t id));
    MOCK_METHOD1(stop, binder::Status(int32_t id));
    MOCK_METHOD1(destroy, binder::Status(int32_t id));
    MOCK_METHOD3(prepareImage,
                 binder::Status(int32_t id, const std::vector<InstallationFileParcel>& addedFiles,
                                const std::vector<std::string>& removedFiles));

    void initializeCreateOk() {
        ON_CALL(*this, create(_, _, _, _)).WillByDefault(Invoke(this, &MockDataLoader::createOk));
    }

    void initializeCreateOkNoStatus() {
        ON_CALL(*this, create(_, _, _, _))
                .WillByDefault(Invoke(this, &MockDataLoader::createOkNoStatus));
    }

    binder::Status createOk(int32_t id, const content::pm::DataLoaderParamsParcel& params,
                            const content::pm::FileSystemControlParcel& control,
                            const sp<content::pm::IDataLoaderStatusListener>& listener) {
        createOkNoStatus(id, params, control, listener);
        reportStatus(id);
        return binder::Status::ok();
    }
    binder::Status createOkNoStatus(int32_t id, const content::pm::DataLoaderParamsParcel& params,
                                    const content::pm::FileSystemControlParcel& control,
                                    const sp<content::pm::IDataLoaderStatusListener>& listener) {
        mServiceConnector = control.service;
        mListener = listener;
        mStatus = IDataLoaderStatusListener::DATA_LOADER_CREATED;
        return binder::Status::ok();
    }
    binder::Status startOk(int32_t id) {
        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_STARTED);
        return binder::Status::ok();
    }
    binder::Status stopOk(int32_t id) {
        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_STOPPED);
        return binder::Status::ok();
    }
    binder::Status destroyOk(int32_t id) {
        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
        mListener = nullptr;
        return binder::Status::ok();
    }
    binder::Status prepareImageOk(int32_t id,
                                  const ::std::vector<content::pm::InstallationFileParcel>&,
                                  const ::std::vector<::std::string>&) {
        setAndReportStatus(id, IDataLoaderStatusListener::DATA_LOADER_IMAGE_READY);
        return binder::Status::ok();
    }
    int32_t setStorageParams(bool enableReadLogs) {
        int32_t result = -1;
        EXPECT_NE(mServiceConnector.get(), nullptr);
        EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk());
        return result;
    }
    int status() const { return mStatus; }

private:
    void setAndReportStatus(int id, int status) {
        mStatus = status;
        reportStatus(id);
    }
    void reportStatus(int id) {
        if (mListener) {
            mListener->onStatusChanged(id, mStatus);
        }
    }

    sp<IIncrementalServiceConnector> mServiceConnector;
    sp<IDataLoaderStatusListener> mListener;
    int mStatus = IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
};

class MockDataLoaderManager : public DataLoaderManagerWrapper {
public:
    MockDataLoaderManager(sp<IDataLoader> dataLoader) : mDataLoaderHolder(std::move(dataLoader)) {
        EXPECT_TRUE(mDataLoaderHolder != nullptr);
    }

    MOCK_CONST_METHOD5(bindToDataLoader,
                       binder::Status(int32_t mountId, const DataLoaderParamsParcel& params,
                                      int bindDelayMs,
                                      const sp<IDataLoaderStatusListener>& listener,
                                      bool* _aidl_return));
    MOCK_CONST_METHOD2(getDataLoader,
                       binder::Status(int32_t mountId, sp<IDataLoader>* _aidl_return));
    MOCK_CONST_METHOD1(unbindFromDataLoader, binder::Status(int32_t mountId));

    void bindToDataLoaderSuccess() {
        ON_CALL(*this, bindToDataLoader(_, _, _, _, _))
                .WillByDefault(Invoke(this, &MockDataLoaderManager::bindToDataLoaderOk));
    }
    void bindToDataLoaderFails() {
        ON_CALL(*this, bindToDataLoader(_, _, _, _, _))
                .WillByDefault(Return(
                        (binder::Status::fromExceptionCode(1, String8("failed to prepare")))));
    }
    void getDataLoaderSuccess() {
        ON_CALL(*this, getDataLoader(_, _))
                .WillByDefault(Invoke(this, &MockDataLoaderManager::getDataLoaderOk));
    }
    void unbindFromDataLoaderSuccess() {
        ON_CALL(*this, unbindFromDataLoader(_))
                .WillByDefault(Invoke(this, &MockDataLoaderManager::unbindFromDataLoaderOk));
    }
    binder::Status bindToDataLoaderOk(int32_t mountId, const DataLoaderParamsParcel& params,
                                      int bindDelayMs,
                                      const sp<IDataLoaderStatusListener>& listener,
                                      bool* _aidl_return) {
        mId = mountId;
        mListener = listener;
        mDataLoader = mDataLoaderHolder;
        mBindDelayMs = bindDelayMs;
        *_aidl_return = true;
        if (mListener) {
            mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BOUND);
        }
        return binder::Status::ok();
    }
    binder::Status bindToDataLoaderNotOkWithNoDelay(int32_t mountId,
                                                    const DataLoaderParamsParcel& params,
                                                    int bindDelayMs,
                                                    const sp<IDataLoaderStatusListener>& listener,
                                                    bool* _aidl_return) {
        CHECK(bindDelayMs == 0) << bindDelayMs;
        *_aidl_return = false;
        return binder::Status::ok();
    }
    binder::Status bindToDataLoaderBindingWithNoDelay(int32_t mountId,
                                                      const DataLoaderParamsParcel& params,
                                                      int bindDelayMs,
                                                      const sp<IDataLoaderStatusListener>& listener,
                                                      bool* _aidl_return) {
        CHECK(bindDelayMs == 0) << bindDelayMs;
        *_aidl_return = true;
        if (listener) {
            listener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_BINDING);
        }
        return binder::Status::ok();
    }
    binder::Status bindToDataLoaderOkWithNoDelay(int32_t mountId,
                                                 const DataLoaderParamsParcel& params,
                                                 int bindDelayMs,
                                                 const sp<IDataLoaderStatusListener>& listener,
                                                 bool* _aidl_return) {
        CHECK(bindDelayMs == 0) << bindDelayMs;
        return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
    }
    binder::Status bindToDataLoaderOkWith1sDelay(int32_t mountId,
                                                 const DataLoaderParamsParcel& params,
                                                 int bindDelayMs,
                                                 const sp<IDataLoaderStatusListener>& listener,
                                                 bool* _aidl_return) {
        CHECK(100 * 9 <= bindDelayMs && bindDelayMs <= 100 * 11) << bindDelayMs;
        return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
    }
    binder::Status bindToDataLoaderOkWith10sDelay(int32_t mountId,
                                                  const DataLoaderParamsParcel& params,
                                                  int bindDelayMs,
                                                  const sp<IDataLoaderStatusListener>& listener,
                                                  bool* _aidl_return) {
        CHECK(100 * 9 * 9 <= bindDelayMs && bindDelayMs <= 100 * 11 * 11) << bindDelayMs;
        return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
    }
    binder::Status bindToDataLoaderOkWith100sDelay(int32_t mountId,
                                                   const DataLoaderParamsParcel& params,
                                                   int bindDelayMs,
                                                   const sp<IDataLoaderStatusListener>& listener,
                                                   bool* _aidl_return) {
        CHECK(100 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 100 * 11 * 11 * 11) << bindDelayMs;
        return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
    }
    binder::Status bindToDataLoaderOkWith1000sDelay(int32_t mountId,
                                                    const DataLoaderParamsParcel& params,
                                                    int bindDelayMs,
                                                    const sp<IDataLoaderStatusListener>& listener,
                                                    bool* _aidl_return) {
        CHECK(100 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 100 * 11 * 11 * 11 * 11)
                << bindDelayMs;
        return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
    }
    binder::Status bindToDataLoaderOkWith10000sDelay(int32_t mountId,
                                                     const DataLoaderParamsParcel& params,
                                                     int bindDelayMs,
                                                     const sp<IDataLoaderStatusListener>& listener,
                                                     bool* _aidl_return) {
        CHECK(100 * 9 * 9 * 9 * 9 * 9 < bindDelayMs && bindDelayMs < 100 * 11 * 11 * 11 * 11 * 11)
                << bindDelayMs;
        return bindToDataLoaderOk(mountId, params, bindDelayMs, listener, _aidl_return);
    }

    binder::Status getDataLoaderOk(int32_t mountId, sp<IDataLoader>* _aidl_return) {
        *_aidl_return = mDataLoader;
        return binder::Status::ok();
    }
    void setDataLoaderStatusCreated() {
        mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
    }
    void setDataLoaderStatusStarted() {
        mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_STARTED);
    }
    void setDataLoaderStatusDestroyed() {
        mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
    }
    void setDataLoaderStatusUnavailable() {
        mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
    }
    void setDataLoaderStatusUnrecoverable() {
        mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_UNRECOVERABLE);
    }
    binder::Status unbindFromDataLoaderOk(int32_t id) {
        mBindDelayMs = -1;
        if (mDataLoader) {
            if (auto status = mDataLoader->destroy(id); !status.isOk()) {
                return status;
            }
            mDataLoader = nullptr;
        } else if (mListener) {
            mListener->onStatusChanged(id, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
        }
        return binder::Status::ok();
    }

    int bindDelayMs() const { return mBindDelayMs; }

private:
    int mId = -1;
    int mBindDelayMs = -1;
    sp<IDataLoaderStatusListener> mListener;
    sp<IDataLoader> mDataLoader;
    sp<IDataLoader> mDataLoaderHolder;
};

class MockIncFs : public IncFsWrapper {
public:
    MOCK_CONST_METHOD0(features, Features());
    MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb));
    MOCK_CONST_METHOD1(openMount, Control(std::string_view path));
    MOCK_CONST_METHOD4(createControl,
                       Control(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs,
                               IncFsFd blocksWritten));
    MOCK_CONST_METHOD5(makeFile,
                       ErrorCode(const Control& control, std::string_view path, int mode, FileId id,
                                 NewFileParams params));
    MOCK_CONST_METHOD4(makeMappedFile,
                       ErrorCode(const Control& control, std::string_view path, int mode,
                                 NewMappedFileParams params));
    MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode));
    MOCK_CONST_METHOD3(makeDirs,
                       ErrorCode(const Control& control, std::string_view path, int mode));
    MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, FileId fileid));
    MOCK_CONST_METHOD2(getMetadata, RawMetadata(const Control& control, std::string_view path));
    MOCK_CONST_METHOD2(getFileId, FileId(const Control& control, std::string_view path));
    MOCK_CONST_METHOD2(countFilledBlocks,
                       std::pair<IncFsBlockIndex, IncFsBlockIndex>(const Control& control,
                                                                   std::string_view path));
    MOCK_CONST_METHOD2(isFileFullyLoaded,
                       incfs::LoadingState(const Control& control, std::string_view path));
    MOCK_CONST_METHOD2(isFileFullyLoaded, incfs::LoadingState(const Control& control, FileId id));
    MOCK_CONST_METHOD1(isEverythingFullyLoaded, incfs::LoadingState(const Control& control));
    MOCK_CONST_METHOD3(link,
                       ErrorCode(const Control& control, std::string_view from,
                                 std::string_view to));
    MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
    MOCK_CONST_METHOD2(openForSpecialOps, UniqueFd(const Control& control, FileId id));
    MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
    MOCK_CONST_METHOD3(reserveSpace, ErrorCode(const Control& control, FileId id, IncFsSize size));
    MOCK_CONST_METHOD3(waitForPendingReads,
                       WaitResult(const Control& control, std::chrono::milliseconds timeout,
                                  std::vector<incfs::ReadInfoWithUid>* pendingReadsBuffer));
    MOCK_CONST_METHOD2(setUidReadTimeouts,
                       ErrorCode(const Control& control,
                                 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
    MOCK_CONST_METHOD2(forEachFile, ErrorCode(const Control& control, FileCallback cb));
    MOCK_CONST_METHOD2(forEachIncompleteFile, ErrorCode(const Control& control, FileCallback cb));
    MOCK_CONST_METHOD1(getMetrics, std::optional<Metrics>(std::string_view path));
    MOCK_CONST_METHOD1(getLastReadError, std::optional<LastReadError>(const Control& control));

    MockIncFs() {
        ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return());
        ON_CALL(*this, reserveSpace(_, _, _)).WillByDefault(Return(0));
    }

    void makeFileFails() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(-1)); }
    void makeFileSuccess() { ON_CALL(*this, makeFile(_, _, _, _, _)).WillByDefault(Return(0)); }

    void countFilledBlocksSuccess() {
        ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(1, 2)));
    }

    void countFilledBlocksFullyLoaded() {
        ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(10000, 10000)));
    }

    void countFilledBlocksFails() {
        ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(-1, -1)));
    }

    void countFilledBlocksEmpty() {
        ON_CALL(*this, countFilledBlocks(_, _)).WillByDefault(Return(std::make_pair(0, 0)));
    }

    void openMountSuccess() {
        ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
    }

    // 1000ms
    void waitForPendingReadsSuccess(uint64_t ts = 0) {
        ON_CALL(*this, waitForPendingReads(_, _, _))
                .WillByDefault(
                        Invoke([ts](const Control& control, std::chrono::milliseconds timeout,
                                    std::vector<incfs::ReadInfoWithUid>* pendingReadsBuffer) {
                            pendingReadsBuffer->push_back({.bootClockTsUs = ts});
                            return android::incfs::WaitResult::HaveData;
                        }));
    }

    void waitForPendingReadsTimeout() {
        ON_CALL(*this, waitForPendingReads(_, _, _))
                .WillByDefault(Return(android::incfs::WaitResult::Timeout));
    }

    static constexpr auto kPendingReadsFd = 42;
    Control openMountForHealth(std::string_view) {
        return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1, -1));
    }

    RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
        metadata::Mount m;
        m.mutable_storage()->set_id(100);
        m.mutable_loader()->set_package_name("com.test");
        m.mutable_loader()->set_arguments("com.uri");
        const auto metadata = m.SerializeAsString();
        static_cast<void>(m.mutable_loader()->release_arguments());
        static_cast<void>(m.mutable_loader()->release_package_name());
        return {metadata.begin(), metadata.end()};
    }
    RawMetadata getStorageMetadata(const Control& control, std::string_view path) {
        metadata::Storage st;
        st.set_id(100);
        auto metadata = st.SerializeAsString();
        return {metadata.begin(), metadata.end()};
    }
    RawMetadata getBindPointMetadata(const Control& control, std::string_view path) {
        metadata::BindPoint bp;
        std::string destPath = "dest";
        std::string srcPath = "src";
        bp.set_storage_id(100);
        bp.set_allocated_dest_path(&destPath);
        bp.set_allocated_source_subdir(&srcPath);
        const auto metadata = bp.SerializeAsString();
        static_cast<void>(bp.release_source_subdir());
        static_cast<void>(bp.release_dest_path());
        return std::vector<char>(metadata.begin(), metadata.end());
    }
};

class MockAppOpsManager : public AppOpsManagerWrapper {
public:
    MOCK_CONST_METHOD3(checkPermission, binder::Status(const char*, const char*, const char*));
    MOCK_METHOD3(startWatchingMode, void(int32_t, const String16&, const sp<IAppOpsCallback>&));
    MOCK_METHOD1(stopWatchingMode, void(const sp<IAppOpsCallback>&));

    void checkPermissionSuccess() {
        ON_CALL(*this, checkPermission(_, _, _)).WillByDefault(Return(android::incremental::Ok()));
    }
    void checkPermissionNoCrossUsers() {
        ON_CALL(*this,
                checkPermission("android.permission.LOADER_USAGE_STATS",
                                "android:loader_usage_stats", _))
                .WillByDefault(Return(android::incremental::Ok()));
        ON_CALL(*this, checkPermission("android.permission.INTERACT_ACROSS_USERS", nullptr, _))
                .WillByDefault(
                        Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
    }
    void checkPermissionFails() {
        ON_CALL(*this, checkPermission(_, _, _))
                .WillByDefault(
                        Return(android::incremental::Exception(binder::Status::EX_SECURITY, {})));
    }
    void initializeStartWatchingMode() {
        ON_CALL(*this, startWatchingMode(_, _, _))
                .WillByDefault(Invoke(this, &MockAppOpsManager::storeCallback));
    }
    void storeCallback(int32_t, const String16&, const sp<IAppOpsCallback>& cb) {
        mStoredCallback = cb;
    }

    sp<IAppOpsCallback> mStoredCallback;
};

class MockJniWrapper : public JniWrapper {
public:
    MOCK_CONST_METHOD0(initializeForCurrentThread, void());

    MockJniWrapper() { EXPECT_CALL(*this, initializeForCurrentThread()).Times(2); }
};

class MockLooperWrapper : public LooperWrapper {
public:
    MOCK_METHOD5(addFd, int(int, int, int, android::Looper_callbackFunc, void*));
    MOCK_METHOD1(removeFd, int(int));
    MOCK_METHOD0(wake, void());
    MOCK_METHOD1(pollAll, int(int));

    MockLooperWrapper() {
        ON_CALL(*this, addFd(_, _, _, _, _))
                .WillByDefault(Invoke(this, &MockLooperWrapper::storeCallback));
        ON_CALL(*this, removeFd(_)).WillByDefault(Invoke(this, &MockLooperWrapper::clearCallback));
        ON_CALL(*this, pollAll(_)).WillByDefault(Invoke(this, &MockLooperWrapper::wait10Ms));
    }

    int storeCallback(int, int, int, android::Looper_callbackFunc callback, void* data) {
        mCallback = callback;
        mCallbackData = data;
        return 0;
    }

    int clearCallback(int) {
        mCallback = nullptr;
        mCallbackData = nullptr;
        return 0;
    }

    int wait10Ms(int) {
        // This is called from a loop in runCmdLooper.
        // Sleeping for 10ms only to avoid busy looping.
        std::this_thread::sleep_for(10ms);
        return 0;
    }

    android::Looper_callbackFunc mCallback = nullptr;
    void* mCallbackData = nullptr;
};

class MockTimedQueueWrapper : public TimedQueueWrapper {
public:
    MOCK_METHOD3(addJob, void(MountId, Milliseconds, Job));
    MOCK_METHOD1(removeJobs, void(MountId));
    MOCK_METHOD0(stop, void());

    MockTimedQueueWrapper() {
        ON_CALL(*this, addJob(_, _, _))
                .WillByDefault(Invoke(this, &MockTimedQueueWrapper::storeJob));
        ON_CALL(*this, removeJobs(_)).WillByDefault(Invoke(this, &MockTimedQueueWrapper::clearJob));
    }

    void storeJob(MountId id, Milliseconds after, Job what) {
        mId = id;
        mAfter = after;
        mWhat = std::move(what);
    }

    void clearJob(MountId id) {
        if (mId == id) {
            mAfter = {};
            mWhat = {};
        }
    }

    MountId mId = -1;
    Milliseconds mAfter;
    Job mWhat;
};

class MockFsWrapper : public FsWrapper {
public:
    MOCK_CONST_METHOD2(listFilesRecursive, void(std::string_view, FileCallback));
    void hasNoFile() { ON_CALL(*this, listFilesRecursive(_, _)).WillByDefault(Return()); }
    void hasFiles() {
        ON_CALL(*this, listFilesRecursive(_, _))
                .WillByDefault(Invoke(this, &MockFsWrapper::fakeFiles));
    }
    void fakeFiles(std::string_view directoryPath, FileCallback onFile) {
        for (auto file : {"base.apk", "split.apk", "lib/a.so"}) {
            if (!onFile(file)) break;
        }
    }
};

class MockClockWrapper : public ClockWrapper {
public:
    MOCK_CONST_METHOD0(now, TimePoint());

    void start() { ON_CALL(*this, now()).WillByDefault(Invoke(this, &MockClockWrapper::getClock)); }

    template <class Delta>
    void advance(Delta delta) {
        mClock += delta;
    }

    void advanceMs(int deltaMs) { mClock += std::chrono::milliseconds(deltaMs); }

    TimePoint getClock() const { return mClock; }
    std::optional<timespec> getClockMono() const {
        const auto nsSinceEpoch =
                std::chrono::duration_cast<std::chrono::nanoseconds>(mClock.time_since_epoch())
                        .count();
        timespec ts = {.tv_sec = static_cast<time_t>(nsSinceEpoch / 1000000000LL),
                       .tv_nsec = static_cast<long>(nsSinceEpoch % 1000000000LL)};
        return ts;
    }

    TimePoint mClock = Clock::now();
};

class MockStorageHealthListener : public os::incremental::BnStorageHealthListener {
public:
    MOCK_METHOD2(onHealthStatus, binder::Status(int32_t storageId, int32_t status));

    MockStorageHealthListener() {
        ON_CALL(*this, onHealthStatus(_, _))
                .WillByDefault(Invoke(this, &MockStorageHealthListener::storeStorageIdAndStatus));
    }

    binder::Status storeStorageIdAndStatus(int32_t storageId, int32_t status) {
        mStorageId = storageId;
        mStatus = status;
        return binder::Status::ok();
    }

    int32_t mStorageId = -1;
    int32_t mStatus = -1;
};

class MockStorageLoadingProgressListener : public IStorageLoadingProgressListener {
public:
    MockStorageLoadingProgressListener() = default;
    MOCK_METHOD2(onStorageLoadingProgressChanged,
                 binder::Status(int32_t storageId, float progress));
    MOCK_METHOD0(onAsBinder, IBinder*());
};

class MockServiceManager : public ServiceManagerWrapper {
public:
    MockServiceManager(std::unique_ptr<MockVoldService> vold,
                       std::unique_ptr<MockDataLoaderManager> dataLoaderManager,
                       std::unique_ptr<MockIncFs> incfs,
                       std::unique_ptr<MockAppOpsManager> appOpsManager,
                       std::unique_ptr<MockJniWrapper> jni,
                       std::unique_ptr<MockLooperWrapper> looper,
                       std::unique_ptr<MockTimedQueueWrapper> timedQueue,
                       std::unique_ptr<MockTimedQueueWrapper> progressUpdateJobQueue,
                       std::unique_ptr<MockFsWrapper> fs, std::unique_ptr<MockClockWrapper> clock)
          : mVold(std::move(vold)),
            mDataLoaderManager(std::move(dataLoaderManager)),
            mIncFs(std::move(incfs)),
            mAppOpsManager(std::move(appOpsManager)),
            mJni(std::move(jni)),
            mLooper(std::move(looper)),
            mTimedQueue(std::move(timedQueue)),
            mProgressUpdateJobQueue(std::move(progressUpdateJobQueue)),
            mFs(std::move(fs)),
            mClock(std::move(clock)) {}
    std::unique_ptr<VoldServiceWrapper> getVoldService() final { return std::move(mVold); }
    std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final {
        return std::move(mDataLoaderManager);
    }
    std::unique_ptr<IncFsWrapper> getIncFs() final { return std::move(mIncFs); }
    std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final {
        return std::move(mAppOpsManager);
    }
    std::unique_ptr<JniWrapper> getJni() final { return std::move(mJni); }
    std::unique_ptr<LooperWrapper> getLooper() final { return std::move(mLooper); }
    std::unique_ptr<TimedQueueWrapper> getTimedQueue() final { return std::move(mTimedQueue); }
    std::unique_ptr<TimedQueueWrapper> getProgressUpdateJobQueue() final {
        return std::move(mProgressUpdateJobQueue);
    }
    std::unique_ptr<FsWrapper> getFs() final { return std::move(mFs); }
    std::unique_ptr<ClockWrapper> getClock() final { return std::move(mClock); }

private:
    std::unique_ptr<MockVoldService> mVold;
    std::unique_ptr<MockDataLoaderManager> mDataLoaderManager;
    std::unique_ptr<MockIncFs> mIncFs;
    std::unique_ptr<MockAppOpsManager> mAppOpsManager;
    std::unique_ptr<MockJniWrapper> mJni;
    std::unique_ptr<MockLooperWrapper> mLooper;
    std::unique_ptr<MockTimedQueueWrapper> mTimedQueue;
    std::unique_ptr<MockTimedQueueWrapper> mProgressUpdateJobQueue;
    std::unique_ptr<MockFsWrapper> mFs;
    std::unique_ptr<MockClockWrapper> mClock;
};

// --- IncrementalServiceTest ---

class IncrementalServiceTest : public testing::Test {
public:
    void SetUp() override {
        auto vold = std::make_unique<NiceMock<MockVoldService>>();
        mVold = vold.get();
        sp<NiceMock<MockDataLoader>> dataLoader{new NiceMock<MockDataLoader>};
        mDataLoader = dataLoader.get();
        auto dataloaderManager = std::make_unique<NiceMock<MockDataLoaderManager>>(dataLoader);
        mDataLoaderManager = dataloaderManager.get();
        auto incFs = std::make_unique<NiceMock<MockIncFs>>();
        mIncFs = incFs.get();
        auto appOps = std::make_unique<NiceMock<MockAppOpsManager>>();
        mAppOpsManager = appOps.get();
        auto jni = std::make_unique<NiceMock<MockJniWrapper>>();
        mJni = jni.get();
        auto looper = std::make_unique<NiceMock<MockLooperWrapper>>();
        mLooper = looper.get();
        auto timedQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
        mTimedQueue = timedQueue.get();
        auto progressUpdateJobQueue = std::make_unique<NiceMock<MockTimedQueueWrapper>>();
        mProgressUpdateJobQueue = progressUpdateJobQueue.get();
        auto fs = std::make_unique<NiceMock<MockFsWrapper>>();
        mFs = fs.get();
        auto clock = std::make_unique<NiceMock<MockClockWrapper>>();
        mClock = clock.get();
        mIncrementalService = std::make_unique<
                IncrementalService>(MockServiceManager(std::move(vold),
                                                       std::move(dataloaderManager),
                                                       std::move(incFs), std::move(appOps),
                                                       std::move(jni), std::move(looper),
                                                       std::move(timedQueue),
                                                       std::move(progressUpdateJobQueue),
                                                       std::move(fs), std::move(clock)),
                                    mRootDir.path);
        mDataLoaderParcel.packageName = "com.test";
        mDataLoaderParcel.arguments = "uri";
        mDataLoaderManager->unbindFromDataLoaderSuccess();
        mIncrementalService->onSystemReady();
        mClock->start();
        setupSuccess();
    }

    void setUpExistingMountDir(const std::string& rootDir) {
        const auto dir = rootDir + "/dir1";
        const auto mountDir = dir + "/mount";
        const auto backingDir = dir + "/backing_store";
        const auto storageDir = mountDir + "/st0";
        ASSERT_EQ(0, mkdir(dir.c_str(), 0755));
        ASSERT_EQ(0, mkdir(mountDir.c_str(), 0755));
        ASSERT_EQ(0, mkdir(backingDir.c_str(), 0755));
        ASSERT_EQ(0, mkdir(storageDir.c_str(), 0755));
        const auto mountInfoFile = rootDir + "/dir1/mount/.info";
        const auto mountPointsFile = rootDir + "/dir1/mount/.mountpoint.abcd";
        ASSERT_TRUE(base::WriteStringToFile("info", mountInfoFile));
        ASSERT_TRUE(base::WriteStringToFile("mounts", mountPointsFile));
        ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountInfoFile)))
                .WillByDefault(Invoke(mIncFs, &MockIncFs::getMountInfoMetadata));
        ON_CALL(*mIncFs, getMetadata(_, std::string_view(mountPointsFile)))
                .WillByDefault(Invoke(mIncFs, &MockIncFs::getBindPointMetadata));
        ON_CALL(*mIncFs, getMetadata(_, std::string_view(rootDir + "/dir1/mount/st0")))
                .WillByDefault(Invoke(mIncFs, &MockIncFs::getStorageMetadata));
    }

    void setupSuccess() {
        mVold->mountIncFsSuccess();
        mIncFs->makeFileSuccess();
        mVold->bindMountSuccess();
        mDataLoaderManager->bindToDataLoaderSuccess();
        mDataLoaderManager->getDataLoaderSuccess();
    }

    void checkHealthMetrics(int storageId, long expectedMillisSinceOldestPendingRead,
                            int expectedStorageHealthStatusCode) {
        android::os::PersistableBundle result{};
        mIncrementalService->getMetrics(storageId, &result);
        ASSERT_EQ(6, (int)result.size());
        int64_t millisSinceOldestPendingRead = -1;
        ASSERT_TRUE(result.getLong(String16(BnIncrementalService::
                                                    METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
                                                            .c_str()),
                                   &millisSinceOldestPendingRead));
        // Allow 10ms.
        ASSERT_LE(expectedMillisSinceOldestPendingRead, millisSinceOldestPendingRead);
        ASSERT_GE(expectedMillisSinceOldestPendingRead + 10, millisSinceOldestPendingRead);
        int storageHealthStatusCode = -1;
        ASSERT_TRUE(
                result.getInt(String16(BnIncrementalService::METRICS_STORAGE_HEALTH_STATUS_CODE()
                                               .c_str()),
                              &storageHealthStatusCode));
        ASSERT_EQ(expectedStorageHealthStatusCode, storageHealthStatusCode);
        int dataLoaderStatusCode = -1;
        ASSERT_TRUE(result.getInt(String16(BnIncrementalService::METRICS_DATA_LOADER_STATUS_CODE()
                                                   .c_str()),
                                  &dataLoaderStatusCode));
        ASSERT_EQ(IDataLoaderStatusListener::DATA_LOADER_STARTED, dataLoaderStatusCode);
    }

    void checkBindingMetrics(int storageId, int64_t expectedMillisSinceLastDataLoaderBind,
                             int64_t expectedDataLoaderBindDelayMillis) {
        android::os::PersistableBundle result{};
        mIncrementalService->getMetrics(storageId, &result);
        ASSERT_EQ(6, (int)result.size());
        int dataLoaderStatus = -1;
        ASSERT_TRUE(result.getInt(String16(BnIncrementalService::METRICS_DATA_LOADER_STATUS_CODE()
                                                   .c_str()),
                                  &dataLoaderStatus));
        ASSERT_EQ(IDataLoaderStatusListener::DATA_LOADER_STARTED, dataLoaderStatus);
        int64_t millisSinceLastDataLoaderBind = -1;
        ASSERT_TRUE(result.getLong(String16(BnIncrementalService::
                                                    METRICS_MILLIS_SINCE_LAST_DATA_LOADER_BIND()
                                                            .c_str()),
                                   &millisSinceLastDataLoaderBind));
        ASSERT_EQ(expectedMillisSinceLastDataLoaderBind, millisSinceLastDataLoaderBind);
        int64_t dataLoaderBindDelayMillis = -1;
        ASSERT_TRUE(
                result.getLong(String16(
                                       BnIncrementalService::METRICS_DATA_LOADER_BIND_DELAY_MILLIS()
                                               .c_str()),
                               &dataLoaderBindDelayMillis));
        ASSERT_EQ(expectedDataLoaderBindDelayMillis, dataLoaderBindDelayMillis);
    }

protected:
    NiceMock<MockVoldService>* mVold = nullptr;
    NiceMock<MockIncFs>* mIncFs = nullptr;
    NiceMock<MockDataLoaderManager>* mDataLoaderManager = nullptr;
    NiceMock<MockAppOpsManager>* mAppOpsManager = nullptr;
    NiceMock<MockJniWrapper>* mJni = nullptr;
    NiceMock<MockLooperWrapper>* mLooper = nullptr;
    NiceMock<MockTimedQueueWrapper>* mTimedQueue = nullptr;
    NiceMock<MockTimedQueueWrapper>* mProgressUpdateJobQueue = nullptr;
    NiceMock<MockFsWrapper>* mFs = nullptr;
    NiceMock<MockClockWrapper>* mClock = nullptr;
    NiceMock<MockDataLoader>* mDataLoader = nullptr;
    std::unique_ptr<IncrementalService> mIncrementalService;
    TemporaryDir mRootDir;
    DataLoaderParamsParcel mDataLoaderParcel;
};

TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) {
    mVold->mountIncFsFails();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_LT(storageId, 0);
}

TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) {
    mVold->mountIncFsInvalidControlParcel();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_LT(storageId, 0);
}

TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) {
    mVold->mountIncFsSuccess();
    mIncFs->makeFileFails();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
    EXPECT_CALL(*mVold, unmountIncFs(_));
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_LT(storageId, 0);
}

TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) {
    mVold->mountIncFsSuccess();
    mIncFs->makeFileSuccess();
    mVold->bindMountFails();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(0);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
    EXPECT_CALL(*mVold, unmountIncFs(_));
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_LT(storageId, 0);
}

TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) {
    mVold->mountIncFsSuccess();
    mIncFs->makeFileSuccess();
    mVold->bindMountSuccess();
    mDataLoaderManager->bindToDataLoaderFails();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(0);
    EXPECT_CALL(*mDataLoader, start(_)).Times(0);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(0);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
}

TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});
    mIncrementalService->deleteStorage(storageId);
}

TEST_F(IncrementalServiceTest, testDataLoaderDestroyedAndDelayed) {
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(7);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(7);
    EXPECT_CALL(*mDataLoader, start(_)).Times(7);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});

    // Simulated crash/other connection breakage.

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith1sDelay));
    checkBindingMetrics(storageId, 0, 0);
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    checkBindingMetrics(storageId, 0, 0);
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
    checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs());
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(),
                        mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
    checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs());
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(),
                        mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
    checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs());
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(),
                        mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
    checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs());
    // Try the reduced delay, just in case.
    mClock->advanceMs(mDataLoaderManager->bindDelayMs() / 2);
    checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs() / 2,
                        mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
    checkBindingMetrics(storageId, 0, mDataLoaderManager->bindDelayMs());
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    checkBindingMetrics(storageId, mDataLoaderManager->bindDelayMs(),
                        mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();
}

TEST_F(IncrementalServiceTest, testDataLoaderOnRestart) {
    mIncFs->waitForPendingReadsSuccess();
    mIncFs->openMountSuccess();

    constexpr auto bindRetryInterval = 5s;

    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(11);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(7);
    EXPECT_CALL(*mDataLoader, start(_)).Times(7);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);

    // First binds to DataLoader fails... because it's restart.
    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderNotOkWithNoDelay));

    // Request DL start.
    mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {});

    // Retry callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
    auto retryCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // Expecting the same bindToDataLoaderNotOkWithNoDelay call.
    mClock->advance(5s);

    retryCallback();
    // Retry callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, bindRetryInterval);
    retryCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // Returning "binding" so that we can retry.
    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderBindingWithNoDelay));

    // Expecting bindToDataLoaderBindingWithNoDelay call.
    mClock->advance(5s);

    retryCallback();
    // No retry callback.
    ASSERT_EQ(mTimedQueue->mAfter, 0ms);
    ASSERT_EQ(mTimedQueue->mWhat, nullptr);

    // Should not change the bindToDataLoader call count
    ASSERT_NE(nullptr, mLooper->mCallback);
    ASSERT_NE(nullptr, mLooper->mCallbackData);
    auto looperCb = mLooper->mCallback;
    auto looperCbData = mLooper->mCallbackData;
    looperCb(-1, -1, looperCbData);

    // Expecting the same bindToDataLoaderBindingWithNoDelay call.
    mClock->advance(5s);

    // Use pending reads callback to trigger binding.
    looperCb(-1, -1, looperCbData);

    // No retry callback.
    ASSERT_EQ(mTimedQueue->mAfter, 0ms);
    ASSERT_EQ(mTimedQueue->mWhat, nullptr);

    // Now we are out of 10m "retry" budget, let's finally bind.
    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager, &MockDataLoaderManager::bindToDataLoaderOk));
    mClock->advance(11min);

    // Use pending reads callback to trigger binding.
    looperCb(-1, -1, looperCbData);

    // No retry callback.
    ASSERT_EQ(mTimedQueue->mAfter, 0ms);
    ASSERT_EQ(mTimedQueue->mWhat, nullptr);

    // And test the rest of the backoff.
    // Simulated crash/other connection breakage.
    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith1sDelay));
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith100sDelay));
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith1000sDelay));
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith10000sDelay));
    mClock->advanceMs(mDataLoaderManager->bindDelayMs());
    mDataLoaderManager->setDataLoaderStatusDestroyed();
}

TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) {
    mDataLoader->initializeCreateOkNoStatus();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    mDataLoaderManager->setDataLoaderStatusCreated();
    mDataLoaderManager->setDataLoaderStatusStarted();
}

TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
    mDataLoader->initializeCreateOkNoStatus();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    mDataLoaderManager->setDataLoaderStatusCreated();
}

TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) {
    mDataLoader->initializeCreateOkNoStatus();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(0);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    mDataLoaderManager->setDataLoaderStatusUnavailable();
}

TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnrecoverable) {
    mDataLoader->initializeCreateOkNoStatus();
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(0);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    mDataLoaderManager->setDataLoaderStatusUnrecoverable();
}

TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
    mIncFs->waitForPendingReadsSuccess();
    mIncFs->openMountSuccess();
    mDataLoader->initializeCreateOkNoStatus();

    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(2);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
    EXPECT_CALL(*mDataLoader, start(_)).Times(0);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
    EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    mDataLoaderManager->setDataLoaderStatusUnrecoverable();

    // Timed callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_GE(mTimedQueue->mAfter, 10ms);
    auto timedCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // First callback call to propagate unrecoverable.
    timedCallback();

    // And second call to trigger recreation.
    ASSERT_NE(nullptr, mLooper->mCallback);
    ASSERT_NE(nullptr, mLooper->mCallbackData);
    mLooper->mCallback(-1, -1, mLooper->mCallbackData);
}

TEST_F(IncrementalServiceTest, testStartDataLoaderUnavailable) {
    mIncFs->openMountSuccess();
    mDataLoader->initializeCreateOkNoStatus();

    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(3);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(3);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(3);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
    EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);

    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWithNoDelay));

    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));

    // Unavailable.
    mDataLoaderManager->setDataLoaderStatusUnavailable();

    // Timed callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_GE(mTimedQueue->mAfter, 10ms);
    auto timedCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // Propagating unavailable and expecting it to trigger rebind with 1s retry delay.
    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith1sDelay));
    timedCallback();

    // Unavailable #2.
    mDataLoaderManager->setDataLoaderStatusUnavailable();

    // Timed callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_GE(mTimedQueue->mAfter, 10ms);
    timedCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // Propagating unavailable and expecting it to trigger rebind with 10s retry delay.
    // This time succeed.
    mDataLoader->initializeCreateOk();
    ON_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _))
            .WillByDefault(Invoke(mDataLoaderManager,
                                  &MockDataLoaderManager::bindToDataLoaderOkWith10sDelay));
    timedCallback();
}

TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) {
    mIncFs->openMountSuccess();

    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
    EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(6);

    sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
    NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
    EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_OK))
            .Times(2);
    EXPECT_CALL(*listenerMock,
                onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_READS_PENDING))
            .Times(1);
    EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_BLOCKED))
            .Times(1);
    EXPECT_CALL(*listenerMock, onHealthStatus(_, IStorageHealthListener::HEALTH_STATUS_UNHEALTHY))
            .Times(2);

    StorageHealthCheckParams params;
    params.blockedTimeoutMs = 10000;
    params.unhealthyTimeoutMs = 20000;
    params.unhealthyMonitoringMs = 30000;

    using MS = std::chrono::milliseconds;
    using MCS = std::chrono::microseconds;

    const auto blockedTimeout = MS(params.blockedTimeoutMs);
    const auto unhealthyTimeout = MS(params.unhealthyTimeoutMs);
    const auto unhealthyMonitoring = MS(params.unhealthyMonitoringMs);

    const uint64_t kFirstTimestampUs = 1000000000ll;
    const uint64_t kBlockedTimestampUs =
            kFirstTimestampUs - std::chrono::duration_cast<MCS>(blockedTimeout).count();
    const uint64_t kUnhealthyTimestampUs =
            kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count();

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {},
                                      std::move(params), listener, {});

    // Healthy state, registered for pending reads.
    ASSERT_NE(nullptr, mLooper->mCallback);
    ASSERT_NE(nullptr, mLooper->mCallbackData);
    ASSERT_EQ(storageId, listener->mStorageId);
    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
    checkHealthMetrics(storageId, 0, listener->mStatus);

    // Looper/epoll callback.
    mIncFs->waitForPendingReadsSuccess(kFirstTimestampUs);
    mLooper->mCallback(-1, -1, mLooper->mCallbackData);

    // Unregister from pending reads and wait.
    ASSERT_EQ(nullptr, mLooper->mCallback);
    ASSERT_EQ(nullptr, mLooper->mCallbackData);
    ASSERT_EQ(storageId, listener->mStorageId);
    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_READS_PENDING, listener->mStatus);
    // Timed callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_GE(mTimedQueue->mAfter, blockedTimeout);
    auto timedCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // Timed job callback for blocked.
    mIncFs->waitForPendingReadsSuccess(kBlockedTimestampUs);
    timedCallback();

    // Still not registered, and blocked.
    ASSERT_EQ(nullptr, mLooper->mCallback);
    ASSERT_EQ(nullptr, mLooper->mCallbackData);
    ASSERT_EQ(storageId, listener->mStorageId);
    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_BLOCKED, listener->mStatus);
    checkHealthMetrics(storageId, params.blockedTimeoutMs, listener->mStatus);

    // Timed callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_GE(mTimedQueue->mAfter, 1000ms);
    timedCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // Timed job callback for unhealthy.
    mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
    timedCallback();

    // Still not registered, and blocked.
    ASSERT_EQ(nullptr, mLooper->mCallback);
    ASSERT_EQ(nullptr, mLooper->mCallbackData);
    ASSERT_EQ(storageId, listener->mStorageId);
    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
    checkHealthMetrics(storageId, params.unhealthyTimeoutMs, listener->mStatus);

    // Timed callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
    timedCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // One more unhealthy.
    mIncFs->waitForPendingReadsSuccess(kUnhealthyTimestampUs);
    timedCallback();

    // Still not registered, and blocked.
    ASSERT_EQ(nullptr, mLooper->mCallback);
    ASSERT_EQ(nullptr, mLooper->mCallbackData);
    ASSERT_EQ(storageId, listener->mStorageId);
    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_UNHEALTHY, listener->mStatus);
    checkHealthMetrics(storageId, params.unhealthyTimeoutMs, listener->mStatus);

    // Timed callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_GE(mTimedQueue->mAfter, unhealthyMonitoring);
    timedCallback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // And now healthy.
    mIncFs->waitForPendingReadsTimeout();
    timedCallback();

    // Healthy state, registered for pending reads.
    ASSERT_NE(nullptr, mLooper->mCallback);
    ASSERT_NE(nullptr, mLooper->mCallbackData);
    ASSERT_EQ(storageId, listener->mStorageId);
    ASSERT_EQ(IStorageHealthListener::HEALTH_STATUS_OK, listener->mStatus);
    checkHealthMetrics(storageId, 0, listener->mStatus);
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // on startLoading
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(1);
    // We are calling setIncFsMountOptions(true).
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(1);
    // After setIncFsMountOptions succeeded expecting to start watching.
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
    // Not expecting callback removal.
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) {
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // Enabling and then disabling readlogs.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(1);
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(2);
    // After setIncFsMountOptions succeeded expecting to start watching.
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
    // Not expecting callback removal.
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
    // Now disable.
    mIncrementalService->disallowReadLogs(storageId);
    ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndTimedOut) {
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();

    const auto readLogsMaxInterval = 2h;

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // Enabling and then disabling readlogs.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(2);
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(2);
    // After setIncFsMountOptions succeeded expecting to start watching.
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
    // Not expecting callback removal.
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));

    // Disable readlogs callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
    auto callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
    // Now advance clock for 1hr.
    mClock->advance(1h);
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
    // Now call the timed callback, it should turn off the readlogs.
    callback();
    // Now advance clock for 2hrs.
    mClock->advance(readLogsMaxInterval);
    ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNoTimedOutForSystem) {
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();

    const auto readLogsMaxInterval = 2h;

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // Enabling and then disabling readlogs.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(3);
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(1);
    // After setIncFsMountOptions succeeded expecting to start watching.
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
    // Not expecting callback removal.
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
    // System data loader.
    mDataLoaderParcel.packageName = "android";
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));

    // IfsState callback.
    auto callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
    // Now advance clock for 1hr.
    mClock->advance(1h);
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
    // Now advance clock for 2hrs.
    mClock->advance(readLogsMaxInterval);
    // IfsStorage callback should not affect anything.
    callback();
    ASSERT_EQ(mDataLoader->setStorageParams(true), 0);
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNewInstall) {
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();

    const auto readLogsMaxInterval = 2h;

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // Enabling and then disabling readlogs.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(5);
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(3);
    // After setIncFsMountOptions succeeded expecting to start watching.
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
    // Not expecting callback removal.
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);

    // Before install - long timeouts.
    ASSERT_TRUE(mVold->readTimeoutsEnabled());

    auto dataLoaderParcel = mDataLoaderParcel;
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(dataLoaderParcel), {}, {},
                                                  {}, {}));
    // During install - short timeouts.
    ASSERT_FALSE(mVold->readTimeoutsEnabled());

    // Disable readlogs callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
    auto callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
    // Now advance clock for 1.5hrs.
    mClock->advance(90min);
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);

    mIncrementalService->onInstallationComplete(storageId);
    // After install - long timeouts.
    ASSERT_TRUE(mVold->readTimeoutsEnabled());

    // New installation.
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    // New installation - short timeouts.
    ASSERT_FALSE(mVold->readTimeoutsEnabled());

    // New callback present.
    ASSERT_EQ(storageId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
    auto callback2 = mTimedQueue->mWhat;
    mTimedQueue->clearJob(storageId);

    // Old callback should not disable readlogs (setIncFsMountOptions should be called only once).
    callback();
    // Advance clock for another 1.5hrs.
    mClock->advance(90min);
    // Still success even it's 3hrs past first install.
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);

    // New one should disable.
    callback2();
    // And timeout.
    mClock->advance(90min);
    ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);

    mIncrementalService->onInstallationComplete(storageId);
    // After install - long timeouts.
    ASSERT_TRUE(mVold->readTimeoutsEnabled());
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();
    mAppOpsManager->initializeStartWatchingMode();

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // We are calling setIncFsMountOptions(true).
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(1);
    // setIncFsMountOptions(false) is called on the callback.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(2);
    // After setIncFsMountOptions succeeded expecting to start watching.
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
    // After callback is called, disable read logs and remove callback.
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);
    ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
    mAppOpsManager->mStoredCallback->opChanged(0, {});
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) {
    mAppOpsManager->checkPermissionFails();

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // checkPermission fails, no calls to set opitions,  start or stop WatchingMode.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(0);
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(1);
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    ASSERT_LT(mDataLoader->setStorageParams(true), 0);
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUsers) {
    mAppOpsManager->checkPermissionNoCrossUsers();

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // checkPermission fails, no calls to set opitions,  start or stop WatchingMode.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(0);
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(1);
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    ASSERT_LT(mDataLoader->setStorageParams(true), 0);
}

TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
    mVold->setIncFsMountOptionsFails();
    mAppOpsManager->checkPermissionSuccess();

    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // We are calling setIncFsMountOptions.
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, true, _, _)).Times(1);
    EXPECT_CALL(*mVold, setIncFsMountOptions(_, false, _, _)).Times(1);
    // setIncFsMountOptions fails, no calls to start or stop WatchingMode.
    EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0);
    EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    ASSERT_LT(mDataLoader->setStorageParams(true), 0);
}

TEST_F(IncrementalServiceTest, testMakeDirectory) {
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    std::string dir_path("test");

    // Expecting incfs to call makeDir on a path like:
    // <root>/*/mount/<storage>/test
    EXPECT_CALL(*mIncFs,
                makeDir(_, Truly([&](std::string_view arg) {
                            return arg.starts_with(mRootDir.path) &&
                                    arg.ends_with("/mount/st_1_0/" + dir_path);
                        }),
                        _));
    auto res = mIncrementalService->makeDir(storageId, dir_path, 0555);
    ASSERT_EQ(res, 0);
}

TEST_F(IncrementalServiceTest, testMakeDirectories) {
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    auto first = "first"sv;
    auto second = "second"sv;
    auto third = "third"sv;
    auto dir_path = std::string(first) + "/" + std::string(second) + "/" + std::string(third);

    EXPECT_CALL(*mIncFs,
                makeDirs(_, Truly([&](std::string_view arg) {
                             return arg.starts_with(mRootDir.path) &&
                                     arg.ends_with("/mount/st_1_0/" + dir_path);
                         }),
                         _));
    auto res = mIncrementalService->makeDirs(storageId, dir_path, 0555);
    ASSERT_EQ(res, 0);
}

TEST_F(IncrementalServiceTest, testIsFileFullyLoadedNoData) {
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>()))
            .Times(1)
            .WillOnce(Return(incfs::LoadingState::MissingBlocks));
    ASSERT_GT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
}

TEST_F(IncrementalServiceTest, testIsFileFullyLoadedError) {
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>()))
            .Times(1)
            .WillOnce(Return(incfs::LoadingState(-1)));
    ASSERT_LT((int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"), 0);
}

TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) {
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    EXPECT_CALL(*mIncFs, isFileFullyLoaded(_, An<std::string_view>()))
            .Times(1)
            .WillOnce(Return(incfs::LoadingState::Full));
    ASSERT_EQ(0, (int)mIncrementalService->isFileFullyLoaded(storageId, "base.apk"));
}

TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) {
    mIncFs->countFilledBlocksSuccess();
    mFs->hasNoFile();

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress());
}

TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) {
    mIncFs->countFilledBlocksFails();
    mFs->hasFiles();

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1);
    ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId).getProgress());
}

TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) {
    mIncFs->countFilledBlocksEmpty();
    mFs->hasFiles();

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
    ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress());
}

TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) {
    mIncFs->countFilledBlocksSuccess();
    mFs->hasFiles();

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3);
    ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId).getProgress());
}

TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) {
    mIncFs->countFilledBlocksSuccess();
    mFs->hasFiles();

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    sp<NiceMock<MockStorageLoadingProgressListener>> listener{
            new NiceMock<MockStorageLoadingProgressListener>};
    NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
    EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(2);
    EXPECT_CALL(*mProgressUpdateJobQueue, addJob(_, _, _)).Times(2);
    mIncrementalService->registerLoadingProgressListener(storageId, listener);
    // Timed callback present.
    ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
    ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
    auto timedCallback = mProgressUpdateJobQueue->mWhat;
    timedCallback();
    ASSERT_EQ(storageId, mProgressUpdateJobQueue->mId);
    ASSERT_EQ(mProgressUpdateJobQueue->mAfter, 1000ms);
    mIncrementalService->unregisterLoadingProgressListener(storageId);
    ASSERT_EQ(mProgressUpdateJobQueue->mAfter, Milliseconds{});
}

TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProgress) {
    mIncFs->countFilledBlocksFails();
    mFs->hasFiles();

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    sp<NiceMock<MockStorageLoadingProgressListener>> listener{
            new NiceMock<MockStorageLoadingProgressListener>};
    NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get();
    EXPECT_CALL(*listenerMock, onStorageLoadingProgressChanged(_, _)).Times(0);
    mIncrementalService->registerLoadingProgressListener(storageId, listener);
}

TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDone) {
    mFs->hasFiles();

    const auto stateUpdateInterval = 1s;

    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    // No unbinding just yet.
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // System data loader to get rid of readlog timeout callback.
    mDataLoaderParcel.packageName = "android";
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));

    // Started.
    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);

    // IfsState callback present.
    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
    auto callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

    // Not loaded yet.
    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
            .WillOnce(Return(incfs::LoadingState::MissingBlocks));

    // Send the callback, should not do anything.
    callback();

    // Still started.
    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);

    // Still present.
    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
    callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

    // Fully loaded.
    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_)).WillOnce(Return(incfs::LoadingState::Full));
    // Expect the unbind.
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);

    callback();

    // Destroyed.
    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
}

TEST_F(IncrementalServiceTest, testStartDataLoaderUnbindOnAllDoneWithReadlogs) {
    mFs->hasFiles();

    // Readlogs.
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();

    const auto stateUpdateInterval = 1s;

    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    // No unbinding just yet.
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    // System data loader to get rid of readlog timeout callback.
    mDataLoaderParcel.packageName = "android";
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));

    // Started.
    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);

    // IfsState callback present.
    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
    auto callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

    // Not loaded yet.
    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
            .WillOnce(Return(incfs::LoadingState::MissingBlocks));

    // Send the callback, should not do anything.
    callback();

    // Still started.
    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);

    // Still present.
    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
    callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

    // Fully loaded.
    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
            .WillOnce(Return(incfs::LoadingState::Full))
            .WillOnce(Return(incfs::LoadingState::Full));
    // But with readlogs.
    ASSERT_GE(mDataLoader->setStorageParams(true), 0);

    // Send the callback, still nothing.
    callback();

    // Still started.
    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_STARTED);

    // Still present.
    ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
    ASSERT_EQ(mTimedQueue->mAfter, stateUpdateInterval);
    callback = mTimedQueue->mWhat;
    mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

    // Disable readlogs and expect the unbind.
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    ASSERT_GE(mDataLoader->setStorageParams(false), 0);

    callback();

    // Destroyed.
    ASSERT_EQ(mDataLoader->status(), IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
}

static std::vector<PerUidReadTimeouts> createPerUidTimeouts(
        std::initializer_list<std::tuple<int, int, int, int>> tuples) {
    std::vector<PerUidReadTimeouts> result;
    for (auto&& tuple : tuples) {
        result.emplace_back();
        auto& timeouts = result.back();
        timeouts.uid = std::get<0>(tuple);
        timeouts.minTimeUs = std::get<1>(tuple);
        timeouts.minPendingTimeUs = std::get<2>(tuple);
        timeouts.maxPendingTimeUs = std::get<3>(tuple);
    }
    return result;
}

static ErrorCode checkPerUidTimeouts(const Control& control,
                                     const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
    std::vector<PerUidReadTimeouts> expected =
            createPerUidTimeouts({{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}});
    EXPECT_EQ(expected, perUidReadTimeouts);
    return 0;
}

static ErrorCode checkPerUidTimeoutsEmpty(
        const Control& control, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
    EXPECT_EQ(0u, perUidReadTimeouts.size());
    return 0;
}

TEST_F(IncrementalServiceTest, testPerUidTimeoutsTooShort) {
    EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
    EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(1);
    EXPECT_CALL(*mDataLoader, start(_)).Times(1);
    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
    EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
    EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
                                      createPerUidTimeouts(
                                              {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}}));
}

TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) {
    mVold->setIncFsMountOptionsSuccess();
    mAppOpsManager->checkPermissionSuccess();
    mFs->hasFiles();

    EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _))
            // First call.
            .WillOnce(Invoke(&checkPerUidTimeouts))
            // Fully loaded and no readlogs.
            .WillOnce(Invoke(&checkPerUidTimeoutsEmpty));
    EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);

    // Loading storage.
    EXPECT_CALL(*mIncFs, isEverythingFullyLoaded(_))
            .WillOnce(Return(incfs::LoadingState::MissingBlocks))
            .WillOnce(Return(incfs::LoadingState::MissingBlocks))
            .WillOnce(Return(incfs::LoadingState::Full));

    // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue.
    mDataLoaderParcel.packageName = "android";

    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {},
                                      createPerUidTimeouts(
                                              {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 100000000}}));

    {
        // Timed callback present -> 0 progress.
        ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
        ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
        const auto timedCallback = mTimedQueue->mWhat;
        mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

        // Call it again.
        timedCallback();
    }

    {
        // Still present -> some progress.
        ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
        ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
        const auto timedCallback = mTimedQueue->mWhat;
        mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

        // Fully loaded but readlogs collection enabled.
        ASSERT_GE(mDataLoader->setStorageParams(true), 0);

        // Call it again.
        timedCallback();
    }

    {
        // Still present -> fully loaded + readlogs.
        ASSERT_EQ(IncrementalService::kAllStoragesId, mTimedQueue->mId);
        ASSERT_GE(mTimedQueue->mAfter, std::chrono::seconds(1));
        const auto timedCallback = mTimedQueue->mWhat;
        mTimedQueue->clearJob(IncrementalService::kAllStoragesId);

        // Now disable readlogs.
        ASSERT_GE(mDataLoader->setStorageParams(false), 0);

        // Call it again.
        timedCallback();
    }

    // No callbacks anymore -> fully loaded and no readlogs.
    ASSERT_EQ(mTimedQueue->mAfter, Milliseconds());
}

TEST_F(IncrementalServiceTest, testInvalidMetricsQuery) {
    const auto invalidStorageId = 100;
    android::os::PersistableBundle result{};
    mIncrementalService->getMetrics(invalidStorageId, &result);
    int64_t expected = -1, value = -1;
    ASSERT_FALSE(
            result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
                                            .c_str()),
                           &value));
    ASSERT_EQ(expected, value);
    ASSERT_TRUE(result.empty());
}

TEST_F(IncrementalServiceTest, testNoDataLoaderMetrics) {
    mVold->setIncFsMountOptionsSuccess();
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    android::os::PersistableBundle result{};
    mIncrementalService->getMetrics(storageId, &result);
    int64_t expected = -1, value = -1;
    ASSERT_FALSE(
            result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_OLDEST_PENDING_READ()
                                            .c_str()),
                           &value));
    ASSERT_EQ(expected, value);
    ASSERT_EQ(1, (int)result.size());
    bool expectedReadLogsEnabled = false;
    ASSERT_TRUE(
            result.getBoolean(String16(BnIncrementalService::METRICS_READ_LOGS_ENABLED().c_str()),
                              &expectedReadLogsEnabled));
    ASSERT_EQ(mVold->readLogsEnabled(), expectedReadLogsEnabled);
}

TEST_F(IncrementalServiceTest, testInvalidMetricsKeys) {
    mVold->setIncFsMountOptionsSuccess();
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    android::os::PersistableBundle result{};
    mIncrementalService->getMetrics(storageId, &result);
    int64_t expected = -1, value = -1;
    ASSERT_FALSE(result.getLong(String16("invalid"), &value));
    ASSERT_EQ(expected, value);
    ASSERT_EQ(6, (int)result.size());
}

TEST_F(IncrementalServiceTest, testMetricsWithNoLastReadError) {
    mVold->setIncFsMountOptionsSuccess();
    ON_CALL(*mIncFs, getMetrics(_))
            .WillByDefault(Return(Metrics{
                    .readsDelayedMin = 10,
                    .readsDelayedMinUs = 5000,
                    .readsDelayedPending = 10,
                    .readsDelayedPendingUs = 5000,
                    .readsFailedHashVerification = 10,
                    .readsFailedOther = 10,
                    .readsFailedTimedOut = 10,
            }));
    ON_CALL(*mIncFs, getLastReadError(_)).WillByDefault(Return(LastReadError{}));
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    android::os::PersistableBundle result{};
    mIncrementalService->getMetrics(storageId, &result);
    ASSERT_EQ(9, (int)result.size());

    int expectedtotalDelayedReads = 20, totalDelayedReads = -1;
    ASSERT_TRUE(result.getInt(String16(BnIncrementalService::METRICS_TOTAL_DELAYED_READS().c_str()),
                              &totalDelayedReads));
    ASSERT_EQ(expectedtotalDelayedReads, totalDelayedReads);
    int expectedtotalFailedReads = 30, totalFailedReads = -1;
    ASSERT_TRUE(result.getInt(String16(BnIncrementalService::METRICS_TOTAL_FAILED_READS().c_str()),
                              &totalFailedReads));
    ASSERT_EQ(expectedtotalFailedReads, totalFailedReads);
    int64_t expectedtotalDelayedReadsMillis = 10, totalDelayedReadsMillis = -1;
    ASSERT_TRUE(result.getLong(String16(BnIncrementalService::METRICS_TOTAL_DELAYED_READS_MILLIS()
                                                .c_str()),
                               &totalDelayedReadsMillis));
    ASSERT_EQ(expectedtotalDelayedReadsMillis, totalDelayedReadsMillis);

    int64_t expectedMillisSinceLastReadError = -1, millisSinceLastReadError = -1;
    ASSERT_FALSE(
            result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_LAST_READ_ERROR()
                                            .c_str()),
                           &millisSinceLastReadError));
    ASSERT_EQ(expectedMillisSinceLastReadError, millisSinceLastReadError);
    int expectedLastReadErrorNumber = -1, lastReadErrorNumber = -1;
    ASSERT_FALSE(
            result.getInt(String16(BnIncrementalService::METRICS_LAST_READ_ERROR_NUMBER().c_str()),
                          &lastReadErrorNumber));
    ASSERT_EQ(expectedLastReadErrorNumber, lastReadErrorNumber);
    int expectedLastReadUid = -1, lastReadErrorUid = -1;
    ASSERT_FALSE(
            result.getInt(String16(BnIncrementalService::METRICS_LAST_READ_ERROR_UID().c_str()),
                          &lastReadErrorUid));
    ASSERT_EQ(expectedLastReadUid, lastReadErrorUid);
}

TEST_F(IncrementalServiceTest, testMetricsWithLastReadError) {
    mVold->setIncFsMountOptionsSuccess();
    ON_CALL(*mIncFs, getMetrics(_)).WillByDefault(Return(Metrics{}));
    mClock->advanceMs(5);
    const auto now = mClock->getClock();
    ON_CALL(*mIncFs, getLastReadError(_))
            .WillByDefault(Return(LastReadError{.timestampUs = static_cast<uint64_t>(
                                                        duration_cast<std::chrono::microseconds>(
                                                                now.time_since_epoch())
                                                                .count()),
                                                .errorNo = static_cast<uint32_t>(-ETIME),
                                                .uid = 20000}));
    TemporaryDir tempDir;
    int storageId =
            mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
                                               IncrementalService::CreateOptions::CreateNew);
    ASSERT_GE(storageId, 0);
    ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
                                                  {}, {}));
    mClock->advanceMs(10);
    android::os::PersistableBundle result{};
    mIncrementalService->getMetrics(storageId, &result);
    ASSERT_EQ(12, (int)result.size());
    int64_t expectedMillisSinceLastReadError = 10, millisSinceLastReadError = -1;
    ASSERT_TRUE(result.getLong(String16(BnIncrementalService::METRICS_MILLIS_SINCE_LAST_READ_ERROR()
                                                .c_str()),
                               &millisSinceLastReadError));
    ASSERT_EQ(expectedMillisSinceLastReadError, millisSinceLastReadError);
    int expectedLastReadErrorNumber = -ETIME, lastReadErrorNumber = -1;
    ASSERT_TRUE(
            result.getInt(String16(BnIncrementalService::METRICS_LAST_READ_ERROR_NUMBER().c_str()),
                          &lastReadErrorNumber));
    ASSERT_EQ(expectedLastReadErrorNumber, lastReadErrorNumber);
    int expectedLastReadUid = 20000, lastReadErrorUid = -1;
    ASSERT_TRUE(result.getInt(String16(BnIncrementalService::METRICS_LAST_READ_ERROR_UID().c_str()),
                              &lastReadErrorUid));
    ASSERT_EQ(expectedLastReadUid, lastReadErrorUid);
}

} // namespace android::os::incremental
