blob: c0cd5272e7e6714f02d4954d7589cf2c3063d185 [file] [log] [blame]
Songchun Fan4f0688b2019-12-05 15:03:22 -08001/*
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
17#define ATRACE_TAG ATRACE_TAG_ADB
18#define LOG_TAG "NativeAdbDataLoaderService"
19
20#include <android-base/file.h>
21#include <android-base/logging.h>
22#include <android-base/properties.h>
23#include <android-base/stringprintf.h>
24#include <android-base/thread_annotations.h>
25#include <android-base/unique_fd.h>
26#include <cutils/trace.h>
27#include <fcntl.h>
28#include <sys/eventfd.h>
29#include <sys/poll.h>
30#include <sys/stat.h>
31#include <unistd.h>
32#include <utils/Log.h>
33
34#include <charconv>
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080035#include <span>
Songchun Fan4f0688b2019-12-05 15:03:22 -080036#include <string>
37#include <thread>
38#include <type_traits>
39#include <unordered_map>
40#include <unordered_set>
41
42#include "dataloader.h"
43
44#ifndef _WIN32
45#include <endian.h>
46#include <sys/stat.h>
47#include <unistd.h>
48#else
49#define be32toh(x) _byteswap_ulong(x)
50#define be16toh(x) _byteswap_ushort(x)
51#endif
52
53namespace {
54
55using android::base::unique_fd;
56
57using namespace std::literals;
58
59using BlockSize = int16_t;
60using FileId = int16_t;
61using BlockIdx = int32_t;
62using NumBlocks = int32_t;
63using CompressionType = int16_t;
64using RequestType = int16_t;
65
Songchun Fan8ee93062020-02-11 15:17:43 -080066static constexpr int COMMAND_SIZE = 2 + 2 + 4; // bytes
67static constexpr int HEADER_SIZE = 2 + 2 + 4 + 2; // bytes
Songchun Fan4f0688b2019-12-05 15:03:22 -080068static constexpr std::string_view OKAY = "OKAY"sv;
69
70static constexpr auto PollTimeoutMs = 5000;
71
72static constexpr auto ReadLogBufferSize = 128 * 1024 * 1024;
73static constexpr auto ReadLogMaxEntrySize = 128;
74
75struct BlockHeader {
76 FileId fileId = -1;
77 CompressionType compressionType = -1;
78 BlockIdx blockIdx = -1;
79 BlockSize blockSize = -1;
80} __attribute__((packed));
81
82static_assert(sizeof(BlockHeader) == HEADER_SIZE);
83
84static constexpr RequestType EXIT = 0;
85static constexpr RequestType BLOCK_MISSING = 1;
86static constexpr RequestType PREFETCH = 2;
87
88struct RequestCommand {
89 RequestType requestType;
90 FileId fileId;
91 BlockIdx blockIdx;
92} __attribute__((packed));
93
94static_assert(COMMAND_SIZE == sizeof(RequestCommand));
95
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080096static bool sendRequest(int fd, RequestType requestType, FileId fileId = -1,
Songchun Fan4f0688b2019-12-05 15:03:22 -080097 BlockIdx blockIdx = -1) {
Songchun Fan8ee93062020-02-11 15:17:43 -080098 const RequestCommand command{.requestType = static_cast<int16_t>(be16toh(requestType)),
99 .fileId = static_cast<int16_t>(be16toh(fileId)),
100 .blockIdx = static_cast<int32_t>(be32toh(blockIdx))};
Songchun Fan4f0688b2019-12-05 15:03:22 -0800101 return android::base::WriteFully(fd, &command, sizeof(command));
102}
103
104static int waitForDataOrSignal(int fd, int event_fd) {
105 struct pollfd pfds[2] = {{fd, POLLIN, 0}, {event_fd, POLLIN, 0}};
106 // Wait indefinitely until either data is ready or stop signal is received
107 int res = poll(pfds, 2, PollTimeoutMs);
108 if (res <= 0) {
109 return res;
110 }
111 // First check if there is a stop signal
112 if (pfds[1].revents == POLLIN) {
113 return event_fd;
114 }
115 // Otherwise check if incoming data is ready
116 if (pfds[0].revents == POLLIN) {
117 return fd;
118 }
119 return -1;
120}
121
122static bool readChunk(int fd, std::vector<uint8_t>& data) {
123 int32_t size;
124 if (!android::base::ReadFully(fd, &size, sizeof(size))) {
125 return false;
126 }
127 size = int32_t(be32toh(size));
128 if (size <= 0) {
129 return false;
130 }
131 data.resize(size);
132 return android::base::ReadFully(fd, data.data(), data.size());
133}
134
135static BlockHeader readHeader(std::span<uint8_t>& data) {
136 BlockHeader header;
137 if (data.size() < sizeof(header)) {
138 return header;
139 }
140
Songchun Fan8ee93062020-02-11 15:17:43 -0800141 header.fileId = static_cast<FileId>(be16toh(*reinterpret_cast<uint16_t*>(&data[0])));
142 header.compressionType =
143 static_cast<CompressionType>(be16toh(*reinterpret_cast<uint16_t*>(&data[2])));
144 header.blockIdx = static_cast<BlockIdx>(be32toh(*reinterpret_cast<uint32_t*>(&data[4])));
145 header.blockSize = static_cast<BlockSize>(be16toh(*reinterpret_cast<uint16_t*>(&data[8])));
Songchun Fan4f0688b2019-12-05 15:03:22 -0800146 data = data.subspan(sizeof(header));
147
148 return header;
149}
150
151static std::string extractPackageName(const std::string& staticArgs) {
152 static constexpr auto kPrefix = "package="sv;
153 static constexpr auto kSuffix = "&"sv;
154
155 const auto startPos = staticArgs.find(kPrefix);
156 if (startPos == staticArgs.npos || startPos + kPrefix.size() >= staticArgs.size()) {
157 return {};
158 }
159 const auto endPos = staticArgs.find(kSuffix, startPos + kPrefix.size());
160 return staticArgs.substr(startPos + kPrefix.size(),
Songchun Fan8ee93062020-02-11 15:17:43 -0800161 endPos == staticArgs.npos ? staticArgs.npos
162 : (endPos - (startPos + kPrefix.size())));
Songchun Fan4f0688b2019-12-05 15:03:22 -0800163}
164
165class AdbDataLoader : public android::dataloader::DataLoader {
166private:
167 // Lifecycle.
168 bool onCreate(const android::dataloader::DataLoaderParams& params,
169 android::dataloader::FilesystemConnectorPtr ifs,
170 android::dataloader::StatusListenerPtr statusListener,
171 android::dataloader::ServiceConnectorPtr,
172 android::dataloader::ServiceParamsPtr) final {
173 CHECK(ifs) << "ifs can't be null";
174 CHECK(statusListener) << "statusListener can't be null";
Songchun Fan8ee93062020-02-11 15:17:43 -0800175 ALOGE("[AdbDataLoader] onCreate: %d/%s/%s/%s/%d", params.type(),
176 params.packageName().c_str(), params.className().c_str(), params.arguments().c_str(),
177 (int)params.dynamicArgs().size());
Songchun Fan4f0688b2019-12-05 15:03:22 -0800178
179 if (params.dynamicArgs().empty()) {
180 ALOGE("[AdbDataLoader] Invalid DataLoaderParams. Need in/out FDs.");
181 return false;
182 }
183 for (auto const& namedFd : params.dynamicArgs()) {
184 if (namedFd.name == "inFd") {
185 mInFd.reset(dup(namedFd.fd));
186 }
187 if (namedFd.name == "outFd") {
188 mOutFd.reset(dup(namedFd.fd));
189 }
190 }
191 if (mInFd < 0 || mOutFd < 0) {
192 ALOGE("[AdbDataLoader] Failed to dup FDs.");
193 return false;
194 }
195
196 mEventFd.reset(eventfd(0, EFD_CLOEXEC));
197 if (mEventFd < 0) {
198 ALOGE("[AdbDataLoader] Failed to create eventfd.");
199 return false;
200 }
201
202 std::string logFile;
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800203 if (const auto packageName = extractPackageName(params.arguments()); !packageName.empty()) {
Songchun Fan4f0688b2019-12-05 15:03:22 -0800204 logFile = android::base::GetProperty("adb.readlog." + packageName, "");
205 }
206 if (logFile.empty()) {
207 logFile = android::base::GetProperty("adb.readlog", "");
208 }
209 if (!logFile.empty()) {
210 int flags = O_WRONLY | O_CREAT | O_CLOEXEC;
Songchun Fan8ee93062020-02-11 15:17:43 -0800211 mReadLogFd.reset(TEMP_FAILURE_RETRY(open(logFile.c_str(), flags, 0666)));
Songchun Fan4f0688b2019-12-05 15:03:22 -0800212 }
213
214 mIfs = ifs;
215 mStatusListener = statusListener;
216 ALOGE("[AdbDataLoader] Successfully created data loader.");
217 return true;
218 }
219
220 bool onStart() final {
221 char okay_buf[OKAY.size()];
222 if (!android::base::ReadFully(mInFd, okay_buf, OKAY.size())) {
223 ALOGE("[AdbDataLoader] Failed to receive OKAY. Abort.");
224 return false;
225 }
226 if (std::string_view(okay_buf, OKAY.size()) != OKAY) {
Songchun Fan8ee93062020-02-11 15:17:43 -0800227 ALOGE("[AdbDataLoader] Received '%.*s', expecting '%.*s'", (int)OKAY.size(), okay_buf,
228 (int)OKAY.size(), OKAY.data());
Songchun Fan4f0688b2019-12-05 15:03:22 -0800229 return false;
230 }
231
232 mReceiverThread = std::thread([this]() { receiver(); });
233 ALOGI("[AdbDataLoader] started loading...");
234 return true;
235 }
236
237 void onStop() final {
238 mStopReceiving = true;
239 eventfd_write(mEventFd, 1);
240 if (mReceiverThread.joinable()) {
241 mReceiverThread.join();
242 }
243 }
244
245 void onDestroy() final {
246 ALOGE("[AdbDataLoader] Sending EXIT to server.");
247 sendRequest(mOutFd, EXIT);
248 // Make sure the receiver thread was stopped
249 CHECK(!mReceiverThread.joinable());
250
251 mInFd.reset();
252 mOutFd.reset();
253
254 mNodeToMetaMap.clear();
255 mIdToNodeMap.clear();
256
257 flushReadLog();
258 mReadLogFd.reset();
259 }
260
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800261 // Installation callback
262 bool onPrepareImage(const android::dataloader::DataLoaderInstallationFiles& addedFiles) final {
263 return true;
264 }
265
Songchun Fan4f0688b2019-12-05 15:03:22 -0800266 // IFS callbacks.
267 void onPendingReads(const android::dataloader::PendingReads& pendingReads) final {
268 std::lock_guard lock{mMapsMutex};
269 CHECK(mIfs);
270 for (auto&& pendingRead : pendingReads) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800271 const android::dataloader::FileId id = pendingRead.id;
272 const auto blockIdx = static_cast<BlockIdx>(pendingRead.block);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800273 /*
274 ALOGI("[AdbDataLoader] Missing: %d", (int) blockIdx);
275 */
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800276 auto fileIdOr = getFileId(id);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800277 if (!fileIdOr) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800278 ALOGE("[AdbDataLoader] Failed to handle event for fileid=%s. "
Songchun Fan4f0688b2019-12-05 15:03:22 -0800279 "Ignore.",
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800280 android::incfs::toString(id).c_str());
Songchun Fan4f0688b2019-12-05 15:03:22 -0800281 continue;
282 }
283 const FileId fileId = *fileIdOr;
284 if (mRequestedFiles.insert(fileId).second) {
285 if (!sendRequest(mOutFd, PREFETCH, fileId, blockIdx)) {
286 ALOGE("[AdbDataLoader] Failed to request prefetch for "
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800287 "fileid=%s. Ignore.",
288 android::incfs::toString(id).c_str());
Songchun Fan4f0688b2019-12-05 15:03:22 -0800289 mRequestedFiles.erase(fileId);
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800290 mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800291 }
292 }
293 sendRequest(mOutFd, BLOCK_MISSING, fileId, blockIdx);
294 }
295 }
296
297 struct TracedRead {
298 uint64_t timestampUs;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800299 android::dataloader::FileId fileId;
Songchun Fan4f0688b2019-12-05 15:03:22 -0800300 uint32_t firstBlockIdx;
301 uint32_t count;
302 };
303 void onPageReads(const android::dataloader::PageReads& pageReads) final {
304 auto trace = atrace_is_tag_enabled(ATRACE_TAG);
305 auto log = mReadLogFd != -1;
306 if (CC_LIKELY(!(trace || log))) {
307 return;
308 }
309
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800310 TracedRead last = {};
Songchun Fan4f0688b2019-12-05 15:03:22 -0800311 std::lock_guard lock{mMapsMutex};
312 for (auto&& read : pageReads) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800313 if (read.id != last.fileId || read.block != last.firstBlockIdx + last.count) {
Songchun Fan4f0688b2019-12-05 15:03:22 -0800314 traceOrLogRead(last, trace, log);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800315 last = {read.bootClockTsUs, read.id, (uint32_t)read.block, 1};
Songchun Fan4f0688b2019-12-05 15:03:22 -0800316 } else {
317 ++last.count;
318 }
319 }
320 traceOrLogRead(last, trace, log);
321 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800322 void onFileCreated(android::dataloader::FileId fileid,
323 const android::dataloader::RawMetadata& metadata) {}
Songchun Fan4f0688b2019-12-05 15:03:22 -0800324
325private:
326 void receiver() {
327 std::vector<uint8_t> data;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800328 std::vector<IncFsDataBlock> instructions;
329 std::unordered_map<android::dataloader::FileId, unique_fd> writeFds;
Songchun Fan4f0688b2019-12-05 15:03:22 -0800330 while (!mStopReceiving) {
331 const int res = waitForDataOrSignal(mInFd, mEventFd);
332 if (res == 0) {
333 flushReadLog();
334 continue;
335 }
336 if (res < 0) {
337 ALOGE("[AdbDataLoader] failed to poll. Abort.");
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800338 mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800339 break;
340 }
341 if (res == mEventFd) {
342 ALOGE("[AdbDataLoader] received stop signal. Exit.");
343 break;
344 }
345 if (!readChunk(mInFd, data)) {
346 ALOGE("[AdbDataLoader] failed to read a message. Abort.");
Alex Buynytskyy1ecfcec2019-12-17 12:10:41 -0800347 mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800348 break;
349 }
350 auto remainingData = std::span(data);
351 while (!remainingData.empty()) {
352 auto header = readHeader(remainingData);
Songchun Fan8ee93062020-02-11 15:17:43 -0800353 if (header.fileId == -1 && header.compressionType == 0 && header.blockIdx == 0 &&
354 header.blockSize == 0) {
Songchun Fan4f0688b2019-12-05 15:03:22 -0800355 ALOGI("[AdbDataLoader] stop signal received. Sending "
356 "exit command (remaining bytes: %d).",
357 int(remainingData.size()));
358
359 sendRequest(mOutFd, EXIT);
360 mStopReceiving = true;
361 break;
362 }
Songchun Fan8ee93062020-02-11 15:17:43 -0800363 if (header.fileId < 0 || header.blockSize <= 0 || header.compressionType < 0 ||
364 header.blockIdx < 0) {
Songchun Fan4f0688b2019-12-05 15:03:22 -0800365 ALOGE("[AdbDataLoader] invalid header received. Abort.");
366 mStopReceiving = true;
367 break;
368 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800369 const android::dataloader::FileId id = mIdToNodeMap[header.fileId];
370 if (!android::incfs::isValidFileId(id)) {
Songchun Fan4f0688b2019-12-05 15:03:22 -0800371 ALOGE("Unknown data destination for file ID %d. "
372 "Ignore.",
373 header.fileId);
374 continue;
375 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800376
377 auto& writeFd = writeFds[id];
378 if (writeFd < 0) {
Songchun Fan8ee93062020-02-11 15:17:43 -0800379 writeFd = this->mIfs->openWrite(id);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800380 if (writeFd < 0) {
381 ALOGE("Failed to open file %d for writing (%d). Aboring.", header.fileId,
382 -writeFd);
383 break;
384 }
385 }
386
387 const auto inst = IncFsDataBlock{
388 .fileFd = writeFd,
389 .pageIndex = static_cast<IncFsBlockIndex>(header.blockIdx),
390 .compression = static_cast<IncFsCompressionKind>(header.compressionType),
391 .kind = INCFS_BLOCK_KIND_DATA,
392 .dataSize = static_cast<uint16_t>(header.blockSize),
393 .data = (const char*)remainingData.data(),
394 };
Songchun Fan4f0688b2019-12-05 15:03:22 -0800395 instructions.push_back(inst);
396 remainingData = remainingData.subspan(header.blockSize);
397 }
398 writeInstructions(instructions);
399 }
400 writeInstructions(instructions);
401 flushReadLog();
402 }
403
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800404 void writeInstructions(std::vector<IncFsDataBlock>& instructions) {
405 auto res = this->mIfs->writeBlocks(instructions);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800406 if (res != instructions.size()) {
407 ALOGE("[AdbDataLoader] failed to write data to Incfs (res=%d when "
408 "expecting %d)",
409 res, int(instructions.size()));
410 }
411 instructions.clear();
412 }
413
414 struct MetaPair {
415 android::dataloader::RawMetadata meta;
416 FileId fileId;
417 };
418
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800419 MetaPair* updateMapsForFile(android::dataloader::FileId id) {
420 android::dataloader::RawMetadata meta = mIfs->getRawMetadata(id);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800421 FileId fileId;
Songchun Fan8ee93062020-02-11 15:17:43 -0800422 auto res = std::from_chars(meta.data(), meta.data() + meta.size(), fileId);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800423 if (res.ec != std::errc{} || fileId < 0) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800424 ALOGE("[AdbDataLoader] Invalid metadata for fileid=%s (%s)",
425 android::incfs::toString(id).c_str(), meta.data());
Songchun Fan4f0688b2019-12-05 15:03:22 -0800426 return nullptr;
427 }
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800428 mIdToNodeMap[fileId] = id;
429 auto& metaPair = mNodeToMetaMap[id];
Songchun Fan4f0688b2019-12-05 15:03:22 -0800430 metaPair.meta = std::move(meta);
431 metaPair.fileId = fileId;
432 return &metaPair;
433 }
434
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800435 android::dataloader::RawMetadata* getMeta(android::dataloader::FileId id) {
436 auto it = mNodeToMetaMap.find(id);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800437 if (it != mNodeToMetaMap.end()) {
438 return &it->second.meta;
439 }
440
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800441 auto metaPair = updateMapsForFile(id);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800442 if (!metaPair) {
443 return nullptr;
444 }
445
446 return &metaPair->meta;
447 }
448
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800449 FileId* getFileId(android::dataloader::FileId id) {
450 auto it = mNodeToMetaMap.find(id);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800451 if (it != mNodeToMetaMap.end()) {
452 return &it->second.fileId;
453 }
454
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800455 auto* metaPair = updateMapsForFile(id);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800456 if (!metaPair) {
457 return nullptr;
458 }
459
460 return &metaPair->fileId;
461 }
462
463 void traceOrLogRead(const TracedRead& read, bool trace, bool log) {
464 if (!read.count) {
465 return;
466 }
467 if (trace) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800468 auto* meta = getMeta(read.fileId);
Songchun Fan8ee93062020-02-11 15:17:43 -0800469 auto str = android::base::StringPrintf("page_read: index=%lld count=%lld meta=%.*s",
470 static_cast<long long>(read.firstBlockIdx),
471 static_cast<long long>(read.count),
472 meta ? int(meta->size()) : 0,
473 meta ? meta->data() : "");
Songchun Fan4f0688b2019-12-05 15:03:22 -0800474 ATRACE_BEGIN(str.c_str());
475 ATRACE_END();
476 }
477 if (log) {
478 mReadLog.reserve(ReadLogBufferSize);
479
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800480 auto fileId = getFileId(read.fileId);
Songchun Fan8ee93062020-02-11 15:17:43 -0800481 android::base::StringAppendF(&mReadLog, "%lld:%lld:%lld:%lld\n",
482 static_cast<long long>(read.timestampUs),
483 static_cast<long long>(fileId ? *fileId : -1),
484 static_cast<long long>(read.firstBlockIdx),
485 static_cast<long long>(read.count));
Songchun Fan4f0688b2019-12-05 15:03:22 -0800486
487 if (mReadLog.size() >= mReadLog.capacity() - ReadLogMaxEntrySize) {
488 flushReadLog();
489 }
490 }
491 }
492
493 void flushReadLog() {
494 if (mReadLog.empty() || mReadLogFd == -1) {
495 return;
496 }
497
498 android::base::WriteStringToFd(mReadLog, mReadLogFd);
499 mReadLog.clear();
500 }
501
502private:
503 android::dataloader::FilesystemConnectorPtr mIfs = nullptr;
504 android::dataloader::StatusListenerPtr mStatusListener = nullptr;
505 android::base::unique_fd mInFd;
506 android::base::unique_fd mOutFd;
507 android::base::unique_fd mEventFd;
508 android::base::unique_fd mReadLogFd;
509 std::string mReadLog;
510 std::thread mReceiverThread;
511 std::mutex mMapsMutex;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800512 std::unordered_map<android::dataloader::FileId, MetaPair> mNodeToMetaMap GUARDED_BY(mMapsMutex);
513 std::unordered_map<FileId, android::dataloader::FileId> mIdToNodeMap GUARDED_BY(mMapsMutex);
Songchun Fan4f0688b2019-12-05 15:03:22 -0800514 /** Tracks which files have been requested */
515 std::unordered_set<FileId> mRequestedFiles;
516 std::atomic<bool> mStopReceiving = false;
517};
518
Songchun Fan8ee93062020-02-11 15:17:43 -0800519} // namespace
Songchun Fan4f0688b2019-12-05 15:03:22 -0800520
521int JNI_OnLoad(JavaVM* jvm, void* /* reserved */) {
Songchun Fan8ee93062020-02-11 15:17:43 -0800522 android::dataloader::DataLoader::initialize(
Alex Buynytskyy04f73912020-02-10 08:34:18 -0800523 [](auto, auto) { return std::make_unique<AdbDataLoader>(); });
Songchun Fan4f0688b2019-12-05 15:03:22 -0800524 return JNI_VERSION_1_6;
525}