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