Lifecycle: detecting blocked and unhealthy.
Part 1: interfaces and PM implementation. Bug: 153874006 Test: atest PackageManagerShellCommandTest PackageManagerShellCommandIncrementalTest IncrementalServiceTest Change-Id: I312dd919d2bb552bea3d72fb49fd1579882da14b
This commit is contained in:
parent
12416fba4a
commit
8ef61aebee
@ -930,6 +930,8 @@ filegroup {
|
||||
srcs: [
|
||||
"core/java/android/os/incremental/IIncrementalService.aidl",
|
||||
"core/java/android/os/incremental/IncrementalNewFileParams.aidl",
|
||||
"core/java/android/os/incremental/IStorageHealthListener.aidl",
|
||||
"core/java/android/os/incremental/StorageHealthCheckParams.aidl",
|
||||
],
|
||||
path: "core/java",
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package android.os.incremental;
|
||||
import android.content.pm.DataLoaderParamsParcel;
|
||||
import android.content.pm.IDataLoaderStatusListener;
|
||||
import android.os.incremental.IncrementalNewFileParams;
|
||||
import android.os.incremental.IStorageHealthListener;
|
||||
import android.os.incremental.StorageHealthCheckParams;
|
||||
|
||||
/** @hide */
|
||||
interface IIncrementalService {
|
||||
@ -34,7 +36,10 @@ 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, in IDataLoaderStatusListener listener, int createMode);
|
||||
int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, int createMode,
|
||||
in IDataLoaderStatusListener statusListener,
|
||||
in StorageHealthCheckParams healthCheckParams,
|
||||
in IStorageHealthListener healthListener);
|
||||
int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode);
|
||||
|
||||
/**
|
||||
|
35
core/java/android/os/incremental/IStorageHealthListener.aidl
Normal file
35
core/java/android/os/incremental/IStorageHealthListener.aidl
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os.incremental;
|
||||
|
||||
/** @hide */
|
||||
oneway interface IStorageHealthListener {
|
||||
/** OK status, no pending reads. */
|
||||
const int HEALTH_STATUS_OK = 0;
|
||||
/* Statuses depend on timeouts defined in StorageHealthCheckParams. */
|
||||
/** Pending reads detected, waiting for params.blockedTimeoutMs to confirm blocked state. */
|
||||
const int HEALTH_STATUS_READS_PENDING = 1;
|
||||
/** There are reads pending for params.blockedTimeoutMs, waiting till
|
||||
* params.unhealthyTimeoutMs to confirm unhealthy state. */
|
||||
const int HEALTH_STATUS_BLOCKED = 2;
|
||||
/** There are reads pending for params.unhealthyTimeoutMs>,
|
||||
* marking storage as unhealthy. */
|
||||
const int HEALTH_STATUS_UNHEALTHY = 3;
|
||||
|
||||
/** Health status callback. */
|
||||
void onHealthStatus(in int storageId, in int status);
|
||||
}
|
@ -65,7 +65,9 @@ public final class IncrementalFileStorages {
|
||||
public static IncrementalFileStorages initialize(Context context,
|
||||
@NonNull File stageDir,
|
||||
@NonNull DataLoaderParams dataLoaderParams,
|
||||
@Nullable IDataLoaderStatusListener dataLoaderStatusListener,
|
||||
@Nullable IDataLoaderStatusListener statusListener,
|
||||
@Nullable StorageHealthCheckParams healthCheckParams,
|
||||
@Nullable IStorageHealthListener healthListener,
|
||||
List<InstallationFileParcel> addedFiles) throws IOException {
|
||||
// TODO(b/136132412): sanity check if session should not be incremental
|
||||
IncrementalManager incrementalManager = (IncrementalManager) context.getSystemService(
|
||||
@ -75,9 +77,9 @@ public final class IncrementalFileStorages {
|
||||
throw new IOException("Failed to obtain incrementalManager.");
|
||||
}
|
||||
|
||||
final IncrementalFileStorages result =
|
||||
new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams,
|
||||
dataLoaderStatusListener);
|
||||
final IncrementalFileStorages result = new IncrementalFileStorages(stageDir,
|
||||
incrementalManager, dataLoaderParams, statusListener, healthCheckParams,
|
||||
healthListener);
|
||||
for (InstallationFileParcel file : addedFiles) {
|
||||
if (file.location == LOCATION_DATA_APP) {
|
||||
try {
|
||||
@ -100,7 +102,9 @@ public final class IncrementalFileStorages {
|
||||
private IncrementalFileStorages(@NonNull File stageDir,
|
||||
@NonNull IncrementalManager incrementalManager,
|
||||
@NonNull DataLoaderParams dataLoaderParams,
|
||||
@Nullable IDataLoaderStatusListener dataLoaderStatusListener) throws IOException {
|
||||
@Nullable IDataLoaderStatusListener statusListener,
|
||||
@Nullable StorageHealthCheckParams healthCheckParams,
|
||||
@Nullable IStorageHealthListener healthListener) throws IOException {
|
||||
try {
|
||||
mStageDir = stageDir;
|
||||
mIncrementalManager = incrementalManager;
|
||||
@ -117,10 +121,9 @@ public final class IncrementalFileStorages {
|
||||
mDefaultStorage.bind(stageDir.getAbsolutePath());
|
||||
} else {
|
||||
mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(),
|
||||
dataLoaderParams,
|
||||
dataLoaderStatusListener,
|
||||
IncrementalManager.CREATE_MODE_CREATE
|
||||
| IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false);
|
||||
dataLoaderParams, IncrementalManager.CREATE_MODE_CREATE
|
||||
| IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false,
|
||||
statusListener, healthCheckParams, healthListener);
|
||||
if (mDefaultStorage == null) {
|
||||
throw new IOException(
|
||||
"Couldn't create incremental storage at " + stageDir);
|
||||
|
@ -110,11 +110,15 @@ public final class IncrementalManager {
|
||||
*/
|
||||
@Nullable
|
||||
public IncrementalStorage createStorage(@NonNull String path,
|
||||
@NonNull DataLoaderParams params, @Nullable IDataLoaderStatusListener listener,
|
||||
@NonNull DataLoaderParams params,
|
||||
@CreateMode int createMode,
|
||||
boolean autoStartDataLoader) {
|
||||
boolean autoStartDataLoader,
|
||||
@Nullable IDataLoaderStatusListener statusListener,
|
||||
@Nullable StorageHealthCheckParams healthCheckParams,
|
||||
@Nullable IStorageHealthListener healthListener) {
|
||||
try {
|
||||
final int id = mService.createStorage(path, params.getData(), listener, createMode);
|
||||
final int id = mService.createStorage(path, params.getData(), createMode,
|
||||
statusListener, healthCheckParams, healthListener);
|
||||
if (id < 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os.incremental;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
parcelable StorageHealthCheckParams {
|
||||
/** Timeouts of the oldest pending read.
|
||||
* Valid values 0ms < blockedTimeoutMs < unhealthyTimeoutMs < storage page read timeout.
|
||||
* Invalid values will disable health checking. */
|
||||
|
||||
/** To consider storage "blocked". */
|
||||
int blockedTimeoutMs;
|
||||
/** To consider storage "unhealthy". */
|
||||
int unhealthyTimeoutMs;
|
||||
|
||||
/** After storage is marked "unhealthy", how often to check if it recovered.
|
||||
* Valid value 1000ms < unhealthyMonitoringMs. */
|
||||
int unhealthyMonitoringMs;
|
||||
}
|
@ -105,8 +105,10 @@ import android.os.RemoteException;
|
||||
import android.os.RevocableFileDescriptor;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.incremental.IStorageHealthListener;
|
||||
import android.os.incremental.IncrementalFileStorages;
|
||||
import android.os.incremental.IncrementalManager;
|
||||
import android.os.incremental.StorageHealthCheckParams;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.stats.devicepolicy.DevicePolicyEnums;
|
||||
@ -231,6 +233,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
private static final String SYSTEM_DATA_LOADER_PACKAGE = "android";
|
||||
|
||||
private static final int INCREMENTAL_STORAGE_BLOCKED_TIMEOUT_MS = 2000;
|
||||
private static final int INCREMENTAL_STORAGE_UNHEALTHY_TIMEOUT_MS = 7000;
|
||||
private static final int INCREMENTAL_STORAGE_UNHEALTHY_MONITORING_MS = 60000;
|
||||
|
||||
// TODO: enforce INSTALL_ALLOW_TEST
|
||||
// TODO: enforce INSTALL_ALLOW_DOWNGRADE
|
||||
|
||||
@ -1568,7 +1574,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
dispatchSessionFinished(error, detailMessage, null);
|
||||
}
|
||||
|
||||
private void onDataLoaderUnrecoverable() {
|
||||
private void onStorageUnhealthy() {
|
||||
if (TextUtils.isEmpty(mPackageName)) {
|
||||
// The package has not been installed.
|
||||
return;
|
||||
@ -2745,7 +2751,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
final DataLoaderParams params = this.params.dataLoaderParams;
|
||||
final boolean manualStartAndDestroy = !isIncrementalInstallation();
|
||||
final IDataLoaderStatusListener listener = new IDataLoaderStatusListener.Stub() {
|
||||
final IDataLoaderStatusListener statusListener = new IDataLoaderStatusListener.Stub() {
|
||||
@Override
|
||||
public void onStatusChanged(int dataLoaderId, int status) {
|
||||
switch (status) {
|
||||
@ -2757,7 +2763,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (mDestroyed || mDataLoaderFinished) {
|
||||
switch (status) {
|
||||
case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
|
||||
onDataLoaderUnrecoverable();
|
||||
onStorageUnhealthy();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
@ -2840,9 +2846,49 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
};
|
||||
|
||||
if (!manualStartAndDestroy) {
|
||||
final StorageHealthCheckParams healthCheckParams = new StorageHealthCheckParams();
|
||||
healthCheckParams.blockedTimeoutMs = INCREMENTAL_STORAGE_BLOCKED_TIMEOUT_MS;
|
||||
healthCheckParams.unhealthyTimeoutMs = INCREMENTAL_STORAGE_UNHEALTHY_TIMEOUT_MS;
|
||||
healthCheckParams.unhealthyMonitoringMs = INCREMENTAL_STORAGE_UNHEALTHY_MONITORING_MS;
|
||||
|
||||
final boolean systemDataLoader =
|
||||
params.getComponentName().getPackageName() == SYSTEM_DATA_LOADER_PACKAGE;
|
||||
final IStorageHealthListener healthListener = new IStorageHealthListener.Stub() {
|
||||
@Override
|
||||
public void onHealthStatus(int storageId, int status) {
|
||||
if (mDestroyed || mDataLoaderFinished) {
|
||||
// App's installed.
|
||||
switch (status) {
|
||||
case IStorageHealthListener.HEALTH_STATUS_UNHEALTHY:
|
||||
onStorageUnhealthy();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case IStorageHealthListener.HEALTH_STATUS_OK:
|
||||
break;
|
||||
case IStorageHealthListener.HEALTH_STATUS_READS_PENDING:
|
||||
case IStorageHealthListener.HEALTH_STATUS_BLOCKED:
|
||||
if (systemDataLoader) {
|
||||
// It's OK for ADB data loader to wait for pages.
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case IStorageHealthListener.HEALTH_STATUS_UNHEALTHY:
|
||||
// Even ADB installation can't wait for missing pages for too long.
|
||||
mDataLoaderFinished = true;
|
||||
dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
|
||||
"Image is missing pages required for installation.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir,
|
||||
params, listener, addedFiles);
|
||||
params, statusListener, healthCheckParams, healthListener, addedFiles);
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(),
|
||||
@ -2850,8 +2896,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataLoaderManager.bindToDataLoader(
|
||||
sessionId, params.getData(), listener)) {
|
||||
if (!dataLoaderManager.bindToDataLoader(sessionId, params.getData(), statusListener)) {
|
||||
throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
|
||||
"Failed to initialize data loader");
|
||||
}
|
||||
|
@ -118,14 +118,18 @@ binder::Status BinderIncrementalService::openStorage(const std::string& path,
|
||||
}
|
||||
|
||||
binder::Status BinderIncrementalService::createStorage(
|
||||
const std::string& path, const content::pm::DataLoaderParamsParcel& params,
|
||||
const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& listener,
|
||||
int32_t createMode, int32_t* _aidl_return) {
|
||||
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,
|
||||
int32_t* _aidl_return) {
|
||||
*_aidl_return =
|
||||
mImpl.createStorage(path, const_cast<content::pm::DataLoaderParamsParcel&&>(params),
|
||||
listener,
|
||||
android::incremental::IncrementalService::CreateOptions(
|
||||
createMode));
|
||||
android::incremental::IncrementalService::CreateOptions(createMode),
|
||||
statusListener,
|
||||
const_cast<StorageHealthCheckParams&&>(healthCheckParams),
|
||||
healthListener);
|
||||
return ok();
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,11 @@ public:
|
||||
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,
|
||||
const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& listener,
|
||||
int32_t createMode, int32_t* _aidl_return) final;
|
||||
int32_t createMode,
|
||||
const ::android::sp<::android::content::pm::IDataLoaderStatusListener>& statusListener,
|
||||
const ::android::os::incremental::StorageHealthCheckParams& healthCheckParams,
|
||||
const ::android::sp<IStorageHealthListener>& healthListener,
|
||||
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 makeBindMount(int32_t storageId, const std::string& sourcePath,
|
||||
@ -55,8 +58,7 @@ public:
|
||||
binder::Status makeDirectories(int32_t storageId, const std::string& path,
|
||||
int32_t* _aidl_return) final;
|
||||
binder::Status makeFile(int32_t storageId, const std::string& path,
|
||||
const ::android::os::incremental::IncrementalNewFileParams& params,
|
||||
int32_t* _aidl_return) final;
|
||||
const IncrementalNewFileParams& params, int32_t* _aidl_return) final;
|
||||
binder::Status makeFileFromRange(int32_t storageId, const std::string& targetPath,
|
||||
const std::string& sourcePath, int64_t start, int64_t end,
|
||||
int32_t* _aidl_return) final;
|
||||
|
@ -410,9 +410,12 @@ auto IncrementalService::getStorageSlotLocked() -> MountMap::iterator {
|
||||
}
|
||||
}
|
||||
|
||||
StorageId IncrementalService::createStorage(
|
||||
std::string_view mountPoint, DataLoaderParamsParcel&& dataLoaderParams,
|
||||
const DataLoaderStatusListener& dataLoaderStatusListener, CreateOptions options) {
|
||||
StorageId IncrementalService::createStorage(std::string_view mountPoint,
|
||||
content::pm::DataLoaderParamsParcel&& dataLoaderParams,
|
||||
CreateOptions options,
|
||||
const DataLoaderStatusListener& statusListener,
|
||||
StorageHealthCheckParams&& healthCheckParams,
|
||||
const StorageHealthListener& healthListener) {
|
||||
LOG(INFO) << "createStorage: " << mountPoint << " | " << int(options);
|
||||
if (!path::isAbsolute(mountPoint)) {
|
||||
LOG(ERROR) << "path is not absolute: " << mountPoint;
|
||||
@ -545,8 +548,8 @@ StorageId IncrementalService::createStorage(
|
||||
// Done here as well, all data structures are in good state.
|
||||
secondCleanupOnFailure.release();
|
||||
|
||||
auto dataLoaderStub =
|
||||
prepareDataLoader(*ifs, std::move(dataLoaderParams), &dataLoaderStatusListener);
|
||||
auto dataLoaderStub = prepareDataLoader(*ifs, std::move(dataLoaderParams), &statusListener,
|
||||
std::move(healthCheckParams), &healthListener);
|
||||
CHECK(dataLoaderStub);
|
||||
|
||||
mountIt->second = std::move(ifs);
|
||||
@ -1254,7 +1257,7 @@ bool IncrementalService::mountExistingImage(std::string_view root) {
|
||||
dataLoaderParams.arguments = loader.arguments();
|
||||
}
|
||||
|
||||
prepareDataLoader(*ifs, std::move(dataLoaderParams), nullptr);
|
||||
prepareDataLoader(*ifs, std::move(dataLoaderParams));
|
||||
CHECK(ifs->dataLoaderStub);
|
||||
|
||||
std::vector<std::pair<std::string, metadata::BindPoint>> bindPoints;
|
||||
@ -1338,14 +1341,18 @@ void IncrementalService::runCmdLooper() {
|
||||
|
||||
IncrementalService::DataLoaderStubPtr IncrementalService::prepareDataLoader(
|
||||
IncFsMount& ifs, DataLoaderParamsParcel&& params,
|
||||
const DataLoaderStatusListener* externalListener) {
|
||||
const DataLoaderStatusListener* statusListener,
|
||||
StorageHealthCheckParams&& healthCheckParams, const StorageHealthListener* healthListener) {
|
||||
std::unique_lock l(ifs.lock);
|
||||
prepareDataLoaderLocked(ifs, std::move(params), externalListener);
|
||||
prepareDataLoaderLocked(ifs, std::move(params), statusListener, std::move(healthCheckParams),
|
||||
healthListener);
|
||||
return ifs.dataLoaderStub;
|
||||
}
|
||||
|
||||
void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderParamsParcel&& params,
|
||||
const DataLoaderStatusListener* externalListener) {
|
||||
const DataLoaderStatusListener* statusListener,
|
||||
StorageHealthCheckParams&& healthCheckParams,
|
||||
const StorageHealthListener* healthListener) {
|
||||
if (ifs.dataLoaderStub) {
|
||||
LOG(INFO) << "Skipped data loader preparation because it already exists";
|
||||
return;
|
||||
@ -1360,7 +1367,8 @@ void IncrementalService::prepareDataLoaderLocked(IncFsMount& ifs, DataLoaderPara
|
||||
|
||||
ifs.dataLoaderStub =
|
||||
new DataLoaderStub(*this, ifs.mountId, std::move(params), std::move(fsControlParcel),
|
||||
externalListener, path::join(ifs.root, constants().mount));
|
||||
statusListener, std::move(healthCheckParams), healthListener,
|
||||
path::join(ifs.root, constants().mount));
|
||||
}
|
||||
|
||||
template <class Duration>
|
||||
@ -1680,19 +1688,24 @@ void IncrementalService::onAppOpChanged(const std::string& packageName) {
|
||||
IncrementalService::DataLoaderStub::DataLoaderStub(IncrementalService& service, MountId id,
|
||||
DataLoaderParamsParcel&& params,
|
||||
FileSystemControlParcel&& control,
|
||||
const DataLoaderStatusListener* externalListener,
|
||||
const DataLoaderStatusListener* statusListener,
|
||||
StorageHealthCheckParams&& healthCheckParams,
|
||||
const StorageHealthListener* healthListener,
|
||||
std::string&& healthPath)
|
||||
: mService(service),
|
||||
mId(id),
|
||||
mParams(std::move(params)),
|
||||
mControl(std::move(control)),
|
||||
mListener(externalListener ? *externalListener : DataLoaderStatusListener()),
|
||||
mStatusListener(statusListener ? *statusListener : DataLoaderStatusListener()),
|
||||
mHealthListener(healthListener ? *healthListener : StorageHealthListener()),
|
||||
mHealthPath(std::move(healthPath)) {
|
||||
// TODO(b/153874006): enable external health listener.
|
||||
mHealthListener = {};
|
||||
healthStatusOk();
|
||||
}
|
||||
|
||||
IncrementalService::DataLoaderStub::~DataLoaderStub() {
|
||||
if (mId != kInvalidStorageId) {
|
||||
if (isValid()) {
|
||||
cleanupResources();
|
||||
}
|
||||
}
|
||||
@ -1710,13 +1723,14 @@ void IncrementalService::DataLoaderStub::cleanupResources() {
|
||||
mStatusCondition.wait_until(lock, now + 60s, [this] {
|
||||
return mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
|
||||
});
|
||||
mListener = {};
|
||||
mStatusListener = {};
|
||||
mHealthListener = {};
|
||||
mId = kInvalidStorageId;
|
||||
}
|
||||
|
||||
sp<content::pm::IDataLoader> IncrementalService::DataLoaderStub::getDataLoader() {
|
||||
sp<IDataLoader> dataloader;
|
||||
auto status = mService.mDataLoaderManager->getDataLoader(mId, &dataloader);
|
||||
auto status = mService.mDataLoaderManager->getDataLoader(id(), &dataloader);
|
||||
if (!status.isOk()) {
|
||||
LOG(ERROR) << "Failed to get dataloader: " << status.toString8();
|
||||
return {};
|
||||
@ -1752,15 +1766,15 @@ void IncrementalService::DataLoaderStub::setTargetStatusLocked(int status) {
|
||||
auto oldStatus = mTargetStatus;
|
||||
mTargetStatus = status;
|
||||
mTargetStatusTs = Clock::now();
|
||||
LOG(DEBUG) << "Target status update for DataLoader " << mId << ": " << oldStatus << " -> "
|
||||
LOG(DEBUG) << "Target status update for DataLoader " << id() << ": " << oldStatus << " -> "
|
||||
<< status << " (current " << mCurrentStatus << ")";
|
||||
}
|
||||
|
||||
bool IncrementalService::DataLoaderStub::bind() {
|
||||
bool result = false;
|
||||
auto status = mService.mDataLoaderManager->bindToDataLoader(mId, mParams, this, &result);
|
||||
auto status = mService.mDataLoaderManager->bindToDataLoader(id(), mParams, this, &result);
|
||||
if (!status.isOk() || !result) {
|
||||
LOG(ERROR) << "Failed to bind a data loader for mount " << mId;
|
||||
LOG(ERROR) << "Failed to bind a data loader for mount " << id();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -1771,9 +1785,9 @@ bool IncrementalService::DataLoaderStub::create() {
|
||||
if (!dataloader) {
|
||||
return false;
|
||||
}
|
||||
auto status = dataloader->create(mId, mParams, mControl, this);
|
||||
auto status = dataloader->create(id(), mParams, mControl, this);
|
||||
if (!status.isOk()) {
|
||||
LOG(ERROR) << "Failed to start DataLoader: " << status.toString8();
|
||||
LOG(ERROR) << "Failed to create DataLoader: " << status.toString8();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -1784,7 +1798,7 @@ bool IncrementalService::DataLoaderStub::start() {
|
||||
if (!dataloader) {
|
||||
return false;
|
||||
}
|
||||
auto status = dataloader->start(mId);
|
||||
auto status = dataloader->start(id());
|
||||
if (!status.isOk()) {
|
||||
LOG(ERROR) << "Failed to start DataLoader: " << status.toString8();
|
||||
return false;
|
||||
@ -1793,7 +1807,7 @@ bool IncrementalService::DataLoaderStub::start() {
|
||||
}
|
||||
|
||||
bool IncrementalService::DataLoaderStub::destroy() {
|
||||
return mService.mDataLoaderManager->unbindFromDataLoader(mId).isOk();
|
||||
return mService.mDataLoaderManager->unbindFromDataLoader(id()).isOk();
|
||||
}
|
||||
|
||||
bool IncrementalService::DataLoaderStub::fsmStep() {
|
||||
@ -1852,8 +1866,8 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount
|
||||
return binder::Status::
|
||||
fromServiceSpecificError(-EINVAL, "onStatusChange came to invalid DataLoaderStub");
|
||||
}
|
||||
if (mId != mountId) {
|
||||
LOG(ERROR) << "Mount ID mismatch: expected " << mId << ", but got: " << mountId;
|
||||
if (id() != mountId) {
|
||||
LOG(ERROR) << "Mount ID mismatch: expected " << id() << ", but got: " << mountId;
|
||||
return binder::Status::fromServiceSpecificError(-EPERM, "Mount ID mismatch.");
|
||||
}
|
||||
|
||||
@ -1869,7 +1883,7 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount
|
||||
mCurrentStatus = newStatus;
|
||||
targetStatus = mTargetStatus;
|
||||
|
||||
listener = mListener;
|
||||
listener = mStatusListener;
|
||||
|
||||
if (mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE) {
|
||||
// For unavailable, unbind from DataLoader to ensure proper re-commit.
|
||||
@ -1877,7 +1891,7 @@ binder::Status IncrementalService::DataLoaderStub::onStatusChanged(MountId mount
|
||||
}
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Current status update for DataLoader " << mId << ": " << oldStatus << " -> "
|
||||
LOG(DEBUG) << "Current status update for DataLoader " << id() << ": " << oldStatus << " -> "
|
||||
<< newStatus << " (target " << targetStatus << ")";
|
||||
|
||||
if (listener) {
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <android/content/pm/FileSystemControlParcel.h>
|
||||
#include <android/content/pm/IDataLoaderStatusListener.h>
|
||||
#include <android/os/incremental/BnIncrementalServiceConnector.h>
|
||||
#include <android/os/incremental/BnStorageHealthListener.h>
|
||||
#include <android/os/incremental/StorageHealthCheckParams.h>
|
||||
#include <binder/IAppOpsCallback.h>
|
||||
#include <utils/String16.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
@ -56,10 +58,15 @@ using RawMetadata = incfs::RawMetadata;
|
||||
using Clock = std::chrono::steady_clock;
|
||||
using TimePoint = std::chrono::time_point<Clock>;
|
||||
using Seconds = std::chrono::seconds;
|
||||
using BootClockTsUs = uint64_t;
|
||||
|
||||
using IDataLoaderStatusListener = ::android::content::pm::IDataLoaderStatusListener;
|
||||
using DataLoaderStatusListener = ::android::sp<IDataLoaderStatusListener>;
|
||||
|
||||
using StorageHealthCheckParams = ::android::os::incremental::StorageHealthCheckParams;
|
||||
using IStorageHealthListener = ::android::os::incremental::IStorageHealthListener;
|
||||
using StorageHealthListener = ::android::sp<IStorageHealthListener>;
|
||||
|
||||
class IncrementalService final {
|
||||
public:
|
||||
explicit IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir);
|
||||
@ -72,6 +79,8 @@ public:
|
||||
static constexpr StorageId kInvalidStorageId = -1;
|
||||
static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max();
|
||||
|
||||
static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max();
|
||||
|
||||
enum CreateOptions {
|
||||
TemporaryBind = 1,
|
||||
PermanentBind = 2,
|
||||
@ -97,8 +106,9 @@ public:
|
||||
|
||||
StorageId createStorage(std::string_view mountPoint,
|
||||
content::pm::DataLoaderParamsParcel&& dataLoaderParams,
|
||||
const DataLoaderStatusListener& dataLoaderStatusListener,
|
||||
CreateOptions options = CreateOptions::Default);
|
||||
CreateOptions options, const DataLoaderStatusListener& statusListener,
|
||||
StorageHealthCheckParams&& healthCheckParams,
|
||||
const StorageHealthListener& healthListener);
|
||||
StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
|
||||
CreateOptions options = CreateOptions::Default);
|
||||
StorageId openStorage(std::string_view path);
|
||||
@ -161,7 +171,9 @@ private:
|
||||
DataLoaderStub(IncrementalService& service, MountId id,
|
||||
content::pm::DataLoaderParamsParcel&& params,
|
||||
content::pm::FileSystemControlParcel&& control,
|
||||
const DataLoaderStatusListener* externalListener, std::string&& healthPath);
|
||||
const DataLoaderStatusListener* statusListener,
|
||||
StorageHealthCheckParams&& healthCheckParams,
|
||||
const StorageHealthListener* healthListener, std::string&& healthPath);
|
||||
~DataLoaderStub();
|
||||
// Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will
|
||||
// result in an error.
|
||||
@ -212,7 +224,8 @@ private:
|
||||
MountId mId = kInvalidStorageId;
|
||||
content::pm::DataLoaderParamsParcel mParams;
|
||||
content::pm::FileSystemControlParcel mControl;
|
||||
DataLoaderStatusListener mListener;
|
||||
DataLoaderStatusListener mStatusListener;
|
||||
StorageHealthListener mHealthListener;
|
||||
|
||||
std::condition_variable mStatusCondition;
|
||||
int mCurrentStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
|
||||
@ -291,9 +304,13 @@ private:
|
||||
|
||||
DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs,
|
||||
content::pm::DataLoaderParamsParcel&& params,
|
||||
const DataLoaderStatusListener* externalListener = nullptr);
|
||||
const DataLoaderStatusListener* statusListener = nullptr,
|
||||
StorageHealthCheckParams&& healthCheckParams = {},
|
||||
const StorageHealthListener* healthListener = nullptr);
|
||||
void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params,
|
||||
const DataLoaderStatusListener* externalListener = nullptr);
|
||||
const DataLoaderStatusListener* statusListener = nullptr,
|
||||
StorageHealthCheckParams&& healthCheckParams = {},
|
||||
const StorageHealthListener* healthListener = nullptr);
|
||||
|
||||
BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
|
||||
StorageId findStorageId(std::string_view path) const;
|
||||
|
@ -175,6 +175,10 @@ public:
|
||||
ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final {
|
||||
return incfs::writeBlocks({blocks.data(), size_t(blocks.size())});
|
||||
}
|
||||
WaitResult waitForPendingReads(const Control& control, std::chrono::milliseconds timeout,
|
||||
std::vector<incfs::ReadInfo>* pendingReadsBuffer) const final {
|
||||
return incfs::waitForPendingReads(control, timeout, pendingReadsBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
using Control = incfs::Control;
|
||||
using FileId = incfs::FileId;
|
||||
using ErrorCode = incfs::ErrorCode;
|
||||
using WaitResult = incfs::WaitResult;
|
||||
|
||||
using ExistingMountCallback =
|
||||
std::function<void(std::string_view root, std::string_view backingDir,
|
||||
@ -90,6 +91,9 @@ public:
|
||||
virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0;
|
||||
virtual base::unique_fd openForSpecialOps(const Control& control, FileId id) const = 0;
|
||||
virtual ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const = 0;
|
||||
virtual WaitResult waitForPendingReads(
|
||||
const Control& control, std::chrono::milliseconds timeout,
|
||||
std::vector<incfs::ReadInfo>* pendingReadsBuffer) const = 0;
|
||||
};
|
||||
|
||||
class AppOpsManagerWrapper {
|
||||
|
@ -284,6 +284,9 @@ public:
|
||||
MOCK_CONST_METHOD2(unlink, ErrorCode(const Control& control, std::string_view path));
|
||||
MOCK_CONST_METHOD2(openForSpecialOps, base::unique_fd(const Control& control, FileId id));
|
||||
MOCK_CONST_METHOD1(writeBlocks, ErrorCode(std::span<const DataBlock> blocks));
|
||||
MOCK_CONST_METHOD3(waitForPendingReads,
|
||||
WaitResult(const Control& control, std::chrono::milliseconds timeout,
|
||||
std::vector<incfs::ReadInfo>* pendingReadsBuffer));
|
||||
|
||||
MockIncFs() { ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return()); }
|
||||
|
||||
@ -292,12 +295,23 @@ public:
|
||||
void openMountSuccess() {
|
||||
ON_CALL(*this, openMount(_)).WillByDefault(Invoke(this, &MockIncFs::openMountForHealth));
|
||||
}
|
||||
void waitForPendingReadsSuccess() {
|
||||
ON_CALL(*this, waitForPendingReads(_, _, _))
|
||||
.WillByDefault(Invoke(this, &MockIncFs::waitForPendingReadsForHealth));
|
||||
}
|
||||
|
||||
static constexpr auto kPendingReadsFd = 42;
|
||||
Control openMountForHealth(std::string_view) {
|
||||
return UniqueControl(IncFs_CreateControl(-1, kPendingReadsFd, -1));
|
||||
}
|
||||
|
||||
WaitResult waitForPendingReadsForHealth(
|
||||
const Control& control, std::chrono::milliseconds timeout,
|
||||
std::vector<incfs::ReadInfo>* pendingReadsBuffer) const {
|
||||
pendingReadsBuffer->push_back({.bootClockTsUs = 0});
|
||||
return android::incfs::WaitResult::HaveData;
|
||||
}
|
||||
|
||||
RawMetadata getMountInfoMetadata(const Control& control, std::string_view path) {
|
||||
metadata::Mount m;
|
||||
m.mutable_storage()->set_id(100);
|
||||
@ -499,9 +513,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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_LT(storageId, 0);
|
||||
}
|
||||
|
||||
@ -510,9 +524,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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_LT(storageId, 0);
|
||||
}
|
||||
|
||||
@ -523,9 +537,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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_LT(storageId, 0);
|
||||
}
|
||||
|
||||
@ -537,9 +551,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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_LT(storageId, 0);
|
||||
}
|
||||
|
||||
@ -555,9 +569,9 @@ 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);
|
||||
int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_LT(storageId, 0);
|
||||
}
|
||||
|
||||
@ -574,9 +588,9 @@ TEST_F(IncrementalServiceTest, testDeleteStorageSuccess) {
|
||||
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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
mIncrementalService->deleteStorage(storageId);
|
||||
}
|
||||
@ -594,9 +608,9 @@ TEST_F(IncrementalServiceTest, testDataLoaderDestroyed) {
|
||||
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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
// Simulated crash/other connection breakage.
|
||||
mDataLoaderManager->setDataLoaderStatusDestroyed();
|
||||
@ -616,9 +630,9 @@ 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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
mDataLoaderManager->setDataLoaderStatusCreated();
|
||||
ASSERT_TRUE(mIncrementalService->startLoading(storageId));
|
||||
@ -639,9 +653,9 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderPendingStart) {
|
||||
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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
ASSERT_TRUE(mIncrementalService->startLoading(storageId));
|
||||
mDataLoaderManager->setDataLoaderStatusCreated();
|
||||
@ -661,9 +675,9 @@ 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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
mDataLoaderManager->setDataLoaderStatusUnavailable();
|
||||
}
|
||||
@ -672,6 +686,7 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderRecreateOnPendingReads) {
|
||||
mVold->mountIncFsSuccess();
|
||||
mIncFs->makeFileSuccess();
|
||||
mIncFs->openMountSuccess();
|
||||
mIncFs->waitForPendingReadsSuccess();
|
||||
mVold->bindMountSuccess();
|
||||
mDataLoader->initializeCreateOkNoStatus();
|
||||
mDataLoaderManager->bindToDataLoaderSuccess();
|
||||
@ -685,9 +700,9 @@ 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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
mDataLoaderManager->setDataLoaderStatusUnavailable();
|
||||
ASSERT_NE(nullptr, mLooper->mCallback);
|
||||
@ -712,9 +727,9 @@ 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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
ASSERT_GE(mDataLoader->setStorageParams(true), 0);
|
||||
}
|
||||
@ -739,9 +754,9 @@ 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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
ASSERT_GE(mDataLoader->setStorageParams(true), 0);
|
||||
ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get());
|
||||
@ -762,9 +777,9 @@ 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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
ASSERT_LT(mDataLoader->setStorageParams(true), 0);
|
||||
}
|
||||
@ -785,9 +800,9 @@ 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, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
ASSERT_GE(storageId, 0);
|
||||
ASSERT_LT(mDataLoader->setStorageParams(true), 0);
|
||||
}
|
||||
@ -799,9 +814,9 @@ TEST_F(IncrementalServiceTest, testMakeDirectory) {
|
||||
mDataLoaderManager->bindToDataLoaderSuccess();
|
||||
mDataLoaderManager->getDataLoaderSuccess();
|
||||
TemporaryDir tempDir;
|
||||
int storageId =
|
||||
mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
|
||||
IncrementalService::CreateOptions::CreateNew);
|
||||
int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
std::string dir_path("test");
|
||||
|
||||
// Expecting incfs to call makeDir on a path like:
|
||||
@ -823,9 +838,9 @@ TEST_F(IncrementalServiceTest, testMakeDirectories) {
|
||||
mDataLoaderManager->bindToDataLoaderSuccess();
|
||||
mDataLoaderManager->getDataLoaderSuccess();
|
||||
TemporaryDir tempDir;
|
||||
int storageId =
|
||||
mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
|
||||
IncrementalService::CreateOptions::CreateNew);
|
||||
int storageId = mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel),
|
||||
IncrementalService::CreateOptions::CreateNew,
|
||||
{}, {}, {});
|
||||
auto first = "first"sv;
|
||||
auto second = "second"sv;
|
||||
auto third = "third"sv;
|
||||
|
Loading…
x
Reference in New Issue
Block a user