• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  *     NOTE: The request multiplexer makes use of move-semantics for certain
53  *     operations so mergeWith must perform a deep copy when creating the merged
54  *     output.
55  */
56 template <typename RequestType>
57 class RequestMultiplexer : public NonCopyable {
58  public:
59   RequestMultiplexer() = default;
RequestMultiplexer(RequestMultiplexer && other)60   RequestMultiplexer(RequestMultiplexer &&other) {
61     *this = std::move(other);
62   }
63 
64   RequestMultiplexer &operator=(RequestMultiplexer &&other) {
65     mRequests = std::move(other.mRequests);
66 
67     mCurrentMaximalRequest = other.mCurrentMaximalRequest;
68     other.mCurrentMaximalRequest = RequestType();
69 
70     return *this;
71   }
72 
73   /**
74    * Adds a request to the list of requests being managed by this multiplexer.
75    *
76    * @param request The request to add to the list.
77    * @param index A non-null pointer to an index that is populated with the
78    *              location that the request was added.
79    * @param maximalRequestChanged A non-null pointer to a bool that is set to
80    *        true if current maximal request has changed. The user of this API
81    *        must query the getCurrentMaximalRequest method to get the new
82    *        maximal request.
83    * @return Returns false if the request cannot be inserted into the
84    *         multiplexer.
85    */
86   bool addRequest(const RequestType &request, size_t *index,
87                   bool *maximalRequestChanged);
88 
89   /**
90    * Same as addRequest above, but uses move semantics.
91    */
92   bool addRequest(RequestType &&request, size_t *index,
93                   bool *maximalRequestChanged);
94 
95   /**
96    * Updates a request in the list of requests being managed by this
97    * multiplexer.
98    *
99    * @param index The index of the request to be updated. This param must fall
100    *        in the range of indices provided by getRequests().
101    * @param request The request to update to.
102    * @param maximalRequestChanged A non-null pointer to a bool that is set to
103    *        true if the current maximal request has changed. The user of this
104    *        API must query the getCurrentMaximalRequest() method to get the new
105    *        maximal request.
106    */
107   void updateRequest(size_t index, const RequestType &request,
108                      bool *maximalRequestChanged);
109 
110   /**
111    * Same as updateRequest above, but uses move semantics.
112    */
113   void updateRequest(size_t index, RequestType &&request,
114                      bool *maximalRequestChanged);
115 
116   /**
117    * Removes a request from the list of requests being managed by this
118    * multiplexer.
119    *
120    * @param index The index of the request to be removed. This index must fall
121    *        in the range of indices provided by getRequests().
122    * @param maximalRequestChanged A non-null pointer to a bool that is set to
123    *        true if the current maximal request has changed. The user of this
124    *        API must query the getCurrentMaximalRequest method to get the new
125    *        maximal request.
126    */
127   void removeRequest(size_t index, bool *maximalRequestChanged);
128 
129   /*
130    * Removes all requests managed by this multiplexer. The maximal request will
131    * change if the multiplexer is not empty.
132    *
133    * @param maximalRequestChanged A non-null pointer to a bool that is set to
134    *        true if the current maximal request has changed.
135    */
136   void removeAllRequests(bool *maximalRequestChanged);
137 
138   /**
139    * @return The list of requests managed by this multiplexer.
140    */
141   const DynamicVector<RequestType> &getRequests() const;
142 
143   /**
144    * @return Returns the current maximal request.
145    */
146   const RequestType &getCurrentMaximalRequest() const;
147 
148  protected:
149   //! The list of requests to track.
150   DynamicVector<RequestType> mRequests;
151 
152   /**
153    * Iterates over all tracked requests and updates the current maximal request
154    * if it has changed.
155    *
156    * @param maximalRequestChanged A non-null pointer to a bool that is set to
157    *        true if the current maximal request has changed.
158    */
159   void updateMaximalRequest(bool *maximalRequestChanged);
160 
161  private:
162   //! The current maximal request as generated by this multiplexer.
163   RequestType mCurrentMaximalRequest;
164 };
165 
166 }  // namespace chre
167 
168 #include "chre/core/request_multiplexer_impl.h"
169 
170 #endif  // CHRE_CORE_REQUEST_MULTIPLEXER_H_
171