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