/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "dataloader.h" namespace android::dataloader { namespace details { struct DataLoaderImpl : public ::DataLoader { DataLoaderImpl(DataLoaderPtr&& dataLoader) : mDataLoader(std::move(dataLoader)) { getFeatures = [](DataLoader* self) -> DataLoaderFeatures { return static_cast(self)->mDataLoader->getFeatures(); }; onStart = [](DataLoader* self) -> bool { return static_cast(self)->mDataLoader->onStart(); }; onStop = [](DataLoader* self) { return static_cast(self)->mDataLoader->onStop(); }; onDestroy = [](DataLoader* self) { auto me = static_cast(self); me->mDataLoader->onDestroy(); delete me; }; onPrepareImage = [](DataLoader* self, const ::DataLoaderInstallationFile addedFiles[], int addedFilesCount) -> bool { return static_cast(self)->mDataLoader->onPrepareImage( DataLoaderInstallationFiles(addedFiles, addedFilesCount)); }; onPendingReads = [](DataLoader* self, const IncFsReadInfo pendingReads[], int pendingReadsCount) { return static_cast(self)->mDataLoader->onPendingReads( PendingReads(pendingReads, pendingReadsCount)); }; onPageReads = [](DataLoader* self, const IncFsReadInfo pageReads[], int pageReadsCount) { return static_cast(self)->mDataLoader->onPageReads( PageReads(pageReads, pageReadsCount)); }; onPendingReadsWithUid = [](DataLoader* self, const IncFsReadInfoWithUid pendingReads[], int pendingReadsCount) { return static_cast(self)->mDataLoader->onPendingReadsWithUid( PendingReadsWithUid(pendingReads, pendingReadsCount)); }; onPageReadsWithUid = [](DataLoader* self, const IncFsReadInfoWithUid pageReads[], int pageReadsCount) { return static_cast(self)->mDataLoader->onPageReadsWithUid( PageReadsWithUid(pageReads, pageReadsCount)); }; } private: DataLoaderPtr mDataLoader; }; inline DataLoaderParams createParams(const ::DataLoaderParams* params) { const DataLoaderType type((DataLoaderType)params->type); std::string packageName(params->packageName); std::string className(params->className); std::string arguments(params->arguments); return DataLoaderParams(type, std::move(packageName), std::move(className), std::move(arguments)); } inline DataLoaderInstallationFile createInstallationFile(const ::DataLoaderInstallationFile* file) { const DataLoaderLocation location((DataLoaderLocation)file->location); std::string name(file->name); IncFsSize size(file->size); RawMetadata metadata(file->metadata.data, file->metadata.data + file->metadata.size); return DataLoaderInstallationFile(location, std::move(name), size, std::move(metadata)); } struct DataLoaderFactoryImpl : public ::DataLoaderFactory { DataLoaderFactoryImpl(DataLoader::Factory&& factory) : mFactory(factory) { onCreate = [](::DataLoaderFactory* self, const ::DataLoaderParams* ndkParams, ::DataLoaderFilesystemConnectorPtr fsConnector, ::DataLoaderStatusListenerPtr statusListener, ::DataLoaderServiceVmPtr vm, ::DataLoaderServiceConnectorPtr serviceConnector, ::DataLoaderServiceParamsPtr serviceParams) { auto me = static_cast(self); ::DataLoader* result = nullptr; auto params = createParams(ndkParams); auto dataLoader = me->mFactory(vm, params); if (!dataLoader || !dataLoader->onCreate(params, static_cast(fsConnector), static_cast(statusListener), serviceConnector, serviceParams)) { return result; } result = new DataLoaderImpl(std::move(dataLoader)); return result; }; } private: DataLoader::Factory mFactory; }; } // namespace details inline void DataLoader::initialize(DataLoader::Factory&& factory) { DataLoader_Initialize_WithFeatures(new details::DataLoaderFactoryImpl(std::move(factory))); } inline DataLoaderParams::DataLoaderParams(DataLoaderType type, std::string&& packageName, std::string&& className, std::string&& arguments) : mType(type), mPackageName(std::move(packageName)), mClassName(std::move(className)), mArguments(std::move(arguments)) {} inline DataLoaderInstallationFile::DataLoaderInstallationFile(DataLoaderLocation location, std::string&& name, IncFsSize size, RawMetadata&& metadata) : mLocation(location), mName(std::move(name)), mSize(size), mMetadata(std::move(metadata)) {} inline android::incfs::UniqueFd FilesystemConnector::openForSpecialOps(FileId fid) { return android::incfs::UniqueFd(DataLoader_FilesystemConnector_openForSpecialOps(this, fid)); } inline int FilesystemConnector::writeBlocks(DataBlocks blocks) { return DataLoader_FilesystemConnector_writeBlocks(this, blocks.data(), blocks.size()); } inline RawMetadata FilesystemConnector::getRawMetadata(FileId fid) { RawMetadata metadata(INCFS_MAX_FILE_ATTR_SIZE); size_t size = metadata.size(); if (DataLoader_FilesystemConnector_getRawMetadata(this, fid, metadata.data(), &size) < 0) { return {}; } metadata.resize(size); return metadata; } inline bool FilesystemConnector::setParams(DataLoaderFilesystemParams params) { return DataLoader_FilesystemConnector_setParams(this, params); } inline bool StatusListener::reportStatus(DataLoaderStatus status) { return DataLoader_StatusListener_reportStatus(this, status); } } // namespace android::dataloader