Merge changes from topic "LOADER_USAGE_STATS" into rvc-dev am: 50e0244012 am: 3ea7adf007

Change-Id: Idea21be4a3c6b191ab12b62fe11a61be535c4391
This commit is contained in:
Alex Buynytskyy
2020-04-02 01:05:29 +00:00
committed by Automerger Merge Worker
13 changed files with 139 additions and 93 deletions

View File

@@ -1,24 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
// edit this file. It looks like you are doing that because you have modified
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
// from an interface or a field from a parcelable and it broke the build. That
// breakage is intended.
//
// You must not make a backward incompatible changes to the AIDL files built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.os.incremental;
/* @hide */
parcelable IncrementalFileSystemControlParcel {
ParcelFileDescriptor cmd;
ParcelFileDescriptor pendingReads;
ParcelFileDescriptor log;
}

View File

@@ -1,44 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
// edit this file. It looks like you are doing that because you have modified
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
// from an interface or a field from a parcelable and it broke the build. That
// breakage is intended.
//
// You must not make a backward incompatible changes to the AIDL files built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.os.incremental;
/* @hide */
interface IIncrementalService {
int openStorage(in @utf8InCpp String path);
int createStorage(in @utf8InCpp String path, in android.content.pm.DataLoaderParamsParcel params, in android.content.pm.IDataLoaderStatusListener listener, int createMode);
int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode);
int makeBindMount(int storageId, in @utf8InCpp String sourcePath, in @utf8InCpp String targetFullPath, int bindType);
int deleteBindMount(int storageId, in @utf8InCpp String targetFullPath);
int makeDirectory(int storageId, in @utf8InCpp String path);
int makeDirectories(int storageId, in @utf8InCpp String path);
int makeFile(int storageId, in @utf8InCpp String path, in android.os.incremental.IncrementalNewFileParams params);
int makeFileFromRange(int storageId, in @utf8InCpp String targetPath, in @utf8InCpp String sourcePath, long start, long end);
int makeLink(int sourceStorageId, in @utf8InCpp String sourcePath, int destStorageId, in @utf8InCpp String destPath);
int unlink(int storageId, in @utf8InCpp String path);
boolean isFileRangeLoaded(int storageId, in @utf8InCpp String path, long start, long end);
byte[] getMetadataByPath(int storageId, in @utf8InCpp String path);
byte[] getMetadataById(int storageId, in byte[] fileId);
boolean startLoading(int storageId);
void deleteStorage(int storageId);
boolean configureNativeBinaries(int storageId, in @utf8InCpp String apkFullPath, in @utf8InCpp String libDirRelativePath, in @utf8InCpp String abi);
const int CREATE_MODE_TEMPORARY_BIND = 1;
const int CREATE_MODE_PERMANENT_BIND = 2;
const int CREATE_MODE_CREATE = 4;
const int CREATE_MODE_OPEN_EXISTING = 8;
const int BIND_TEMPORARY = 0;
const int BIND_PERMANENT = 1;
}

View File

@@ -1,25 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
// edit this file. It looks like you are doing that because you have modified
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
// from an interface or a field from a parcelable and it broke the build. That
// breakage is intended.
//
// You must not make a backward incompatible changes to the AIDL files built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.os.incremental;
/* @hide */
parcelable IncrementalNewFileParams {
long size;
byte[] fileId;
byte[] metadata;
@nullable byte[] signature;
}

View File

