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 {
24     DataLoaderImpl(DataLoaderPtr&& dataLoader) : mDataLoader(std::move(dataLoader)) {
25         onStart = [](DataLoader* self) -> bool {
26             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onStart();
27         };
28         onStop = [](DataLoader* self) {
29             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onStop();
30         };
31         onDestroy = [](DataLoader* self) {
32             auto me = static_cast<DataLoaderImpl*>(self);
33             me->mDataLoader->onDestroy();
34             delete me;
35         };
36         onPrepareImage = [](DataLoader* self, const ::DataLoaderInstallationFile addedFiles[],
37                             int addedFilesCount) -> bool {
38             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPrepareImage(
39                     DataLoaderInstallationFiles(addedFiles, addedFilesCount));
40         };
41         onPendingReads = [](DataLoader* self, const IncFsReadInfo pendingReads[],
42                             int pendingReadsCount) {
43             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPendingReads(
44                     PendingReads(pendingReads, pendingReadsCount));
45         };
46         onPageReads = [](DataLoader* self, const IncFsReadInfo pageReads[], int pageReadsCount) {
47             return static_cast<DataLoaderImpl*>(self)->mDataLoader->onPageReads(
48                     PageReads(pageReads, pageReadsCount));
49         };
50     }
51 
52 private:
53     DataLoaderPtr mDataLoader;
54 };
55 
56 inline DataLoaderParams createParams(const ::DataLoaderParams* params) {
57     const DataLoaderType type((DataLoaderType)params->type);
58     std::string packageName(params->packageName);
59     std::string className(params->className);
60     std::string arguments(params->arguments);
61     return DataLoaderParams(type, std::move(packageName), std::move(className),
62                             std::move(arguments));
63 }
64 
65 inline DataLoaderInstallationFile createInstallationFile(const ::DataLoaderInstallationFile* file) {
66     const DataLoaderLocation location((DataLoaderLocation)file->location);
67     std::string name(file->name);
68     IncFsSize size(file->size);
69     RawMetadata metadata(file->metadata.data, file->metadata.data + file->metadata.size);
70     return DataLoaderInstallationFile(location, std::move(name), size, std::move(metadata));
71 }
72 
73 struct DataLoaderFactoryImpl : public ::DataLoaderFactory {
74     DataLoaderFactoryImpl(DataLoader::Factory&& factory) : mFactory(factory) {
75         onCreate = [](::DataLoaderFactory* self, const ::DataLoaderParams* ndkParams,
76                       ::DataLoaderFilesystemConnectorPtr fsConnector,
77                       ::DataLoaderStatusListenerPtr statusListener, ::DataLoaderServiceVmPtr vm,
78                       ::DataLoaderServiceConnectorPtr serviceConnector,
79                       ::DataLoaderServiceParamsPtr serviceParams) {
80             auto me = static_cast<DataLoaderFactoryImpl*>(self);
81             ::DataLoader* result = nullptr;
82             auto params = createParams(ndkParams);
83             auto dataLoader = me->mFactory(vm, params);
84             if (!dataLoader ||
85                 !dataLoader->onCreate(params, static_cast<FilesystemConnector*>(fsConnector),
86                                       static_cast<StatusListener*>(statusListener),
87                                       serviceConnector, serviceParams)) {
88                 return result;
89             }
90             result = new DataLoaderImpl(std::move(dataLoader));
91             return result;
92         };
93     }
94 
95 private:
96     DataLoader::Factory mFactory;
97 };
98 
99 } // namespace details
100 
101 inline void DataLoader::initialize(DataLoader::Factory&& factory) {
102     DataLoader_Initialize(new details::DataLoaderFactoryImpl(std::move(factory)));
103 }
104 
105 inline DataLoaderParams::DataLoaderParams(DataLoaderType type, std::string&& packageName,
106                                           std::string&& className, std::string&& arguments)
107       : mType(type),
108         mPackageName(std::move(packageName)),
109         mClassName(std::move(className)),
110         mArguments(std::move(arguments)) {}
111 
112 inline DataLoaderInstallationFile::DataLoaderInstallationFile(DataLoaderLocation location,
113                                                               std::string&& name, IncFsSize size,
114                                                               RawMetadata&& metadata)
115       : mLocation(location), mName(std::move(name)), mSize(size), mMetadata(std::move(metadata)) {}
116 
117 inline android::incfs::UniqueFd FilesystemConnector::openForSpecialOps(FileId fid) {
118     return android::incfs::UniqueFd(DataLoader_FilesystemConnector_openForSpecialOps(this, fid));
119 }
120 
121 inline int FilesystemConnector::writeBlocks(DataBlocks blocks) {
122     return DataLoader_FilesystemConnector_writeBlocks(this, blocks.data(), blocks.size());
123 }
124 
125 inline RawMetadata FilesystemConnector::getRawMetadata(FileId fid) {
126     RawMetadata metadata(INCFS_MAX_FILE_ATTR_SIZE);
127     size_t size = metadata.size();
128     if (DataLoader_FilesystemConnector_getRawMetadata(this, fid, metadata.data(), &size) < 0) {
129         return {};
130     }
131     metadata.resize(size);
132     return metadata;
133 }
134 
135 inline bool FilesystemConnector::setParams(DataLoaderFilesystemParams params) {
136     return DataLoader_FilesystemConnector_setParams(this, params);
137 }
138 
139 inline bool StatusListener::reportStatus(DataLoaderStatus status) {
140     return DataLoader_StatusListener_reportStatus(this, status);
141 }
142 
143 } // namespace android::dataloader
144