diff options
12 files changed, 413 insertions, 287 deletions
diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalService.aidl index 7db5a80b6cf9..3fbc28402405 100644 --- a/core/java/android/os/incremental/IIncrementalService.aidl +++ b/core/java/android/os/incremental/IIncrementalService.aidl @@ -38,14 +38,20 @@ interface IIncrementalService { * Opens or creates a storage given a target path and data loader params. Returns the storage ID. */ int openStorage(in @utf8InCpp String path); - int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode, - in IDataLoaderStatusListener statusListener, - in StorageHealthCheckParams healthCheckParams, - in IStorageHealthListener healthListener, - in PerUidReadTimeouts[] perUidReadTimeouts); + int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode); int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode); /** + * Loops DataLoader through bind/create/start with params. + */ + boolean startLoading(int storageId, + in DataLoaderParamsParcel params, + in IDataLoaderStatusListener statusListener, + in StorageHealthCheckParams healthCheckParams, + in IStorageHealthListener healthListener, + in PerUidReadTimeouts[] perUidReadTimeouts); + + /** * Bind-mounts a path under a storage to a full path. Can be permanent or temporary. */ const int BIND_TEMPORARY = 0; @@ -101,6 +107,14 @@ interface IIncrementalService { int isFileFullyLoaded(int storageId, in @utf8InCpp String path); /** + * Checks if all files in the storage are fully loaded. + * 0 - fully loaded + * >0 - certain pages missing + * <0 - -errcode + */ + int isFullyLoaded(int storageId); + + /** * Returns overall loading progress of all the files on a storage, progress value between [0,1]. * Returns a negative value on error. */ @@ -113,11 +127,6 @@ interface IIncrementalService { byte[] getMetadataById(int storageId, in byte[] fileId); /** - * Starts loading data for a storage. - */ - boolean startLoading(int storageId); - - /** * Deletes a storage given its ID. Deletes its bind mounts and unmount it. Stop its data loader. */ void deleteStorage(int storageId); diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java index 59292baa110c..f2fe71913bb1 100644 --- a/core/java/android/os/incremental/IncrementalFileStorages.java +++ b/core/java/android/os/incremental/IncrementalFileStorages.java @@ -37,7 +37,6 @@ import android.content.Context; import android.content.pm.DataLoaderParams; import android.content.pm.IDataLoaderStatusListener; import android.content.pm.InstallationFileParcel; -import android.text.TextUtils; import java.io.File; import java.io.IOException; @@ -53,6 +52,7 @@ public final class IncrementalFileStorages { private @NonNull final IncrementalManager mIncrementalManager; private @NonNull final File mStageDir; + private @Nullable IncrementalStorage mInheritedStorage; private @Nullable IncrementalStorage mDefaultStorage; /** @@ -65,6 +65,7 @@ public final class IncrementalFileStorages { */ public static IncrementalFileStorages initialize(Context context, @NonNull File stageDir, + @Nullable File inheritedDir, @NonNull DataLoaderParams dataLoaderParams, @Nullable IDataLoaderStatusListener statusListener, @Nullable StorageHealthCheckParams healthCheckParams, @@ -79,9 +80,8 @@ public final class IncrementalFileStorages { throw new IOException("Failed to obtain incrementalManager."); } - final IncrementalFileStorages result = new IncrementalFileStorages(stageDir, - incrementalManager, dataLoaderParams, statusListener, healthCheckParams, - healthListener, perUidReadTimeouts); + final IncrementalFileStorages result = new IncrementalFileStorages(stageDir, inheritedDir, + incrementalManager, dataLoaderParams); for (InstallationFileParcel file : addedFiles) { if (file.location == LOCATION_DATA_APP) { try { @@ -95,43 +95,46 @@ public final class IncrementalFileStorages { throw new IOException("Unknown file location: " + file.location); } } - - result.startLoading(); + result.startLoading(dataLoaderParams, statusListener, healthCheckParams, healthListener, + perUidReadTimeouts); return result; } private IncrementalFileStorages(@NonNull File stageDir, + @Nullable File inheritedDir, @NonNull IncrementalManager incrementalManager, - @NonNull DataLoaderParams dataLoaderParams, - @Nullable IDataLoaderStatusListener statusListener, - @Nullable StorageHealthCheckParams healthCheckParams, - @Nullable IStorageHealthListener healthListener, - @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException { + @NonNull DataLoaderParams dataLoaderParams) throws IOException { try { mStageDir = stageDir; mIncrementalManager = incrementalManager; - if (dataLoaderParams.getComponentName().getPackageName().equals("local")) { - final String incrementalPath = dataLoaderParams.getArguments(); - if (TextUtils.isEmpty(incrementalPath)) { - throw new IOException("Failed to create storage: incrementalPath is empty"); - } - mDefaultStorage = mIncrementalManager.openStorage(incrementalPath); - if (mDefaultStorage == null) { - throw new IOException( - "Couldn't open incremental storage at " + incrementalPath); - } - mDefaultStorage.bind(stageDir.getAbsolutePath()); - } else { - mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), - dataLoaderParams, IncrementalManager.CREATE_MODE_CREATE - | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false, - statusListener, healthCheckParams, healthListener, perUidReadTimeouts); - if (mDefaultStorage == null) { - throw new IOException( - "Couldn't create incremental storage at " + stageDir); + if (inheritedDir != null && IncrementalManager.isIncrementalPath( + inheritedDir.getAbsolutePath())) { + mInheritedStorage = mIncrementalManager.openStorage( + inheritedDir.getAbsolutePath()); + if (mInheritedStorage != null) { + if (!mInheritedStorage.isFullyLoaded()) { + throw new IOException("Inherited storage has missing pages."); + } + + mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), + mInheritedStorage, IncrementalManager.CREATE_MODE_CREATE + | IncrementalManager.CREATE_MODE_TEMPORARY_BIND); + if (mDefaultStorage == null) { + throw new IOException( + "Couldn't create linked incremental storage at " + stageDir); + } + return; } } + + mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(), + dataLoaderParams, IncrementalManager.CREATE_MODE_CREATE + | IncrementalManager.CREATE_MODE_TEMPORARY_BIND); + if (mDefaultStorage == null) { + throw new IOException( + "Couldn't create incremental storage at " + stageDir); + } } catch (IOException e) { cleanUp(); throw e; @@ -149,9 +152,16 @@ public final class IncrementalFileStorages { /** * Starts or re-starts loading of data. */ - public void startLoading() throws IOException { - if (!mDefaultStorage.startLoading()) { - throw new IOException("Failed to start loading data for Incremental installation."); + void startLoading( + @NonNull DataLoaderParams dataLoaderParams, + @Nullable IDataLoaderStatusListener statusListener, + @Nullable StorageHealthCheckParams healthCheckParams, + @Nullable IStorageHealthListener healthListener, + @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException { + if (!mDefaultStorage.startLoading(dataLoaderParams, statusListener, healthCheckParams, + healthListener, perUidReadTimeouts)) { + throw new IOException( + "Failed to start or restart loading data for Incremental installation."); } } @@ -163,6 +173,21 @@ public final class IncrementalFileStorages { } /** + * Creates a hardlink from inherited storage to default. + */ + public boolean makeLink(@NonNull String relativePath, @NonNull String fromBase, + @NonNull String toBase) throws IOException { + if (mInheritedStorage == null) { + return false; + } + final File sourcePath = new File(fromBase, relativePath); + final File destPath = new File(toBase, relativePath); + mInheritedStorage.makeLink(sourcePath.getAbsolutePath(), mDefaultStorage, + destPath.getAbsolutePath()); + return true; + } + + /** * Permanently disables readlogs. */ public void disallowReadLogs() { diff --git a/core/java/android/os/incremental/IncrementalManager.java b/core/java/android/os/incremental/IncrementalManager.java index 4b9327021cb0..7e7057fe56cb 100644 --- a/core/java/android/os/incremental/IncrementalManager.java +++ b/core/java/android/os/incremental/IncrementalManager.java @@ -22,7 +22,6 @@ import android.annotation.Nullable; import android.annotation.SystemService; import android.content.Context; import android.content.pm.DataLoaderParams; -import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IPackageLoadingProgressCallback; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -95,32 +94,20 @@ public final class IncrementalManager { * @param params IncrementalDataLoaderParams object to configure data loading. * @param createMode Mode for opening an old Incremental File System mount or creating * a new mount. - * @param autoStartDataLoader Set true to immediately start data loader after creating storage. * @return IncrementalStorage object corresponding to the mounted directory. */ @Nullable public IncrementalStorage createStorage(@NonNull String path, @NonNull DataLoaderParams params, - @CreateMode int createMode, - boolean autoStartDataLoader, - @Nullable IDataLoaderStatusListener statusListener, - @Nullable StorageHealthCheckParams healthCheckParams, - @Nullable IStorageHealthListener healthListener, - @NonNull PerUidReadTimeouts[] perUidReadTimeouts) { + @CreateMode int createMode) { Objects.requireNonNull(path); Objects.requireNonNull(params); - Objects.requireNonNull(perUidReadTimeouts); try { - final int id = mService.createStorage(path, params.getData(), createMode, - statusListener, healthCheckParams, healthListener, perUidReadTimeouts); + final int id = mService.createStorage(path, params.getData(), createMode); if (id < 0) { return null; } - final IncrementalStorage storage = new IncrementalStorage(mService, id); - if (autoStartDataLoader) { - storage.startLoading(); - } - return storage; + return new IncrementalStorage(mService, id); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -281,15 +268,18 @@ public final class IncrementalManager { * Unbinds the target dir and deletes the corresponding storage instance. * Deletes the package name and associated storage id from maps. */ - public void onPackageRemoved(@NonNull String codePath) { + public void onPackageRemoved(@NonNull File codeFile) { try { + final String codePath = codeFile.getAbsolutePath(); final IncrementalStorage storage = openStorage(codePath); if (storage == null) { return; } mLoadingProgressCallbacks.cleanUpCallbacks(storage); unregisterHealthListener(codePath); - mService.deleteStorage(storage.getId()); + + // Parent since we bind-mount a folder one level above. + mService.deleteBindMount(storage.getId(), codeFile.getParent()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/os/incremental/IncrementalStorage.java b/core/java/android/os/incremental/IncrementalStorage.java index 5b688bbd0655..e6ce8cd56d28 100644 --- a/core/java/android/os/incremental/IncrementalStorage.java +++ b/core/java/android/os/incremental/IncrementalStorage.java @@ -18,11 +18,14 @@ package android.os.incremental; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.DataLoaderParams; +import android.content.pm.IDataLoaderStatusListener; import android.os.RemoteException; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.Objects; import java.util.UUID; /** @@ -323,6 +326,24 @@ public final class IncrementalStorage { } } + + /** + * Checks if all files in the storage are fully loaded. + */ + public boolean isFullyLoaded() throws IOException { + try { + final int res = mService.isFullyLoaded(mId); + if (res < 0) { + throw new IOException( + "isFullyLoaded() failed at querying loading progress, errno " + -res); + } + return res == 0; + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return false; + } + } + /** * Returns the loading progress of a storage * @@ -376,13 +397,21 @@ public final class IncrementalStorage { } /** - * Informs the data loader service associated with the current storage to start data loader - * - * @return True if data loader is successfully started. + * Iinitializes and starts the DataLoader. + * This makes sure all install-time parameters are applied. + * Does not affect persistent DataLoader params. + * @return True if start request was successfully queued. */ - public boolean startLoading() { + public boolean startLoading( + @NonNull DataLoaderParams dataLoaderParams, + @Nullable IDataLoaderStatusListener statusListener, + @Nullable StorageHealthCheckParams healthCheckParams, + @Nullable IStorageHealthListener healthListener, + @NonNull PerUidReadTimeouts[] perUidReadTimeouts) { + Objects.requireNonNull(perUidReadTimeouts); try { - return mService.startLoading(mId); + return mService.startLoading(mId, dataLoaderParams.getData(), statusListener, + healthCheckParams, healthListener, perUidReadTimeouts); } catch (RemoteException e) { e.rethrowFromSystemServer(); return false; diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 4eaac2e44da8..7c425698e507 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -3299,17 +3299,28 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } + private void linkFile(String relativePath, String fromBase, String toBase) throws IOException { + try { + // Try + if (mIncrementalFileStorages != null && mIncrementalFileStorages.makeLink(relativePath, + fromBase, toBase)) { + return; + } + mPm.mInstaller.linkFile(relativePath, fromBase, toBase); + } catch (InstallerException | IOException e) { + throw new IOException("failed linkOrCreateDir(" + relativePath + ", " + + fromBase + ", " + toBase + ")", e); + } + } + private void linkFiles(List<File> fromFiles, File toDir, File fromDir) throws IOException { for (File fromFile : fromFiles) { final String relativePath = getRelativePath(fromFile, fromDir); - try { - mPm.mInstaller.linkFile(relativePath, fromDir.getAbsolutePath(), - toDir.getAbsolutePath()); - } catch (InstallerException e) { - throw new IOException("failed linkOrCreateDir(" + relativePath + ", " - + fromDir + ", " + toDir + ")", e); - } + final String fromBase = fromDir.getAbsolutePath(); + final String toBase = toDir.getAbsolutePath(); + + linkFile(relativePath, fromBase, toBase); } Slog.d(TAG, "Linked " + fromFiles.size() + " files into " + toDir); @@ -3577,12 +3588,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Retrying commit. if (mIncrementalFileStorages != null) { - try { - mIncrementalFileStorages.startLoading(); - } catch (IOException e) { - throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), - e.getCause()); - } return false; } @@ -3757,9 +3762,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { }; try { + final PackageInfo pkgInfo = mPm.getPackageInfo(this.params.appPackageName, 0, + userId); + final File inheritedDir = + (pkgInfo != null && pkgInfo.applicationInfo != null) ? new File( + pkgInfo.applicationInfo.getCodePath()).getParentFile() : null; + mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir, - params, statusListener, healthCheckParams, healthListener, addedFiles, - perUidReadTimeouts); + inheritedDir, params, statusListener, healthCheckParams, healthListener, + addedFiles, perUidReadTimeouts); return false; } catch (IOException e) { throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(), diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index d2fc5b4c0967..f772f63a08ac 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -18163,13 +18163,15 @@ public class PackageManagerService extends IPackageManager.Stub return false; } - String codePath = codeFile.getAbsolutePath(); - if (mIncrementalManager != null && isIncrementalPath(codePath)) { - mIncrementalManager.onPackageRemoved(codePath); - } + final boolean isIncremental = (mIncrementalManager != null && isIncrementalPath( + codeFile.getAbsolutePath())); removeCodePathLI(codeFile); + if (isIncremental) { + mIncrementalManager.onPackageRemoved(codeFile); + } + return true; } diff --git a/services/incremental/BinderIncrementalService.cpp b/services/incremental/BinderIncrementalService.cpp index d2244286450b..b2efc71860fb 100644 --- a/services/incremental/BinderIncrementalService.cpp +++ b/services/incremental/BinderIncrementalService.cpp @@ -118,18 +118,10 @@ binder::Status BinderIncrementalService::openStorage(const std::string& path, binder::Status BinderIncrementalService::createStorage( const ::std::string& path, const ::android::content::pm::DataLoaderParamsParcel& params, - int32_t createMode, - const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& statusListener, - const ::android::os::incremental::StorageHealthCheckParams& healthCheckParams, - const ::android::sp<::android::os::incremental::IStorageHealthListener>& healthListener, - const ::std::vector<::android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts, - int32_t* _aidl_return) { - *_aidl_return = - mImpl.createStorage(path, const_cast<content::pm::DataLoaderParamsParcel&&>(params), - android::incremental::IncrementalService::CreateOptions(createMode), - statusListener, - const_cast<StorageHealthCheckParams&&>(healthCheckParams), - healthListener, perUidReadTimeouts); + int32_t createMode, int32_t* _aidl_return) { + *_aidl_return = mImpl.createStorage(path, params, + android::incremental::IncrementalService::CreateOptions( + createMode)); return ok(); } @@ -144,6 +136,21 @@ binder::Status BinderIncrementalService::createLinkedStorage(const std::string& return ok(); } +binder::Status BinderIncrementalService::startLoading( + int32_t storageId, const ::android::content::pm::DataLoaderParamsParcel& params, + const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& statusListener, + const ::android::os::incremental::StorageHealthCheckParams& healthCheckParams, + const ::android::sp<IStorageHealthListener>& healthListener, + const ::std::vector<::android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts, + bool* _aidl_return) { + *_aidl_return = + mImpl.startLoading(storageId, const_cast<content::pm::DataLoaderParamsParcel&&>(params), + statusListener, + const_cast<StorageHealthCheckParams&&>(healthCheckParams), + healthListener, perUidReadTimeouts); + return ok(); +} + binder::Status BinderIncrementalService::makeBindMount(int32_t storageId, const std::string& sourcePath, const std::string& targetFullPath, @@ -253,9 +260,16 @@ binder::Status BinderIncrementalService::isFileFullyLoaded(int32_t storageId, return ok(); } +binder::Status BinderIncrementalService::isFullyLoaded(int32_t storageId, int32_t* _aidl_return) { + *_aidl_return = mImpl.getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/true) + .blocksRemainingOrError(); + return ok(); +} + binder::Status BinderIncrementalService::getLoadingProgress(int32_t storageId, float* _aidl_return) { - *_aidl_return = mImpl.getLoadingProgress(storageId).getProgress(); + *_aidl_return = + mImpl.getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false).getProgress(); return ok(); } @@ -291,11 +305,6 @@ binder::Status BinderIncrementalService::makeDirectories(int32_t storageId, cons return ok(); } -binder::Status BinderIncrementalService::startLoading(int32_t storageId, bool* _aidl_return) { - *_aidl_return = mImpl.startLoading(storageId); - return ok(); -} - binder::Status BinderIncrementalService::configureNativeBinaries( int32_t storageId, const std::string& apkFullPath, const std::string& libDirRelativePath, const std::string& abi, bool extractNativeLibs, bool* _aidl_return) { diff --git a/services/incremental/BinderIncrementalService.h b/services/incremental/BinderIncrementalService.h index 9a4537a15f31..740c542f9759 100644 --- a/services/incremental/BinderIncrementalService.h +++ b/services/incremental/BinderIncrementalService.h @@ -39,16 +39,18 @@ public: void onInvalidStorage(int mountId); binder::Status openStorage(const std::string& path, int32_t* _aidl_return) final; - binder::Status createStorage( - const ::std::string& path, const ::android::content::pm::DataLoaderParamsParcel& params, - int32_t createMode, + binder::Status createStorage(const ::std::string& path, + const ::android::content::pm::DataLoaderParamsParcel& params, + int32_t createMode, int32_t* _aidl_return) final; + binder::Status createLinkedStorage(const std::string& path, int32_t otherStorageId, + int32_t createMode, int32_t* _aidl_return) final; + binder::Status startLoading( + int32_t storageId, const ::android::content::pm::DataLoaderParamsParcel& params, const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& statusListener, const ::android::os::incremental::StorageHealthCheckParams& healthCheckParams, const ::android::sp<IStorageHealthListener>& healthListener, const ::std::vector<::android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts, - int32_t* _aidl_return) final; - binder::Status createLinkedStorage(const std::string& path, int32_t otherStorageId, - int32_t createMode, int32_t* _aidl_return) final; + bool* _aidl_return) final; binder::Status makeBindMount(int32_t storageId, const std::string& sourcePath, const std::string& targetFullPath, int32_t bindType, int32_t* _aidl_return) final; @@ -71,12 +73,12 @@ public: binder::Status unlink(int32_t storageId, const std::string& path, int32_t* _aidl_return) final; binder::Status isFileFullyLoaded(int32_t storageId, const std::string& path, int32_t* _aidl_return) final; + binder::Status isFullyLoaded(int32_t storageId, int32_t* _aidl_return) final; binder::Status getLoadingProgress(int32_t storageId, float* _aidl_return) final; binder::Status getMetadataByPath(int32_t storageId, const std::string& path, std::vector<uint8_t>* _aidl_return) final; binder::Status getMetadataById(int32_t storageId, const std::vector<uint8_t>& id, std::vector<uint8_t>* _aidl_return) final; - binder::Status startLoading(int32_t storageId, bool* _aidl_return) final; binder::Status deleteStorage(int32_t storageId) final; binder::Status disallowReadLogs(int32_t storageId) final; binder::Status configureNativeBinaries(int32_t storageId, const std::string& apkFullPath, diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index c9c5489a50df..132f973ee83b 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -356,7 +356,9 @@ void IncrementalService::onDump(int fd) { dprintf(fd, " storages (%d): {\n", int(mnt.storages.size())); for (auto&& [storageId, storage] : mnt.storages) { dprintf(fd, " [%d] -> [%s] (%d %% loaded) \n", storageId, storage.name.c_str(), - (int)(getLoadingProgressFromPath(mnt, storage.name.c_str()).getProgress() * + (int)(getLoadingProgressFromPath(mnt, storage.name.c_str(), + /*stopOnFirstIncomplete=*/false) + .getProgress() * 100)); } dprintf(fd, " }\n"); @@ -427,10 +429,8 @@ auto IncrementalService::getStorageSlotLocked() -> MountMap::iterator { } StorageId IncrementalService::createStorage( - std::string_view mountPoint, content::pm::DataLoaderParamsParcel&& dataLoaderParams, - CreateOptions options, const DataLoaderStatusListener& statusListener, - StorageHealthCheckParams&& healthCheckParams, const StorageHealthListener& healthListener, - const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) { + std::string_view mountPoint, const content::pm::DataLoaderParamsParcel& dataLoaderParams, + CreateOptions options) { LOG(INFO) << "createStorage: " << mountPoint << " | " << int(options); if (!path::isAbsolute(mountPoint)) { LOG(ERROR) << "path is not absolute: " << mountPoint; @@ -538,13 +538,10 @@ StorageId IncrementalService::createStorage( metadata::Mount m; m.mutable_storage()->set_id(ifs->mountId); m.mutable_loader()->set_type((int)dataLoaderParams.type); - m.mutable_loader()->set_allocated_package_name(&dataLoaderParams.packageName); - m.mutable_loader()->set_allocated_class_name(&dataLoaderParams.className); - m.mutable_loader()->set_allocated_arguments(&dataLoaderParams.arguments); + m.mutable_loader()->set_package_name(dataLoaderParams.packageName); + m.mutable_loader()->set_class_name(dataLoaderParams.className); + m.mutable_loader()->set_arguments(dataLoaderParams.arguments); const auto metadata = m.SerializeAsString(); - m.mutable_loader()->release_arguments(); - m.mutable_loader()->release_class_name(); - m.mutable_loader()->release_package_name(); if (auto err = mIncFs->makeFile(ifs->control, path::join(ifs->root, constants().mount, @@ -568,26 +565,9 @@ StorageId IncrementalService::createStorage( // Done here as well, all data structures are in good state. secondCleanupOnFailure.release(); - // DataLoader. - auto dataLoaderStub = prepareDataLoader(*ifs, std::move(dataLoaderParams), &statusListener, - std::move(healthCheckParams), &healthListener); - CHECK(dataLoaderStub); - mountIt->second = std::move(ifs); l.unlock(); - // Per Uid timeouts. - if (!perUidReadTimeouts.empty()) { - setUidReadTimeouts(mountId, perUidReadTimeouts); - } - - if (mSystemReady.load(std::memory_order_relaxed) && !dataLoaderStub->requestCreate()) { - // failed to create data loader - LOG(ERROR) << "initializeDataLoader() failed"; - deleteStorage(dataLoaderStub->id()); - return kInvalidStorageId; - } - LOG(INFO) << "created storage " << mountId; return mountId; } @@ -634,6 +614,37 @@ StorageId IncrementalService::createLinkedStorage(std::string_view mountPoint, return storageId; } +bool IncrementalService::startLoading(StorageId storage, + content::pm::DataLoaderParamsParcel&& dataLoaderParams, + const DataLoaderStatusListener& statusListener, + StorageHealthCheckParams&& healthCheckParams, + const StorageHealthListener& healthListener, + const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) { + // Per Uid timeouts. + if (!perUidReadTimeouts.empty()) { + setUidReadTimeouts(storage, perUidReadTimeouts); + } + + // Re-initialize DataLoader. + std::unique_lock l(mLock); + const auto ifs = getIfsLocked(storage); + if (!ifs) { + return false; + } + if (ifs->dataLoaderStub) { + ifs->dataLoaderStub->cleanupResources(); + ifs->dataLoaderStub = {}; + } + l.unlock(); + + // DataLoader. + auto dataLoaderStub = prepareDataLoader(*ifs, std::move(dataLoaderParams), &statusListener, + std::move(healthCheckParams), &healthListener); + CHECK(dataLoaderStub); + + return dataLoaderStub->requestStart(); +} + IncrementalService::BindPathMap::const_iterator IncrementalService::findStorageLocked( std::string_view path) const { return findParentPath(mBindsByPath, path); @@ -960,7 +971,12 @@ int IncrementalService::link(StorageId sourceStorageId, std::string_view oldPath LOG(ERROR) << "Invalid paths in link(): " << normOldPath << " | " << normNewPath; return -EINVAL; } - return mIncFs->link(ifsSrc->control, normOldPath, normNewPath); + if (auto err = mIncFs->link(ifsSrc->control, normOldPath, normNewPath); err < 0) { + PLOG(ERROR) << "Failed to link " << oldPath << "[" << normOldPath << "]" + << " to " << newPath << "[" << normNewPath << "]"; + return err; + } + return 0; } int IncrementalService::unlink(StorageId storage, std::string_view path) { @@ -1065,23 +1081,6 @@ RawMetadata IncrementalService::getMetadata(StorageId storage, FileId node) cons return mIncFs->getMetadata(ifs->control, node); } -bool IncrementalService::startLoading(StorageId storage) const { - DataLoaderStubPtr dataLoaderStub; - { - std::unique_lock l(mLock); - const auto& ifs = getIfsLocked(storage); - if (!ifs) { - return false; - } - dataLoaderStub = ifs->dataLoaderStub; - if (!dataLoaderStub) { - return false; - } - } - dataLoaderStub->requestStart(); - return true; -} - void IncrementalService::setUidReadTimeouts( StorageId storage, const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) { using microseconds = std::chrono::microseconds; @@ -1092,11 +1091,15 @@ void IncrementalService::setUidReadTimeouts( maxPendingTimeUs = std::max(maxPendingTimeUs, microseconds(timeouts.maxPendingTimeUs)); } if (maxPendingTimeUs < Constants::minPerUidTimeout) { + LOG(ERROR) << "Skip setting timeouts: maxPendingTime < Constants::minPerUidTimeout" + << duration_cast<milliseconds>(maxPendingTimeUs).count() << "ms < " + << Constants::minPerUidTimeout.count() << "ms"; return; } const auto ifs = getIfs(storage); if (!ifs) { + LOG(ERROR) << "Setting read timeouts failed: invalid storage id: " << storage; return; } @@ -1126,7 +1129,7 @@ void IncrementalService::updateUidReadTimeouts(StorageId storage, Clock::time_po } // Still loading? - const auto progress = getLoadingProgress(storage); + const auto progress = getLoadingProgress(storage, /*stopOnFirstIncomplete=*/true); if (progress.isError()) { // Something is wrong, abort. return clearUidReadTimeouts(storage); @@ -1840,7 +1843,7 @@ int IncrementalService::isFileFullyLoadedFromPath(const IncFsMount& ifs, } IncrementalService::LoadingProgress IncrementalService::getLoadingProgress( - StorageId storage) const { + StorageId storage, bool stopOnFirstIncomplete) const { std::unique_lock l(mLock); const auto ifs = getIfsLocked(storage); if (!ifs) { @@ -1853,11 +1856,11 @@ IncrementalService::LoadingProgress IncrementalService::getLoadingProgress( return {-EINVAL, -EINVAL}; } l.unlock(); - return getLoadingProgressFromPath(*ifs, storageInfo->second.name); + return getLoadingProgressFromPath(*ifs, storageInfo->second.name, stopOnFirstIncomplete); } IncrementalService::LoadingProgress IncrementalService::getLoadingProgressFromPath( - const IncFsMount& ifs, std::string_view storagePath) const { + const IncFsMount& ifs, std::string_view storagePath, bool stopOnFirstIncomplete) const { ssize_t totalBlocks = 0, filledBlocks = 0; const auto filePaths = mFs->listFilesRecursive(storagePath); for (const auto& filePath : filePaths) { @@ -1870,6 +1873,9 @@ IncrementalService::LoadingProgress IncrementalService::getLoadingProgressFromPa } totalBlocks += totalBlocksCount; filledBlocks += filledBlocksCount; + if (stopOnFirstIncomplete && filledBlocks < totalBlocks) { + break; + } } return {filledBlocks, totalBlocks}; @@ -1877,7 +1883,7 @@ IncrementalService::LoadingProgress IncrementalService::getLoadingProgressFromPa bool IncrementalService::updateLoadingProgress( StorageId storage, const StorageLoadingProgressListener& progressListener) { - const auto progress = getLoadingProgress(storage); + const auto progress = getLoadingProgress(storage, /*stopOnFirstIncomplete=*/false); if (progress.isError()) { // Failed to get progress from incfs, abort. return false; diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h index 306612159412..5d53bac777b5 100644 --- a/services/incremental/IncrementalService.h +++ b/services/incremental/IncrementalService.h @@ -113,6 +113,10 @@ public: bool started() const { return totalBlocks > 0; } bool fullyLoaded() const { return !isError() && (totalBlocks == filledBlocks); } + int blocksRemainingOrError() const { + return totalBlocks <= 0 ? totalBlocks : totalBlocks - filledBlocks; + } + float getProgress() const { return totalBlocks < 0 ? totalBlocks @@ -130,15 +134,18 @@ public: void onSystemReady(); StorageId createStorage(std::string_view mountPoint, - content::pm::DataLoaderParamsParcel&& dataLoaderParams, - CreateOptions options, const DataLoaderStatusListener& statusListener, - StorageHealthCheckParams&& healthCheckParams, - const StorageHealthListener& healthListener, - const std::vector<PerUidReadTimeouts>& perUidReadTimeouts); + const content::pm::DataLoaderParamsParcel& dataLoaderParams, + CreateOptions options); StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage, CreateOptions options = CreateOptions::Default); StorageId openStorage(std::string_view path); + bool startLoading(StorageId storage, content::pm::DataLoaderParamsParcel&& dataLoaderParams, + const DataLoaderStatusListener& statusListener, + StorageHealthCheckParams&& healthCheckParams, + const StorageHealthListener& healthListener, + const std::vector<PerUidReadTimeouts>& perUidReadTimeouts); + int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind); int unbind(StorageId storage, std::string_view target); void deleteStorage(StorageId storage); @@ -156,7 +163,9 @@ public: int unlink(StorageId storage, std::string_view path); int isFileFullyLoaded(StorageId storage, std::string_view filePath) const; - LoadingProgress getLoadingProgress(StorageId storage) const; + + LoadingProgress getLoadingProgress(StorageId storage, bool stopOnFirstIncomplete) const; + bool registerLoadingProgressListener(StorageId storage, const StorageLoadingProgressListener& progressListener); bool unregisterLoadingProgressListener(StorageId storage); @@ -167,8 +176,6 @@ public: RawMetadata getMetadata(StorageId storage, std::string_view path) const; RawMetadata getMetadata(StorageId storage, FileId node) const; - bool startLoading(StorageId storage) const; - bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath, std::string_view libDirRelativePath, std::string_view abi, bool extractNativeLibs); @@ -388,7 +395,8 @@ private: binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs); int isFileFullyLoadedFromPath(const IncFsMount& ifs, std::string_view filePath) const; - LoadingProgress getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path) const; + LoadingProgress getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path, + bool stopOnFirstIncomplete) const; int setFileContent(const IfsMountPtr& ifs, const incfs::FileId& fileId, std::string_view debugFilePath, std::span<const uint8_t> data) const; diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp index dfa6083691a9..3573177af185 100644 --- a/services/incremental/ServiceWrappers.cpp +++ b/services/incremental/ServiceWrappers.cpp @@ -220,6 +220,11 @@ public: timeout.minPendingTimeUs = perUidTimeout.minPendingTimeUs; timeout.maxPendingTimeUs = perUidTimeout.maxPendingTimeUs; } + + LOG(ERROR) << "Set read timeouts: " << timeouts.size() << " [" + << (timeouts.empty() ? -1 : timeouts.front().uid) << "@" + << (timeouts.empty() ? -1 : timeouts.front().minTimeUs / 1000) << "ms]"; + return incfs::setUidReadTimeouts(control, timeouts); } }; diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp index f0deba7db01c..8713f9d3d821 100644 --- a/services/incremental/test/IncrementalServiceTest.cpp +++ b/services/incremental/test/IncrementalServiceTest.cpp @@ -678,9 +678,9 @@ TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsFails) { mVold->mountIncFsFails(); EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_LT(storageId, 0); } @@ -689,9 +689,9 @@ TEST_F(IncrementalServiceTest, testCreateStorageMountIncFsInvalidControlParcel) EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(0); EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_LT(storageId, 0); } @@ -702,9 +702,9 @@ TEST_F(IncrementalServiceTest, testCreateStorageMakeFileFails) { EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0); EXPECT_CALL(*mVold, unmountIncFs(_)); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_LT(storageId, 0); } @@ -716,9 +716,9 @@ TEST_F(IncrementalServiceTest, testCreateStorageBindMountFails) { EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(0); EXPECT_CALL(*mVold, unmountIncFs(_)); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_LT(storageId, 0); } @@ -734,24 +734,24 @@ TEST_F(IncrementalServiceTest, testCreateStoragePrepareDataLoaderFails) { EXPECT_CALL(*mDataLoader, destroy(_)).Times(0); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); - ASSERT_LT(storageId, 0); + 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(*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, start(_)).Times(1); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); + mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, {}, {}); mIncrementalService->deleteStorage(storageId); } @@ -759,14 +759,15 @@ TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) { EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2); EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2); - EXPECT_CALL(*mDataLoader, start(_)).Times(0); + EXPECT_CALL(*mDataLoader, start(_)).Times(2); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + 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. mDataLoaderManager->setDataLoaderStatusDestroyed(); } @@ -780,12 +781,13 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderCreate) { EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); + ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, + {}, {})); mDataLoaderManager->setDataLoaderStatusCreated(); - ASSERT_TRUE(mIncrementalService->startLoading(storageId)); mDataLoaderManager->setDataLoaderStatusStarted(); } @@ -793,16 +795,17 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) { mDataLoader->initializeCreateOkNoStatus(); EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(1); EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1); - EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2); + 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, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_TRUE(mIncrementalService->startLoading(storageId)); + ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, + {}, {})); mDataLoaderManager->setDataLoaderStatusCreated(); } @@ -815,10 +818,12 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderCreateUnavailable) { EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); + ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, + {}, {})); mDataLoaderManager->setDataLoaderStatusUnavailable(); } @@ -836,10 +841,12 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) { EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1); EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); + ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, + {}, {})); mDataLoaderManager->setDataLoaderStatusUnavailable(); ASSERT_NE(nullptr, mLooper->mCallback); ASSERT_NE(nullptr, mLooper->mCallbackData); @@ -890,10 +897,12 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderUnhealthyStorage) { kFirstTimestampUs - std::chrono::duration_cast<MCS>(unhealthyTimeout).count(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, std::move(params), listener, {}); + 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); @@ -985,10 +994,12 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) { // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + 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); } @@ -1006,10 +1017,12 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndDisabled) { // Not expecting callback removal. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + 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); @@ -1032,10 +1045,12 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChang // After callback is called, disable read logs and remove callback. EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(1); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + 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, {}); @@ -1051,10 +1066,12 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) { EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0); EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + 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); } @@ -1068,10 +1085,12 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionNoCrossUse EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0); EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + 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); } @@ -1087,18 +1106,20 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) { EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(0); EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + 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, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); std::string dir_path("test"); // Expecting incfs to call makeDir on a path like: @@ -1115,9 +1136,9 @@ TEST_F(IncrementalServiceTest, testMakeDirectory) { TEST_F(IncrementalServiceTest, testMakeDirectories) { TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); auto first = "first"sv; auto second = "second"sv; auto third = "third"sv; @@ -1138,9 +1159,9 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithNoFile) { mFs->hasNoFile(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk")); } @@ -1149,9 +1170,9 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedFailsWithFailedRanges) { mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1); ASSERT_EQ(-1, mIncrementalService->isFileFullyLoaded(storageId, "base.apk")); } @@ -1161,9 +1182,9 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccessWithEmptyRanges) { mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1); ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk")); } @@ -1173,9 +1194,9 @@ TEST_F(IncrementalServiceTest, testIsFileFullyLoadedSuccess) { mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1); ASSERT_EQ(0, mIncrementalService->isFileFullyLoaded(storageId, "base.apk")); } @@ -1185,10 +1206,12 @@ TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithNoFile) { mFs->hasNoFile(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); - ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress()); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); + ASSERT_EQ(1, + mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false) + .getProgress()); } TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) { @@ -1196,11 +1219,13 @@ TEST_F(IncrementalServiceTest, testGetLoadingProgressFailsWithFailedRanges) { mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(1); - ASSERT_EQ(-1, mIncrementalService->getLoadingProgress(storageId).getProgress()); + ASSERT_EQ(-1, + mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false) + .getProgress()); } TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) { @@ -1208,11 +1233,13 @@ TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccessWithEmptyRanges) { mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3); - ASSERT_EQ(1, mIncrementalService->getLoadingProgress(storageId).getProgress()); + ASSERT_EQ(1, + mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false) + .getProgress()); } TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) { @@ -1220,11 +1247,13 @@ TEST_F(IncrementalServiceTest, testGetLoadingProgressSuccess) { mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); EXPECT_CALL(*mIncFs, countFilledBlocks(_, _)).Times(3); - ASSERT_EQ(0.5, mIncrementalService->getLoadingProgress(storageId).getProgress()); + ASSERT_EQ(0.5, + mIncrementalService->getLoadingProgress(storageId, /*stopOnFirstIncomplete=*/false) + .getProgress()); } TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) { @@ -1232,9 +1261,9 @@ TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerSuccess) { mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); sp<NiceMock<MockStorageLoadingProgressListener>> listener{ new NiceMock<MockStorageLoadingProgressListener>}; NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get(); @@ -1257,9 +1286,9 @@ TEST_F(IncrementalServiceTest, testRegisterLoadingProgressListenerFailsToGetProg mFs->hasFiles(); TemporaryDir tempDir; - int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, - {}, {}, {}, {}); + int storageId = + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); sp<NiceMock<MockStorageLoadingProgressListener>> listener{ new NiceMock<MockStorageLoadingProgressListener>}; NiceMock<MockStorageLoadingProgressListener>* listenerMock = listener.get(); @@ -1275,10 +1304,12 @@ TEST_F(IncrementalServiceTest, testRegisterStorageHealthListenerSuccess) { TemporaryDir tempDir; int storageId = - mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, {}, - StorageHealthCheckParams{}, listener, {}); + mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel, + IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); + mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {}, listener, + {}); + StorageHealthCheckParams newParams; newParams.blockedTimeoutMs = 10000; newParams.unhealthyTimeoutMs = 20000; @@ -1378,19 +1409,19 @@ 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(0); + EXPECT_CALL(*mDataLoader, start(_)).Times(1); EXPECT_CALL(*mDataLoader, destroy(_)).Times(1); EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0); EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0); EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2); TemporaryDir tempDir; int storageId = - mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, {}, {}, - {}, - createPerUidTimeouts( - {{0, 1, 2, 3}, {1, 2, 3, 4}, {2, 3, 4, 5}})); + 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) { @@ -1410,13 +1441,12 @@ TEST_F(IncrementalServiceTest, testPerUidTimeoutsSuccess) { TemporaryDir tempDir; int storageId = - mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), - IncrementalService::CreateOptions::CreateNew, {}, {}, - {}, - createPerUidTimeouts({{0, 1, 2, 3}, - {1, 2, 3, 4}, - {2, 3, 4, 100000000}})); + 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. |