1 /*
2  * Copyright (C) 2020 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_AUDIO_CONCURRENCY_TEST_MANAGER_H_
18 #define CHRE_AUDIO_CONCURRENCY_TEST_MANAGER_H_
19 
20 #include <cinttypes>
21 
22 #include "chre/util/optional.h"
23 #include "chre/util/singleton.h"
24 #include "chre_api/chre.h"
25 
26 namespace chre {
27 
28 namespace audio_concurrency_test {
29 
30 /**
31  * A class to manage a CHRE audio concurrency test session.
32  */
33 class Manager {
34  public:
35   enum class TestStep : uint8_t {
36     ENABLE_AUDIO = 0,  // without gap verification.
37     VERIFY_AUDIO_RESUME,
38     ENABLE_AUDIO_WITH_GAP_VERIFICATION,
39   };
40 
41   ~Manager();
42 
43   /**
44    * Handles an event from CHRE. Semantics are the same as nanoappHandleEvent.
45    */
46   void handleEvent(uint32_t senderInstanceId, uint16_t eventType,
47                    const void *eventData);
48 
49  private:
50   struct TestSession {
51     uint16_t hostEndpointId;
52     TestStep step;
53 
TestSessionTestSession54     TestSession(uint16_t id, TestStep currentStep) {
55       this->hostEndpointId = id;
56       this->step = currentStep;
57     }
58   };
59 
60   /**
61    * Handles a message from the host.
62    *
63    * @param senderInstanceId The sender instance ID of this message.
64    * @param hostData The data from the host.
65    */
66   void handleMessageFromHost(uint32_t senderInstanceId,
67                              const chreMessageFromHostData *hostData);
68 
69   /**
70    * Initiates the test given a test command from the host.
71    *
72    * @param hostEndpointId The test host endpoint ID.
73    * @param step The test step.
74    *
75    * @return true if the message was handled correctly.
76    */
77   bool handleTestCommandMessage(uint16_t hostEndpointId, TestStep step);
78 
79   /**
80    * Processes data from CHRE.
81    *
82    * @param eventType The event type as defined by CHRE.
83    * @param eventData A pointer to the data.
84    */
85   void handleDataFromChre(uint16_t eventType, const void *eventData);
86 
87   /**
88    * Handles a CHRE timer event.
89    */
90   void handleTimer();
91 
92   /**
93    * @param durationSeconds The duration of the timeout timer.
94    *
95    * @return True if the timer was set successfully.
96    */
97   bool setTimeoutTimer(uint32_t durationSeconds);
98 
99   /**
100    * Cancels the timeout timer, if pending.
101    */
102   void cancelTimeoutTimer();
103 
104   /**
105    * Performs a check on the audio data.
106    *
107    * @param data The audio data.
108    *
109    * @return true if the audio data is valid.
110    */
111   bool validateAudioDataEvent(const chreAudioDataEvent *data);
112 
113   /**
114    * @param data The audio data.
115    */
116   void handleAudioDataEvent(const chreAudioDataEvent *data);
117 
118   /**
119    * @param data The audio status data.
120    */
121   void handleAudioSourceStatusEvent(const chreAudioSourceStatusEvent *data);
122 
123   //! Use the first audio source available for this test.
124   static constexpr uint32_t kAudioHandle = 0;
125 
126   //! The audio source to use for this test.
127   struct chreAudioSource mAudioSource;
128 
129   //! The current test session.
130   Optional<TestSession> mTestSession;
131 
132   //! The handle of the timer to check timeout.
133   uint32_t mTimerHandle = CHRE_TIMER_INVALID;
134 
135   //! True if CHRE audio is enabled for this nanoapp.
136   bool mAudioEnabled = false;
137 
138   //! The last timestamp seen at the end of the last audio buffer.
139   Optional<uint64_t> mLastAudioBufferEndTimestampNs;
140 
141   //! True if there is a gap between the audio buffers.
142   bool mSawSuspendAudioEvent = false;
143 
144   //! If true, verify gaps between audio data events are accompanied with
145   //! the appropriate status change event.
146   bool mVerifyAudioGaps = false;
147 };
148 
149 // The audio concurrency test manager singleton.
150 typedef chre::Singleton<Manager> ManagerSingleton;
151 
152 }  // namespace audio_concurrency_test
153 
154 }  // namespace chre
155 
156 #endif  // CHRE_AUDIO_CONCURRENCY_TEST_MANAGER_H_
157