@@ -37,6 +37,13 @@ interface IIncrementalService {
int createStorage(in @utf8InCpp String path, in DataLoaderParamsParcel params, in IDataLoaderStatusListener listener, int createMode);
int createLinkedStorage(in @utf8InCpp String path, int otherStorageId, int createMode);
/**
* Changes storage params. Returns 0 on success, and -errno on failure.
* Use enableReadLogs to switch pages read logs reporting on and off.
* Returns 0 on success, and - errno on failure: permission check or remount.
*/
int setStorageParams(int storageId, boolean enableReadLogs);
/**
* Bind-mounts a path under a storage to a full path. Can be permanent or temporary.
*/

View File

@@ -19,11 +19,13 @@ package android.os.incremental;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.DataLoaderParams;
import android.content.pm.IDataLoaderStatusListener;
import android.os.RemoteException;
import android.system.ErrnoException;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
@@ -319,6 +321,23 @@ public final class IncrementalManager {
return nativeUnsafeGetFileSignature(path);
}
/**
* Sets storage parameters.
*
* @param enableReadLogs - enables or disables read logs. Caller has to have a permission.
*/
@RequiresPermission(android.Manifest.permission.LOADER_USAGE_STATS)
public void setStorageParams(int storageId, boolean enableReadLogs) throws ErrnoException {
try {
int res = mService.setStorageParams(storageId, enableReadLogs);
if (res < 0) {
throw new ErrnoException("setStorageParams", -res);
}
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/* Native methods */
private static native boolean nativeIsEnabled();
private static native boolean nativeIsIncrementalPath(@NonNull String path);

View File

@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.DataLoaderParams;
import android.content.pm.DataLoaderParamsParcel;
@@ -31,6 +32,8 @@ import android.content.pm.InstallationFile;
import android.content.pm.InstallationFileParcel;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.incremental.IncrementalManager;
import android.system.ErrnoException;
import android.util.ExceptionUtils;
import android.util.Slog;
@@ -208,6 +211,25 @@ public abstract class DataLoaderService extends Service {
private final long mNativeInstance;
}
/* Used by native FileSystemConnector. */
private boolean setStorageParams(int storageId, boolean enableReadLogs) {
IncrementalManager incrementalManager = (IncrementalManager) getSystemService(
Context.INCREMENTAL_SERVICE);
if (incrementalManager == null) {
Slog.e(TAG, "Failed to obtain incrementalManager: " + storageId);
return false;
}
try {
// This has to be done directly in incrementalManager as the storage
// might be missing still.
incrementalManager.setStorageParams(storageId, enableReadLogs);
} catch (ErrnoException e) {
Slog.e(TAG, "Failed to set params for storage: " + storageId, e);
return false;
}
return true;
}
/* Native methods */
private native boolean nativeCreateDataLoader(int storageId,
@NonNull FileSystemControlParcel control,

View File

@@ -392,6 +392,7 @@ private:
mArgs = params.arguments();
mIfs = ifs;
mStatusListener = statusListener;
mIfs->setParams({.readLogsEnabled = true});
return true;
}
bool onStart() final { return true; }

View File

@@ -155,6 +155,11 @@ binder::Status BinderIncrementalService::deleteStorage(int32_t storageId) {
return ok();
}
binder::Status BinderIncrementalService::setStorageParams(int32_t storage, bool enableReadLogs, int32_t* _aidl_return) {
*_aidl_return = mImpl.setStorageParams(storage, enableReadLogs);
return ok();
}
binder::Status BinderIncrementalService::makeDirectory(int32_t storageId, const std::string& path,
int32_t* _aidl_return) {
*_aidl_return = mImpl.makeDir(storageId, path);

View File

@@ -71,6 +71,7 @@ public:
binder::Status configureNativeBinaries(int32_t storageId, const std::string& apkFullPath,
const std::string& libDirRelativePath,
const std::string& abi, bool* _aidl_return) final;
binder::Status setStorageParams(int32_t storage, bool enableReadLogs, int32_t* _aidl_return) final;
private:
android::incremental::IncrementalService mImpl;

View File

@@ -563,6 +563,36 @@ StorageId IncrementalService::findStorageId(std::string_view path) const {
return it->second->second.storage;
}
int IncrementalService::setStorageParams(StorageId storageId, bool enableReadLogs) {
const auto ifs = getIfs(storageId);
if (!ifs) {
return -EINVAL;
}
using unique_fd = ::android::base::unique_fd;
::android::os::incremental::IncrementalFileSystemControlParcel control;
control.cmd.reset(unique_fd(dup(ifs->control.cmd())));
control.pendingReads.reset(unique_fd(dup(ifs->control.pendingReads())));
auto logsFd = ifs->control.logs();
if (logsFd >= 0) {
control.log.reset(unique_fd(dup(logsFd)));
}
std::lock_guard l(mMountOperationLock);
const auto status = mVold->setIncFsMountOptions(control, enableReadLogs);
if (!status.isOk()) {
LOG(ERROR) << "Calling Vold::setIncFsMountOptions() failed: " << status.toString8();
return status.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC
? status.serviceSpecificErrorCode() > 0 ? -status.serviceSpecificErrorCode()
: status.serviceSpecificErrorCode() == 0
? -EFAULT
: status.serviceSpecificErrorCode()
: -EIO;
}
return 0;
}
void IncrementalService::deleteStorage(StorageId storageId) {
const auto ifs = getIfs(storageId);
if (!ifs) {
@@ -737,10 +767,12 @@ int IncrementalService::makeFile(StorageId storage, std::string_view path, int m
if (auto ifs = getIfs(storage)) {
std::string normPath = normalizePathToStorage(ifs, storage, path);
if (normPath.empty()) {
LOG(ERROR) << "Internal error: storageId " << storage << " failed to normalize: " << path;
return -EINVAL;
}
auto err = mIncFs->makeFile(ifs->control, normPath, mode, id, params);
if (err) {
LOG(ERROR) << "Internal error: storageId " << storage << " failed to makeFile: " << err;
return err;
}
std::vector<uint8_t> metadataBytes;

View File

@@ -111,6 +111,8 @@ public:
int unbind(StorageId storage, std::string_view target);
void deleteStorage(StorageId storage);
int setStorageParams(StorageId storage, bool enableReadLogs);
int makeFile(StorageId storage, std::string_view path, int mode, FileId id,
incfs::NewFileParams params);
int makeDir(StorageId storage, std::string_view path, int mode = 0755);

View File

@@ -49,6 +49,7 @@ public:
virtual binder::Status unmountIncFs(const std::string& dir) const = 0;
virtual binder::Status bindMount(const std::string& sourceDir,
const std::string& targetDir) const = 0;
virtual binder::Status setIncFsMountOptions(const ::android::os::incremental::IncrementalFileSystemControlParcel& control, bool enableReadLogs) const = 0;
};
class DataLoaderManagerWrapper {
@@ -106,6 +107,9 @@ public:
const std::string& targetDir) const override {
return mInterface->bindMount(sourceDir, targetDir);
}
binder::Status setIncFsMountOptions(const ::android::os::incremental::IncrementalFileSystemControlParcel& control, bool enableReadLogs) const override {
return mInterface->setIncFsMountOptions(control, enableReadLogs);
}
private:
sp<os::IVold> mInterface;

View File

@@ -52,6 +52,8 @@ public:
MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
MOCK_CONST_METHOD2(bindMount,
binder::Status(const std::string& sourceDir, const std::string& argetDir));
MOCK_CONST_METHOD2(setIncFsMountOptions,
binder::Status(const ::android::os::incremental::IncrementalFileSystemControlParcel&, bool));
void mountIncFsFails() {
ON_CALL(*this, mountIncFs(_, _, _, _))
@@ -74,6 +76,14 @@ public:
void bindMountSuccess() {
ON_CALL(*this, bindMount(_, _)).WillByDefault(Return(binder::Status::ok()));
}
void setIncFsMountOptionsFails() const {
ON_CALL(*this, setIncFsMountOptions(_, _))
.WillByDefault(
Return(binder::Status::fromExceptionCode(1, String8("failed to set options"))));
}
void setIncFsMountOptionsSuccess() {
ON_CALL(*this, setIncFsMountOptions(_, _)).WillByDefault(Return(binder::Status::ok()));
}
binder::Status getInvalidControlParcel(const std::string& imagePath,
const std::string& targetDir, int32_t flags,
IncrementalFileSystemControlParcel* _aidl_return) {
@@ -390,6 +400,42 @@ TEST_F(IncrementalServiceTest, testStartDataLoaderSuccess) {
ASSERT_TRUE(mIncrementalService->startLoading(storageId));
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) {
mVold->mountIncFsSuccess();
mIncFs->makeFileSuccess();
mVold->bindMountSuccess();
mVold->setIncFsMountOptionsSuccess();
mDataLoaderManager->initializeDataLoaderSuccess();
mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
EXPECT_CALL(*mVold, setIncFsMountOptions(_, _));
TemporaryDir tempDir;
int storageId =
mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
IncrementalService::CreateOptions::CreateNew);
ASSERT_GE(storageId, 0);
ASSERT_GE(mIncrementalService->setStorageParams(storageId, true), 0);
}
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) {
mVold->mountIncFsSuccess();
mIncFs->makeFileSuccess();
mVold->bindMountSuccess();
mVold->setIncFsMountOptionsFails();
mDataLoaderManager->initializeDataLoaderSuccess();
mDataLoaderManager->getDataLoaderSuccess();
EXPECT_CALL(*mDataLoaderManager, destroyDataLoader(_));
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
EXPECT_CALL(*mVold, setIncFsMountOptions(_, _));
TemporaryDir tempDir;
int storageId =
mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {},
IncrementalService::CreateOptions::CreateNew);
ASSERT_GE(storageId, 0);
ASSERT_LT(mIncrementalService->setStorageParams(storageId, true), 0);
}
TEST_F(IncrementalServiceTest, testMakeDirectory) {
mVold->mountIncFsSuccess();
mIncFs->makeFileSuccess();