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
23namespace android {
24namespace 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 */
32struct 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
41  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
46  FragmentedLoadRequest(
47      size_t fragmentId, uint32_t transactionId, uint64_t appId,
48      uint32_t appVersion, uint32_t targetApiVersion,
49      size_t appTotalSizeBytes, 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 */
67class 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
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