| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <vector> |
| |
| #include "adb_unique_fd.h" |
| #include "fastdeploy/proto/ApkEntry.pb.h" |
| |
| /** |
| * This class is responsible for creating a patch that can be accepted by the deployagent. The |
| * patch format is documented in GeneratePatch. |
| */ |
| class DeployPatchGenerator { |
| public: |
| /** |
| * Simple struct to hold mapping between local metadata and device metadata. |
| */ |
| struct SimpleEntry { |
| com::android::fastdeploy::APKEntry* localEntry; |
| com::android::fastdeploy::APKEntry* deviceEntry; |
| }; |
| |
| /** |
| * If |is_verbose| is true ApkEntries that are similar between device and host are written to |
| * the console. |
| */ |
| explicit DeployPatchGenerator(bool is_verbose) : is_verbose_(is_verbose) {} |
| /** |
| * Given a |localApkPath|, and the |deviceApkMetadataPath| from an installed APK this function |
| * writes a patch to the given |output|. |
| */ |
| bool CreatePatch(const char* localApkPath, const char* deviceApkMetadataPath, |
| android::base::borrowed_fd output); |
| |
| private: |
| bool is_verbose_; |
| |
| /** |
| * Log function only logs data to stdout when |is_verbose_| is true. |
| */ |
| void Log(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))); |
| |
| /** |
| * Helper function to log the APKMetaData structure. If |is_verbose_| is false this function |
| * early outs. |file| is the path to the file represented by |metadata|. This function is used |
| * for debugging / information. |
| */ |
| void APKMetaDataToLog(const char* file, const com::android::fastdeploy::APKMetaData& metadata); |
| /** |
| * Helper function to log APKEntry. |
| */ |
| void APKEntryToLog(const com::android::fastdeploy::APKEntry& entry); |
| |
| /** |
| * Helper function to report savings by fastdeploy. This function prints out savings even with |
| * |is_verbose_| set to false. |totalSize| is used to show a percentage of savings. Note: |
| * |totalSize| is the size of the ZipEntries. Not the size of the entire file. The metadata of |
| * the zip data needs to be sent across with every iteration. |
| * [Patch format] |
| * |Fixed String| Signature |
| * |long| New Size of Apk |
| * |Packets[]| Array of Packets |
| * |
| * [Packet Format] |
| * |long| Size of data to use from patch |
| * |byte[]| Patch data |
| * |long| Offset of data to use already on device |
| * |long| Length of data to read from device APK |
| * TODO(b/138306784): Move the patch format to a proto. |
| */ |
| void ReportSavings(const std::vector<SimpleEntry>& identicalEntries, uint64_t totalSize); |
| |
| /** |
| * This enumerates each entry in |entriesToUseOnDevice| and builds a patch file copying data |
| * from |localApkPath| where we are unable to use entries already on the device. The new patch |
| * is written to |output|. The entries are expected to be sorted by data offset from lowest to |
| * highest. |
| */ |
| void GeneratePatch(const std::vector<SimpleEntry>& entriesToUseOnDevice, |
| const char* localApkPath, android::base::borrowed_fd output); |
| |
| protected: |
| uint64_t BuildIdenticalEntries( |
| std::vector<SimpleEntry>& outIdenticalEntries, |
| const com::android::fastdeploy::APKMetaData& localApkMetadata, |
| const com::android::fastdeploy::APKMetaData& deviceApkMetadataPath); |
| }; |