1 /* 2 * Copyright (C) 2016 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_CORE_REQUEST_MULTIPLEXER_H_ 18 #define CHRE_CORE_REQUEST_MULTIPLEXER_H_ 19 20 #include "chre/util/dynamic_vector.h" 21 #include "chre/util/non_copyable.h" 22 23 namespace chre { 24 25 /** 26 * This class multiplexes multiple generic requests into one maximal request. 27 * This is a templated class and the template type is required to implement the 28 * following API: 29 * 30 * 1. RequestType(); 31 * 32 * RequestTypes must be default constructable and constructed to a state 33 * that is the lowest possible priority for a request. The lowest priority 34 * state must be equivalent to being restored to the initial state for the 35 * RequestType. 36 * 37 * 2. bool isEquivalentTo(const RequestType& request) const; 38 * 39 * Perform a comparison to another request to determine if they are 40 * equivalent. This is different from equality in that the request object 41 * may have other internal state that makes two requests different, but 42 * their net request is considered to be equal. This function returns true 43 * if the requests are equivalent. 44 * 45 * 3. bool mergeWith(const RequestType& request); 46 * 47 * Merges a request with the current request. This method must set the 48 * attributes of the current request to the highest priority attributes of 49 * both the current and other. The method returns true if the current 50 * request has changed. 51 */ 52 template <typename RequestType> 53 class RequestMultiplexer : public NonCopyable { 54 public: 55 RequestMultiplexer() = default; RequestMultiplexer(RequestMultiplexer && other)56 RequestMultiplexer(RequestMultiplexer &&other) { 57 *this = std::move(other); 58 } 59 60 RequestMultiplexer &operator=(RequestMultiplexer &&other) { 61 mRequests = std::move(other.mRequests); 62 63 mCurrentMaximalRequest = other.mCurrentMaximalRequest; 64 other.mCurrentMaximalRequest = RequestType(); 65 66 return *this; 67 } 68 69 /** 70 * Adds a request to the list of requests being managed by this multiplexer. 71 * 72 * @param request The request to add to the list. 73 * @param index A non-null pointer to an index that is populated with the 74 * location that the request was added. 75 * @param maximalRequestChanged A non-null pointer to a bool that is set to 76 * true if current maximal request has changed. The user of this API 77 * must query the getCurrentMaximalRequest method to get the new 78 * maximal request. 79 * @return Returns false if the request cannot be inserted into the 80 * multiplexer. 81 */ 82 bool addRequest(const RequestType &request, size_t *index, 83 bool *maximalRequestChanged); 84 85 /** 86 * Updates a request in the list of requests being managed by this 87 * multiplexer. 88 * 89 * @param index The index of the request to be updated. This param must fall 90 * in the range of indices provided by getRequests(). 91 * @param request The request to update to. 92 * @param maximalRequestChanged A non-null pointer to a bool that is set to 93 * true if the current maximal request has changed. The user of this 94 * API must query the getCurrentMaximalRequest() method to get the new 95 * maximal request. 96 */ 97 void updateRequest(size_t index, const RequestType &request, 98 bool *maximalRequestChanged); 99 100 /** 101 * Removes a request from the list of requests being managed by this 102 * multiplexer. 103 * 104 * @param index The index of the request to be removed. This index must fall 105 * in the range of indices provided by getRequests(). 106 * @param maximalRequestChanged A non-null pointer to a bool that is set to 107 * true if the current maximal request has changed. The user of this 108 * API must query the getCurrentMaximalRequest method to get the new 109 * maximal request. 110 */ 111 void removeRequest(size_t index, bool *maximalRequestChanged); 112 113 /* 114 * Removes all requests managed by this multiplexer. The maximal request will 115 * change if the multiplexer is not empty. 116 * 117 * @param maximalRequestChanged A non-null pointer to a bool that is set to 118 * true if the current maximal request has changed. 119 */ 120 void removeAllRequests(bool *maximalRequestChanged); 121 122 /** 123 * @return The list of requests managed by this multiplexer. 124 */ 125 const DynamicVector<RequestType> &getRequests() const; 126 127 /** 128 * @return Returns the current maximal request. 129 */ 130 const RequestType &getCurrentMaximalRequest() const; 131 132 private: 133 //! The list of requests to track. 134 DynamicVector<RequestType> mRequests; 135 136 //! The current maximal request as generated by this multiplexer. 137 RequestType mCurrentMaximalRequest; 138 139 /** 140 * Iterates over all tracked requests and updates the current maximal request 141 * if it has changed. 142 * 143 * @param maximalRequestChanged A non-null pointer to a bool that is set to 144 * true if the current maximal request has changed. 145 */ 146 void updateMaximalRequest(bool *maximalRequestChanged); 147 }; 148 149 } // namespace chre 150 151 #include "chre/core/request_multiplexer_impl.h" 152 153 #endif // CHRE_CORE_REQUEST_MULTIPLEXER_H_ 154