Inherited installation support for Incremental.
Bug: 162345970
Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest PackageManagerServiceTest ChecksumsTest
Change-Id: I360f44bc52e05553eacc448faa26f603d9eaae59
Merged-In: I360f44bc52e05553eacc448faa26f603d9eaae59
diff --git a/core/java/android/os/incremental/IIncrementalService.aidl b/core/java/android/os/incremental/IIncrementalService.aidl
index 7db5a80..3fbc284 100644
--- a/core/java/android/os/incremental/IIncrementalService.aidl
+++ b/core/java/android/os/incremental/IIncrementalService.aidl
@@ -38,14 +38,20 @@
* 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 @@
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 @@
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 59292baa..f2fe719 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -37,7 +37,6 @@
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 @@
private @NonNull final IncrementalManager mIncrementalManager;
private @NonNull final File mStageDir;
+ private @Nullable IncrementalStorage mInheritedStorage;
private @Nullable IncrementalStorage mDefaultStorage;
/**
@@ -65,6 +65,7 @@
*/
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 @@
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,42 +95,45 @@
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");
+ 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.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);
- }
+ }
+
+ 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();
@@ -149,9 +152,16 @@
/**
* 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 @@
}
/**
+ * 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 4b93270..7e7057f 100644
--- a/core/java/android/os/incremental/IncrementalManager.java
+++ b/core/java/android/os/incremental/IncrementalManager.java
@@ -22,7 +22,6 @@
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 @@
* @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 @@
* 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 5b688bb..e6ce8cd 100644
--- a/core/java/android/os/incremental/IncrementalStorage.java
+++ b/core/java/android/os/incremental/IncrementalStorage.java
@@ -18,11 +18,14 @@
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 @@
}
}
+
+ /**
+ * 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 @@
}
/**
- * 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 4eaac2e4..7c42569 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 @@
}
}
+ 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 @@
// 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 @@
};
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 d2fc5b4..f772f63 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 @@
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 d224428..b2efc71 100644
--- a/services/incremental/BinderIncrementalService.cpp
+++ b/services/incremental/BinderIncrementalService.cpp
@@ -118,18 +118,10 @@
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 @@
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 @@
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 @@
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 9a4537a..740c542 100644
--- a/services/incremental/BinderIncrementalService.h
+++ b/services/incremental/BinderIncrementalService.h
@@ -39,16 +39,18 @@
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 @@
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 c9c5489..132f973 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -356,7 +356,9 @@
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 @@
}
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
}
// 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 @@
}
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 @@
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 @@
}
totalBlocks += totalBlocksCount;
filledBlocks += filledBlocksCount;
+ if (stopOnFirstIncomplete && filledBlocks < totalBlocks) {
+ break;
+ }
}
return {filledBlocks, totalBlocks};
@@ -1877,7 +1883,7 @@
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 3066121..5d53bac 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -113,6 +113,10 @@
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 @@
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 @@
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 @@
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 @@
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 dfa6083..3573177 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -220,6 +220,11 @@
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 f0deba7..8713f9d 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -678,9 +678,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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, 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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.