1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "dataloader.h"
19 
20 namespace android::dataloader {
21 namespace details {
22 
23 struct DataLoaderImpl : public ::DataLoader {
DataLoaderImplDataLoaderImpl24     DataLoaderImpl(DataLoaderPtr&& dataLoader) : mDataLoader(std::move(dataLoader)) {
25         getFeatures = [](DataLoader* self) -> DataLoaderFeatures {
26             return static_cast<DataLoaderImpl*>(self)->mDataLoader->getFeatures();
27         };
28         onStart = [](DataLoader* self) -> bool {
29             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onStart();
30         };
31         onStop = [](DataLoader* self) {
32             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onStop();
33         };
34         onDestroy = [](DataLoader* self) {
35             auto me = static_cast<DataLoaderImpl*>(self);
36             me->mDataLoader->onDestroy();
37             delete me;
38         };
39         onPrepareImage = [](DataLoader* self, const ::DataLoaderInstallationFile addedFiles[],
40                             int addedFilesCount) -> bool {
41             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPrepareImage(
42                     DataLoaderInstallationFiles(addedFiles, addedFilesCount));
43         };
44         onPendingReads = [](DataLoader* self, const IncFsReadInfo pendingReads[],
45                             int pendingReadsCount) {
46             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPendingReads(
47                     PendingReads(pendingReads, pendingReadsCount));
48         };
49         onPageReads = [](DataLoader* self, const IncFsReadInfo pageReads[], int pageReadsCount) {
50             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPageReads(
51                     PageReads(pageReads, pageReadsCount));
52         };
53         onPendingReadsWithUid = [](DataLoader* self, const IncFsReadInfoWithUid pendingReads[],
54                                    int pendingReadsCount) {
55             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPendingReadsWithUid(
56                     PendingReadsWithUid(pendingReads, pendingReadsCount));
57         };
58         onPageReadsWithUid = [](DataLoader* self, const IncFsReadInfoWithUid pageReads[],
59                                 int pageReadsCount) {
60             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPageReadsWithUid(
61                     PageReadsWithUid(pageReads, pageReadsCount));
62         };
63     }
64 
65 private:
66     DataLoaderPtr mDataLoader;
67 };
68 
createParams(const::DataLoaderParams * params)69 inline DataLoaderParams createParams(const ::DataLoaderParams* params) {
70     const DataLoaderType type((DataLoaderType)params->type);
71     std::string packageName(params->packageName);
72     std::string className(params->className);
73     std::string arguments(params->arguments);
74     return DataLoaderParams(type, std::move(packageName), std::move(className),
75                             std::move(arguments));
76 }
77 
createInstallationFile(const::DataLoaderInstallationFile * file)78 inline DataLoaderInstallationFile createInstallationFile(const ::DataLoaderInstallationFile* file) {
79     const DataLoaderLocation location((DataLoaderLocation)file->location);
80     std::string name(file->name);
81     IncFsSize size(file->size);
82     RawMetadata metadata(file->metadata.data, file->metadata.data + file->metadata.size);
83     return DataLoaderInstallationFile(location, std::move(name), size, std::move(metadata));
84 }
85 
86 struct DataLoaderFactoryImpl : public ::DataLoaderFactory {
DataLoaderFactoryImplDataLoaderFactoryImpl87     DataLoaderFactoryImpl(DataLoader::Factory&& factory) : mFactory(factory) {
88         onCreate = [](::DataLoaderFactory* self, const ::DataLoaderParams* ndkParams,
89                       ::DataLoaderFilesystemConnectorPtr fsConnector,
90                       ::DataLoaderStatusListenerPtr statusListener, ::DataLoaderServiceVmPtr vm,
91                       ::DataLoaderServiceConnectorPtr serviceConnector,
92                       ::DataLoaderServiceParamsPtr serviceParams) {
93             auto me = static_cast<DataLoaderFactoryImpl*>(self);
94             ::DataLoader* result = nullptr;
95             auto params = createParams(ndkParams);
96             auto dataLoader = me->mFactory(vm, params);
97             if (!dataLoader ||
98                 !dataLoader->onCreate(params, static_cast<FilesystemConnector*>(fsConnector),
99                                       static_cast<StatusListener*>(statusListener),
100                                       serviceConnector, serviceParams)) {
101                 return result;
102             }
103             result = new DataLoaderImpl(std::move(dataLoader));
104             return result;
105         };
106     }
107 
108 private:
109     DataLoader::Factory mFactory;
110 };
111 
112 } // namespace details
113 
initialize(DataLoader::Factory && factory)114 inline void DataLoader::initialize(DataLoader::Factory&& factory) {
115     DataLoader_Initialize_WithFeatures(new details::DataLoaderFactoryImpl(std::move(factory)));
116 }
117 
DataLoaderParams(DataLoaderType type,std::string && packageName,std::string && className,std::string && arguments)118 inline DataLoaderParams::DataLoaderParams(DataLoaderType type, std::string&& packageName,
119                                           std::string&& className, std::string&& arguments)
120       : mType(type),
121         mPackageName(std::move(packageName)),
122         mClassName(std::move(className)),
123         mArguments(std::move(arguments)) {}
124 
DataLoaderInstallationFile(DataLoaderLocation location,std::string && name,IncFsSize size,RawMetadata && metadata)125 inline DataLoaderInstallationFile::DataLoaderInstallationFile(DataLoaderLocation location,
126                                                               std::string&& name, IncFsSize size,
127                                                               RawMetadata&& metadata)
128       : mLocation(location), mName(std::move(name)), mSize(size), mMetadata(std::move(metadata)) {}
129 
openForSpecialOps(FileId fid)130 inline android::incfs::UniqueFd FilesystemConnector::openForSpecialOps(FileId fid) {
131     return android::incfs::UniqueFd(DataLoader_FilesystemConnector_openForSpecialOps(this, fid));
132 }
133 
writeBlocks(DataBlocks blocks)134 inline int FilesystemConnector::writeBlocks(DataBlocks blocks) {
135     return DataLoader_FilesystemConnector_writeBlocks(this, blocks.data(), blocks.size());
136 }
137 
getRawMetadata(FileId fid)138 inline RawMetadata FilesystemConnector::getRawMetadata(FileId fid) {
139     RawMetadata metadata(INCFS_MAX_FILE_ATTR_SIZE);
140     size_t size = metadata.size();
141     if (DataLoader_FilesystemConnector_getRawMetadata(this, fid, metadata.data(), &size) < 0) {
142         return {};
143     }
144     metadata.resize(size);
145     return metadata;
146 }
147 
setParams(DataLoaderFilesystemParams params)148 inline bool FilesystemConnector::setParams(DataLoaderFilesystemParams params) {
149     return DataLoader_FilesystemConnector_setParams(this, params);
150 }
151 
reportStatus(DataLoaderStatus status)152 inline bool StatusListener::reportStatus(DataLoaderStatus status) {
153     return DataLoader_StatusListener_reportStatus(this, status);
154 }
155 
156 } // namespace android::dataloader
157