1 /*
2  * Copyright (C) 2018 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 #ifndef CHRE_HOST_FRAGMENTED_LOAD_TRANSACTION_H_
18 #define CHRE_HOST_FRAGMENTED_LOAD_TRANSACTION_H_
19 
20 #include <cinttypes>
21 #include <vector>
22 
23 namespace android {
24 namespace chre {
25 
26 /**
27  * A struct which represents a single fragmented request. The caller should use
28  * this class along with FragmentedLoadTransaction to get global attributes for
29  * the transaction and encode the load request using
30  * HostProtocolHost::encodeFragmentedLoadNanoappRequest.
31  */
32 struct FragmentedLoadRequest {
33   size_t fragmentId;
34   uint32_t transactionId;
35   uint64_t appId;
36   uint32_t appVersion;
37   uint32_t targetApiVersion;
38   size_t appTotalSizeBytes;
39   std::vector<uint8_t> binary;
40 
FragmentedLoadRequestFragmentedLoadRequest41   FragmentedLoadRequest(
42       size_t fragmentId, uint32_t transactionId,
43       const std::vector<uint8_t>& binary) :
44     FragmentedLoadRequest(fragmentId, transactionId, 0, 0, 0, 0, binary) {}
45 
FragmentedLoadRequestFragmentedLoadRequest46   FragmentedLoadRequest(
47       size_t fragmentId, uint32_t transactionId, uint64_t appId,
48       uint32_t appVersion, uint32_t targetApiVersion, size_t appTotalSizeBytes,
49       const std::vector<uint8_t>& binary)
50       : fragmentId(fragmentId),
51         transactionId(transactionId),
52         appId(appId),
53         appVersion(appVersion),
54         targetApiVersion(targetApiVersion),
55         appTotalSizeBytes(appTotalSizeBytes),
56         binary(binary) {}
57 };
58 
59 /**
60  * A class which splits a load transaction into separate requests with
61  * fragmented binaries. This class can be used to send smaller chunks of data
62  * when the kernel is under memory pressure and has limited contiguous memory.
63  * The caller should use the getNextRequest() to retrieve the next available
64  * fragment and send a load request with the fragmented binary and the fragment
65  * ID.
66  */
67 class FragmentedLoadTransaction {
68  public:
69    /**
70     * @param transactionId the unique ID of the unfragmented load transaction
71     * @param appId the unique ID of the nanoapp
72     * @param appVersion the version of the nanoapp
73     * @param targetApiVersion the API version this nanoapp is targeted for
74     * @param appBinary the nanoapp binary data
75     * @param fragmentSize the size of each fragment in bytes
76     */
77   FragmentedLoadTransaction(
78       uint32_t transactionId, uint64_t appId, uint32_t appVersion,
79       uint32_t targetApiVersion, const std::vector<uint8_t>& appBinary,
80       size_t fragmentSize = kDefaultFragmentSize);
81 
82   /**
83    * Retrieves the FragmentedLoadRequest including the next fragment of the
84    * binary. Invoking getNextRequest() will prepare the next fragment for a
85    * subsequent invocation.
86    *
87    * Invoking this method when there is no next request (i.e. isComplete()
88    * returns true) is illegal.
89    *
90    * @return returns a reference to the next fragment.
91    */
92   const FragmentedLoadRequest& getNextRequest();
93 
94   /**
95    * @return true if the last fragment has been retrieved by getNextRequest(),
96    *         false otherwise.
97    */
98   bool isComplete() const;
99 
getTransactionId()100   uint32_t getTransactionId() const {
101     return mTransactionId;
102   }
103 
104  private:
105   std::vector<FragmentedLoadRequest> mFragmentRequests;
106   size_t mCurrentRequestIndex = 0;
107   uint32_t mTransactionId;
108 
109   static constexpr size_t kDefaultFragmentSize = 30 * 1024;
110 };
111 
112 }  // namespace chre
113 }  // namespace android
114 
115 #endif  // CHRE_HOST_FRAGMENTED_LOAD_TRANSACTION_H_
116