• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "audio_process_in_server.h"
17 
18 #include "securec.h"
19 
20 #include "audio_errors.h"
21 #include "audio_log.h"
22 
23 namespace OHOS {
24 namespace AudioStandard {
25 namespace {
26     static constexpr int32_t VOLUME_SHIFT_NUMBER = 16; // 1 >> 16 = 65536, max volume
27 }
28 
Create(const AudioProcessConfig & processConfig,ProcessReleaseCallback * releaseCallback)29 sptr<AudioProcessInServer> AudioProcessInServer::Create(const AudioProcessConfig &processConfig,
30     ProcessReleaseCallback *releaseCallback)
31 {
32     sptr<AudioProcessInServer> process = new(std::nothrow) AudioProcessInServer(processConfig, releaseCallback);
33 
34     return process;
35 }
36 
AudioProcessInServer(const AudioProcessConfig & processConfig,ProcessReleaseCallback * releaseCallback)37 AudioProcessInServer::AudioProcessInServer(const AudioProcessConfig &processConfig,
38     ProcessReleaseCallback *releaseCallback) : processConfig_(processConfig), releaseCallback_(releaseCallback)
39 {
40     AUDIO_INFO_LOG("AudioProcessInServer()");
41 }
42 
~AudioProcessInServer()43 AudioProcessInServer::~AudioProcessInServer()
44 {
45     AUDIO_INFO_LOG("~AudioProcessInServer()");
46 }
47 
ResolveBuffer(std::shared_ptr<OHAudioBuffer> & buffer)48 int32_t AudioProcessInServer::ResolveBuffer(std::shared_ptr<OHAudioBuffer> &buffer)
49 {
50     if (!isBufferConfiged_) {
51         AUDIO_ERR_LOG("ResolveBuffer failed, buffer is not configed.");
52         return ERR_ILLEGAL_STATE;
53     }
54 
55     buffer = processBuffer_;
56     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, ERR_ILLEGAL_STATE, "ResolveBuffer failed, processBuffer_ is null.");
57 
58     return SUCCESS;
59 }
60 
RequestHandleInfo()61 int32_t AudioProcessInServer::RequestHandleInfo()
62 {
63     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
64     CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_ILLEGAL_STATE, "buffer not inited!");
65 
66     for (size_t i = 0; i < listenerList_.size(); i++) {
67         listenerList_[i]->OnUpdateHandleInfo(this);
68     }
69     return SUCCESS;
70 }
71 
Start()72 int32_t AudioProcessInServer::Start()
73 {
74     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
75     std::lock_guard<std::mutex> lock(statusLock_);
76     if (streamStatus_->load() != STREAM_STARTING) {
77         AUDIO_ERR_LOG("Start failed, invalid status.");
78         return ERR_ILLEGAL_STATE;
79     }
80 
81     for (size_t i = 0; i < listenerList_.size(); i++) {
82         listenerList_[i]->OnStart(this);
83     }
84 
85     AUDIO_INFO_LOG("Start in server success!");
86     return SUCCESS;
87 }
88 
Pause(bool isFlush)89 int32_t AudioProcessInServer::Pause(bool isFlush)
90 {
91     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
92 
93     (void)isFlush;
94     std::lock_guard<std::mutex> lock(statusLock_);
95     if (streamStatus_->load() != STREAM_PAUSING) {
96         AUDIO_ERR_LOG("Pause failed, invalid status.");
97         return ERR_ILLEGAL_STATE;
98     }
99 
100     for (size_t i = 0; i < listenerList_.size(); i++) {
101         listenerList_[i]->OnPause(this);
102     }
103 
104     AUDIO_INFO_LOG("Pause in server success!");
105     return SUCCESS;
106 }
107 
Resume()108 int32_t AudioProcessInServer::Resume()
109 {
110     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
111     std::lock_guard<std::mutex> lock(statusLock_);
112     if (streamStatus_->load() != STREAM_STARTING) {
113         AUDIO_ERR_LOG("Resume failed, invalid status.");
114         return ERR_ILLEGAL_STATE;
115     }
116 
117     for (size_t i = 0; i < listenerList_.size(); i++) {
118         listenerList_[i]->OnStart(this);
119     }
120 
121     AUDIO_INFO_LOG("Resume in server success!");
122     return SUCCESS;
123 }
124 
Stop()125 int32_t AudioProcessInServer::Stop()
126 {
127     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited!");
128 
129     std::lock_guard<std::mutex> lock(statusLock_);
130     if (streamStatus_->load() != STREAM_STOPPING) {
131         AUDIO_ERR_LOG("Stop failed, invalid status.");
132         return ERR_ILLEGAL_STATE;
133     }
134 
135     for (size_t i = 0; i < listenerList_.size(); i++) {
136         listenerList_[i]->OnPause(this); // notify endpoint?
137     }
138 
139     AUDIO_INFO_LOG("Stop in server success!");
140     return SUCCESS;
141 }
142 
Release()143 int32_t AudioProcessInServer::Release()
144 {
145     CHECK_AND_RETURN_RET_LOG(isInited_, ERR_ILLEGAL_STATE, "not inited or already released");
146 
147     isInited_ = false;
148     std::lock_guard<std::mutex> lock(statusLock_);
149     CHECK_AND_RETURN_RET_LOG(releaseCallback_ != nullptr, ERR_OPERATION_FAILED, "Failed: no service to notify.");
150 
151     int32_t ret = releaseCallback_->OnProcessRelease(this);
152     AUDIO_INFO_LOG("notify service release result: %{public}d", ret);
153     return SUCCESS;
154 }
155 
ProcessDeathRecipient(AudioProcessInServer * processInServer,ProcessReleaseCallback * processHolder)156 ProcessDeathRecipient::ProcessDeathRecipient(AudioProcessInServer *processInServer,
157     ProcessReleaseCallback *processHolder)
158 {
159     processInServer_ = processInServer;
160     processHolder_ = processHolder;
161 }
162 
OnRemoteDied(const wptr<IRemoteObject> & remote)163 void ProcessDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
164 {
165     CHECK_AND_RETURN_LOG(processHolder_ != nullptr, "processHolder_ is null.");
166     int32_t ret = processHolder_->OnProcessRelease(processInServer_);
167     AUDIO_INFO_LOG("OnRemoteDied, call release ret: %{public}d", ret);
168 }
169 
RegisterProcessCb(sptr<IRemoteObject> object)170 int32_t AudioProcessInServer::RegisterProcessCb(sptr<IRemoteObject> object)
171 {
172     sptr<IProcessCb> processCb = iface_cast<IProcessCb>(object);
173     CHECK_AND_RETURN_RET_LOG(processCb != nullptr, ERR_INVALID_PARAM, "RegisterProcessCb obj cast failed");
174     bool result = object->AddDeathRecipient(new ProcessDeathRecipient(this, releaseCallback_));
175     if (!result) {
176         AUDIO_ERR_LOG("AddDeathRecipient failed.");
177         return ERR_OPERATION_FAILED;
178     }
179 
180     return SUCCESS;
181 }
182 
Dump(int fd,const std::vector<std::u16string> & args)183 int AudioProcessInServer::Dump(int fd, const std::vector<std::u16string> &args)
184 {
185     return SUCCESS;
186 }
187 
Dump(std::stringstream & dumpStringStream)188 void AudioProcessInServer::Dump(std::stringstream &dumpStringStream)
189 {
190     dumpStringStream << std::endl << "uid:" << processConfig_.appInfo.appUid;
191     dumpStringStream << " pid:" << processConfig_.appInfo.appPid << std::endl;
192     dumpStringStream << " process info:" << std::endl;
193     dumpStringStream << " stream info:" << std::endl;
194     dumpStringStream << "   samplingRate:" << processConfig_.streamInfo.samplingRate << std::endl;
195     dumpStringStream << "   channels:" << processConfig_.streamInfo.channels << std::endl;
196     dumpStringStream << "   format:" << processConfig_.streamInfo.format << std::endl;
197     dumpStringStream << "   encoding:" << processConfig_.streamInfo.encoding << std::endl;
198     if (streamStatus_ != nullptr) {
199         dumpStringStream << "Status:" << streamStatus_->load() << std::endl;
200     }
201     dumpStringStream << std::endl;
202 }
203 
GetStreamBuffer()204 std::shared_ptr<OHAudioBuffer> AudioProcessInServer::GetStreamBuffer()
205 {
206     if (!isBufferConfiged_ || processBuffer_ == nullptr) {
207         AUDIO_ERR_LOG("GetStreamBuffer failed:process buffer not config.");
208         return nullptr;
209     }
210     return processBuffer_;
211 }
212 
GetStreamInfo()213 AudioStreamInfo AudioProcessInServer::GetStreamInfo()
214 {
215     return processConfig_.streamInfo;
216 }
217 
GetAudioStreamType()218 AudioStreamType AudioProcessInServer::GetAudioStreamType()
219 {
220     return processConfig_.streamType;
221 }
222 
PcmFormatToBits(AudioSampleFormat format)223 inline uint32_t PcmFormatToBits(AudioSampleFormat format)
224 {
225     switch (format) {
226         case SAMPLE_U8:
227             return 1; // 1 byte
228         case SAMPLE_S16LE:
229             return 2; // 2 byte
230         case SAMPLE_S24LE:
231             return 3; // 3 byte
232         case SAMPLE_S32LE:
233             return 4; // 4 byte
234         case SAMPLE_F32LE:
235             return 4; // 4 byte
236         default:
237             return 2; // 2 byte
238     }
239 }
240 
InitBufferStatus()241 int32_t AudioProcessInServer::InitBufferStatus()
242 {
243     if (processBuffer_ == nullptr) {
244         AUDIO_ERR_LOG("InitBufferStatus failed, null buffer.");
245         return ERR_ILLEGAL_STATE;
246     }
247 
248     uint32_t spanCount = processBuffer_->GetSpanCount();
249     for (uint32_t i = 0; i < spanCount; i++) {
250         SpanInfo *spanInfo = processBuffer_->GetSpanInfoByIndex(i);
251         if (spanInfo == nullptr) {
252             AUDIO_ERR_LOG("InitBufferStatus failed, null spaninfo");
253             return ERR_ILLEGAL_STATE;
254         }
255         spanInfo->spanStatus = SPAN_READ_DONE;
256         spanInfo->offsetInFrame = 0;
257 
258         spanInfo->readStartTime = 0;
259         spanInfo->readDoneTime = 0;
260 
261         spanInfo->writeStartTime = 0;
262         spanInfo->writeDoneTime = 0;
263 
264         spanInfo->volumeStart = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
265         spanInfo->volumeEnd = 1 << VOLUME_SHIFT_NUMBER; // 65536 for initialize
266         spanInfo->isMute = false;
267     }
268     return SUCCESS;
269 }
270 
ConfigProcessBuffer(uint32_t & totalSizeInframe,uint32_t & spanSizeInframe)271 int32_t AudioProcessInServer::ConfigProcessBuffer(uint32_t &totalSizeInframe, uint32_t &spanSizeInframe)
272 {
273     if (processBuffer_ != nullptr) {
274         AUDIO_INFO_LOG("ConfigProcessBuffer: process buffer already configed!");
275         return SUCCESS;
276     }
277     // check
278     if (totalSizeInframe == 0 || spanSizeInframe == 0 || totalSizeInframe % spanSizeInframe != 0) {
279         AUDIO_ERR_LOG("ConfigProcessBuffer failed: ERR_INVALID_PARAM");
280         return ERR_INVALID_PARAM;
281     }
282     totalSizeInframe_ = totalSizeInframe;
283     spanSizeInframe_ = spanSizeInframe;
284 
285     uint32_t channel = processConfig_.streamInfo.channels;
286     uint32_t formatbyte = PcmFormatToBits(processConfig_.streamInfo.format);
287     byteSizePerFrame_ = channel * formatbyte;
288 
289     // create OHAudioBuffer in server.
290     processBuffer_ = OHAudioBuffer::CreateFormLocal(totalSizeInframe_, spanSizeInframe_, byteSizePerFrame_);
291     CHECK_AND_RETURN_RET_LOG(processBuffer_ != nullptr, ERR_OPERATION_FAILED, "Create process buffer failed.");
292 
293     if (processBuffer_->GetBufferHolder() != AudioBufferHolder::AUDIO_SERVER_SHARED) {
294         AUDIO_ERR_LOG("CreateFormLocal in server failed.");
295         return ERR_ILLEGAL_STATE;
296     }
297     AUDIO_INFO_LOG("Config: totalSizeInframe:%{public}d spanSizeInframe:%{public}d byteSizePerFrame:%{public}d",
298         totalSizeInframe_, spanSizeInframe_, byteSizePerFrame_);
299 
300     // we need to clear data buffer to avoid dirty data.
301     memset_s(processBuffer_->GetDataBase(), processBuffer_->GetDataSize(), 0, processBuffer_->GetDataSize());
302     int32_t ret = InitBufferStatus();
303     AUDIO_DEBUG_LOG("clear data buffer, ret:%{public}d", ret);
304 
305     streamStatus_ = processBuffer_->GetStreamStatus();
306     CHECK_AND_RETURN_RET_LOG(streamStatus_ != nullptr, ERR_OPERATION_FAILED, "Create process buffer failed.");
307     isBufferConfiged_ = true;
308     isInited_ = true;
309     return SUCCESS;
310 }
311 
AddProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)312 int32_t AudioProcessInServer::AddProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)
313 {
314     std::lock_guard<std::mutex> lock(listenerListLock_);
315     listenerList_.push_back(listener);
316     return SUCCESS;
317 }
318 
RemoveProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)319 int32_t AudioProcessInServer::RemoveProcessStatusListener(std::shared_ptr<IProcessStatusListener> listener)
320 {
321     std::lock_guard<std::mutex> lock(listenerListLock_);
322     std::vector<std::shared_ptr<IProcessStatusListener>>::iterator it = listenerList_.begin();
323     bool isFind = false;
324     while (it != listenerList_.end()) {
325         if (*it == listener) {
326             listenerList_.erase(it);
327             isFind = true;
328             break;
329         } else {
330             it++;
331         }
332     }
333 
334     AUDIO_INFO_LOG("%{public}s the endpoint.", (isFind ? "find and remove" : "not find"));
335     return SUCCESS;
336 }
337 } // namespace AudioStandard
338 } // namespace OHOS
339