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 17 #pragma once 18 19 #include <memory> 20 #include <string> 21 #include <vector> 22 23 #include <adb_unique_fd.h> 24 25 #include "fastdeploy/proto/ApkEntry.pb.h" 26 27 class ApkArchiveTester; 28 29 // Manipulates an APK archive. Process it by mmaping it in order to minimize 30 // I/Os. 31 class ApkArchive { 32 public: 33 friend ApkArchiveTester; 34 35 // A convenience struct to store the result of search operation when 36 // locating the EoCDr, CDr, and Signature Block. 37 struct Location { 38 off_t offset = 0; 39 off_t size = 0; 40 bool valid = false; 41 }; 42 43 ApkArchive(const std::string& path); 44 ~ApkArchive(); 45 46 com::android::fastdeploy::APKDump ExtractMetadata(); 47 48 // Parses the CDr starting from |input| and returns number of bytes consumed. 49 // Extracts local file header offset, data size and calculates MD5 hash of the record. 50 // 0 indicates invalid CDr. 51 static size_t ParseCentralDirectoryRecord(const char* input, size_t size, std::string* md5Hash, 52 int64_t* localFileHeaderOffset, int64_t* dataSize); 53 // Calculates Local File Entry size including header using offset and data size from CDr. 54 // 0 indicates invalid Local File Entry. 55 size_t CalculateLocalFileEntrySize(int64_t localFileHeaderOffset, int64_t dataSize) const; 56 57 private: 58 std::string ReadMetadata(Location loc) const; 59 60 // Retrieve the location of the Central Directory Record. 61 Location GetCDLocation(); 62 63 // Retrieve the location of the signature block starting from Central 64 // Directory Record 65 Location GetSignatureLocation(off_t cdRecordOffset); 66 67 // Find the End of Central Directory Record, starting from the end of the 68 // file. 69 off_t FindEndOfCDRecord() const; 70 71 // Find Central Directory Record, starting from the end of the file. 72 Location FindCDRecord(const char* cursor); 73 74 // Checks if the archive can be used. ready()75 bool ready() const { return fd_ >= 0; } 76 77 std::string path_; 78 off_t size_; 79 unique_fd fd_; 80 }; 81