Home | History | Annotate | Download | only in chre_host
      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 
     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  */
     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 
    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