• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 #include "chre/platform/platform_audio.h"
18 
19 #include <cstring>
20 
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/platform/host_link.h"
23 #include "chre/platform/log.h"
24 #include "chre/platform/shared/pal_system_api.h"
25 #include "chre/platform/slpi/power_control_util.h"
26 
27 namespace chre {
28 namespace {
29 
handleAudioDataEvent(struct chreAudioDataEvent * event)30 void handleAudioDataEvent(struct chreAudioDataEvent *event) {
31   EventLoopManagerSingleton::get()->getAudioRequestManager()
32       .handleAudioDataEvent(event);
33 }
34 
handleAudioAvailability(uint32_t handle,bool available)35 void handleAudioAvailability(uint32_t handle, bool available) {
36   LOGD("SPI audio handle %" PRIu32 " available: %d", handle, available);
37   EventLoopManagerSingleton::get()->getAudioRequestManager()
38       .handleAudioAvailability(handle, available);
39 }
40 
41 }  // anonymous namespace
42 
43 const chrePalAudioCallbacks PlatformAudioBase::sAudioCallbacks = {
44   handleAudioDataEvent,
45   handleAudioAvailability,
46 };
47 
PlatformAudio()48 PlatformAudio::PlatformAudio() {}
49 
~PlatformAudio()50 PlatformAudio::~PlatformAudio() {
51   if (mAudioApi != nullptr) {
52     LOGD("Platform audio closing");
53     prePalApiCall();
54     mAudioApi->close();
55     LOGD("Platform audio closed");
56   }
57 }
58 
init()59 void PlatformAudio::init() {
60   prePalApiCall();
61   mAudioApi = chrePalAudioGetApi(CHRE_PAL_AUDIO_API_CURRENT_VERSION);
62   if (mAudioApi != nullptr) {
63     if (!mAudioApi->open(&gChrePalSystemApi, &sAudioCallbacks)) {
64       LOGD("Audio PAL open returned false");
65       mAudioApi = nullptr;
66     } else {
67       LOGD("Opened audio PAL version 0x%08" PRIx32, mAudioApi->moduleVersion);
68     }
69   } else {
70     LOGW("Requested audio PAL (version 0x%08" PRIx32 ") not found",
71          CHRE_PAL_AUDIO_API_CURRENT_VERSION);
72   }
73 }
74 
setHandleEnabled(uint32_t handle,bool enabled)75 void PlatformAudio::setHandleEnabled(uint32_t handle, bool enabled) {
76   uint32_t lastNumAudioClients = mNumAudioClients;
77 
78   if (enabled) {
79     mNumAudioClients++;
80   } else if (mNumAudioClients > 0) {
81     mNumAudioClients--;
82   } else {
83     LOGE("Invalid request to change handle enabled state");
84   }
85 
86   if (lastNumAudioClients == 0 && mNumAudioClients > 0) {
87     mTargetAudioEnabled = true;
88     if (!mCurrentAudioEnabled) {
89       LOGD("Enabling audio");
90       mCurrentAudioEnabled = true;
91       sendAudioRequest();
92     }
93   } else if (lastNumAudioClients > 0 && mNumAudioClients == 0) {
94     mTargetAudioEnabled = false;
95     if (EventLoopManagerSingleton::get()->getEventLoop()
96             .getPowerControlManager().hostIsAwake()) {
97       onHostAwake();
98     } else {
99       LOGD("Deferring disable audio");
100     }
101   }
102 }
103 
requestAudioDataEvent(uint32_t handle,uint32_t numSamples,Nanoseconds eventDelay)104 bool PlatformAudio::requestAudioDataEvent(uint32_t handle,
105                                           uint32_t numSamples,
106                                           Nanoseconds eventDelay) {
107   bool success = false;
108   if (mAudioApi != nullptr) {
109     prePalApiCall();
110     success = mAudioApi->requestAudioDataEvent(
111         handle, numSamples, eventDelay.toRawNanoseconds());
112   }
113 
114   return success;
115 }
116 
cancelAudioDataEventRequest(uint32_t handle)117 void PlatformAudio::cancelAudioDataEventRequest(uint32_t handle) {
118   if (mAudioApi != nullptr) {
119     prePalApiCall();
120     mAudioApi->cancelAudioDataEvent(handle);
121   }
122 }
123 
releaseAudioDataEvent(struct chreAudioDataEvent * event)124 void PlatformAudio::releaseAudioDataEvent(struct chreAudioDataEvent *event) {
125   if (mAudioApi != nullptr) {
126     prePalApiCall();
127     mAudioApi->releaseAudioDataEvent(event);
128   }
129 }
130 
getSourceCount()131 size_t PlatformAudio::getSourceCount() {
132   size_t sourceCount = 0;
133   if (mAudioApi != nullptr) {
134     prePalApiCall();
135     sourceCount = mAudioApi->getSourceCount();
136   }
137 
138   return sourceCount;
139 }
140 
getAudioSource(uint32_t handle,struct chreAudioSource * source) const141 bool PlatformAudio::getAudioSource(uint32_t handle,
142                                    struct chreAudioSource *source) const {
143   bool success = false;
144   if (mAudioApi != nullptr) {
145     prePalApiCall();
146     success = mAudioApi->getAudioSource(handle, source);
147   }
148 
149   return success;
150 }
151 
onHostAwake()152 void PlatformAudioBase::onHostAwake() {
153   if (mCurrentAudioEnabled && !mTargetAudioEnabled) {
154     LOGD("Disabling audio");
155     mCurrentAudioEnabled = mTargetAudioEnabled;
156     sendAudioRelease();
157   }
158 }
159 
160 }  // namespace chre
161