File: deploy_patch_generator.h

package info (click to toggle)
android-platform-tools 35.0.2-1~exp6
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 211,716 kB
  • sloc: cpp: 995,749; java: 290,495; ansic: 145,647; xml: 58,531; python: 39,608; sh: 14,500; javascript: 5,198; asm: 4,866; makefile: 3,115; yacc: 769; awk: 368; ruby: 183; sql: 140; perl: 88; lex: 67
file content (111 lines) | stat: -rw-r--r-- 4,285 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
 * 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:
    using APKEntry = com::android::fastdeploy::APKEntry;
    using APKMetaData = com::android::fastdeploy::APKMetaData;

    /**
     * Simple struct to hold mapping between local metadata and device metadata.
     */
    struct SimpleEntry {
        const APKEntry* localEntry;
        const 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 |deviceApkMetadata| from an installed APK this function
     * writes a patch to the given |output|.
     */
    bool CreatePatch(const char* localApkPath, APKMetaData deviceApkMetadata,
                     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. This function is used for debugging / information.
     */
    void APKMetaDataToLog(const APKMetaData& metadata);
    /**
     * Helper function to log APKEntry.
     */
    void APKEntryToLog(const APKEntry& entry);

    /**
     * Given the |localApkMetadata| metadata, and the |deviceApkMetadata| from an installed APK this
     * function writes a patch to the given |output|.
     */
    bool CreatePatch(APKMetaData localApkMetadata, APKMetaData deviceApkMetadata,
                     android::base::borrowed_fd output);

    /**
     * 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 std::string& localApkPath, const std::string& deviceApkPath,
                       android::base::borrowed_fd output);

  protected:
    uint64_t BuildIdenticalEntries(std::vector<SimpleEntry>& outIdenticalEntries,
                                   const APKMetaData& localApkMetadata,
                                   const APKMetaData& deviceApkMetadata);
};