• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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