blob: 2b7856bd77bf3ce83a1d4a48ed6658a0b61abc48 [file] [log] [blame]
Mikhail Naganov31d46652023-01-10 18:29:25 +00001/*
2 * Copyright (C) 2023 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#define LOG_TAG "StreamHalAidl"
18//#define LOG_NDEBUG 0
19
20#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
21#include <mediautils/TimeCheck.h>
22#include <utils/Log.h>
23
24#include "DeviceHalAidl.h"
25#include "StreamHalAidl.h"
26
27using ::aidl::android::hardware::audio::core::IStreamCommon;
28using ::aidl::android::hardware::audio::core::IStreamIn;
29using ::aidl::android::hardware::audio::core::IStreamOut;
30using ::aidl::android::hardware::audio::core::StreamDescriptor;
31
32namespace android {
33
Mikhail Naganovfab697c2023-01-11 19:33:13 +000034// static
35template<class T>
36std::shared_ptr<IStreamCommon> StreamHalAidl::getStreamCommon(const std::shared_ptr<T>& stream) {
37 std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> streamCommon;
38 if (stream != nullptr) {
39 if (ndk::ScopedAStatus status = stream->getStreamCommon(&streamCommon);
40 !status.isOk()) {
41 ALOGE("%s: failed to retrieve IStreamCommon instance: %s", __func__,
42 status.getDescription().c_str());
43 }
44 }
45 return streamCommon;
46}
47
Mikhail Naganov31d46652023-01-10 18:29:25 +000048StreamHalAidl::StreamHalAidl(
Mikhail Naganov5b1eed12023-01-25 11:29:11 -080049 std::string_view className, bool isInput, const audio_config& config,
50 const StreamDescriptor& descriptor, const std::shared_ptr<IStreamCommon>& stream)
Mikhail Naganov31d46652023-01-10 18:29:25 +000051 : ConversionHelperAidl(className),
52 mIsInput(isInput),
Mikhail Naganov5b1eed12023-01-25 11:29:11 -080053 mConfig(configToBase(config)),
Mikhail Naganov31d46652023-01-10 18:29:25 +000054 mFrameSizeBytes(descriptor.frameSizeBytes),
55 mBufferSizeFrames(descriptor.bufferSizeFrames),
56 mCommandMQ(new CommandMQ(descriptor.command)),
57 mReplyMQ(new ReplyMQ(descriptor.reply)),
58 mDataMQ(maybeCreateDataMQ(descriptor)),
59 mStream(stream) {
60 // Instrument audio signal power logging.
61 // Note: This assumes channel mask, format, and sample rate do not change after creation.
62 if (audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
63 /* mStreamPowerLog.isUserDebugOrEngBuild() && */
64 StreamHalAidl::getAudioProperties(&config) == NO_ERROR) {
65 mStreamPowerLog.init(config.sample_rate, config.channel_mask, config.format);
66 }
67}
68
69StreamHalAidl::~StreamHalAidl() {
70 if (mStream != nullptr) {
71 ndk::ScopedAStatus status = mStream->close();
72 ALOGE_IF(!status.isOk(), "%s: status %s", __func__, status.getDescription().c_str());
73 }
74}
75
76status_t StreamHalAidl::getBufferSize(size_t *size) {
77 if (size == nullptr) {
78 return BAD_VALUE;
79 }
Mikhail Naganov5b1eed12023-01-25 11:29:11 -080080 if (mFrameSizeBytes == 0 || mBufferSizeFrames == 0 || !mStream) {
Mikhail Naganov31d46652023-01-10 18:29:25 +000081 return NO_INIT;
82 }
83 *size = mFrameSizeBytes * mBufferSizeFrames;
84 return OK;
85}
86
87status_t StreamHalAidl::getAudioProperties(audio_config_base_t *configBase) {
88 if (configBase == nullptr) {
89 return BAD_VALUE;
90 }
Mikhail Naganov5b1eed12023-01-25 11:29:11 -080091 if (!mStream) return NO_INIT;
92 *configBase = mConfig;
Mikhail Naganov31d46652023-01-10 18:29:25 +000093 return OK;
94}
95
96status_t StreamHalAidl::setParameters(const String8& kvPairs __unused) {
97 TIME_CHECK();
98 if (!mStream) return NO_INIT;
99 ALOGE("%s not implemented yet", __func__);
100 return OK;
101}
102
103status_t StreamHalAidl::getParameters(const String8& keys __unused, String8 *values) {
104 TIME_CHECK();
105 values->clear();
106 if (!mStream) return NO_INIT;
107 ALOGE("%s not implemented yet", __func__);
108 return OK;
109}
110
111status_t StreamHalAidl::getFrameSize(size_t *size) {
112 if (size == nullptr) {
113 return BAD_VALUE;
114 }
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800115 if (mFrameSizeBytes == 0 || !mStream) {
Mikhail Naganov31d46652023-01-10 18:29:25 +0000116 return NO_INIT;
117 }
118 *size = mFrameSizeBytes;
119 return OK;
120}
121
122status_t StreamHalAidl::addEffect(sp<EffectHalInterface> effect __unused) {
123 TIME_CHECK();
124 if (!mStream) return NO_INIT;
125 ALOGE("%s not implemented yet", __func__);
126 return OK;
127}
128
129status_t StreamHalAidl::removeEffect(sp<EffectHalInterface> effect __unused) {
130 TIME_CHECK();
131 if (!mStream) return NO_INIT;
132 ALOGE("%s not implemented yet", __func__);
133 return OK;
134}
135
136status_t StreamHalAidl::standby() {
137 TIME_CHECK();
138 if (!mStream) return NO_INIT;
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800139 if (mState == StreamDescriptor::State::STANDBY) {
140 return OK;
141 }
Mikhail Naganov31d46652023-01-10 18:29:25 +0000142 ALOGE("%s not implemented yet", __func__);
143 return OK;
144}
145
Mikhail Naganovfab697c2023-01-11 19:33:13 +0000146status_t StreamHalAidl::dump(int fd, const Vector<String16>& args) {
Mikhail Naganov31d46652023-01-10 18:29:25 +0000147 TIME_CHECK();
148 if (!mStream) return NO_INIT;
Mikhail Naganovfab697c2023-01-11 19:33:13 +0000149 return mStream->dump(fd, Args(args).args(), args.size());
Mikhail Naganov31d46652023-01-10 18:29:25 +0000150}
151
152status_t StreamHalAidl::start() {
153 TIME_CHECK();
154 if (!mStream) return NO_INIT;
155 ALOGE("%s not implemented yet", __func__);
156 return OK;
157}
158
159status_t StreamHalAidl::stop() {
160 TIME_CHECK();
161 if (!mStream) return NO_INIT;
162 ALOGE("%s not implemented yet", __func__);
163 return OK;
164}
165
166status_t StreamHalAidl::createMmapBuffer(int32_t minSizeFrames __unused,
167 struct audio_mmap_buffer_info *info __unused) {
168 TIME_CHECK();
169 if (!mStream) return NO_INIT;
170 ALOGE("%s not implemented yet", __func__);
171 return OK;
172}
173
174status_t StreamHalAidl::getMmapPosition(struct audio_mmap_position *position __unused) {
175 TIME_CHECK();
176 if (!mStream) return NO_INIT;
177 ALOGE("%s not implemented yet", __func__);
178 return OK;
179}
180
181status_t StreamHalAidl::setHalThreadPriority(int priority __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800182 // Obsolete, must be done by the HAL module.
Mikhail Naganov31d46652023-01-10 18:29:25 +0000183 return OK;
184}
185
186status_t StreamHalAidl::getHalPid(pid_t *pid __unused) {
187 TIME_CHECK();
188 if (!mStream) return NO_INIT;
189 ALOGE("%s not implemented yet", __func__);
190 return OK;
191}
192
193bool StreamHalAidl::requestHalThreadPriority(pid_t threadPid __unused, pid_t threadId __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800194 // Obsolete, must be done by the HAL module.
195 return true;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000196}
197
198status_t StreamHalAidl::legacyCreateAudioPatch(const struct audio_port_config& port __unused,
199 std::optional<audio_source_t> source __unused,
200 audio_devices_t type __unused) {
Mikhail Naganovfab697c2023-01-11 19:33:13 +0000201 // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
202 return INVALID_OPERATION;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000203}
204
205status_t StreamHalAidl::legacyReleaseAudioPatch() {
Mikhail Naganovfab697c2023-01-11 19:33:13 +0000206 // Obsolete since 'DeviceHalAidl.supportsAudioPatches' always returns 'true'.
207 return INVALID_OPERATION;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000208}
209
210namespace {
211
212/* Notes on callback ownership.
213
214This is how Binder ownership model looks like. The server implementation
215is owned by Binder framework (via sp<>). Proxies are owned by clients.
216When the last proxy disappears, Binder framework releases the server impl.
217
218Thus, it is not needed to keep any references to StreamCallback (this is
219the server impl) -- it will live as long as HAL server holds a strong ref to
220IStreamCallback proxy.
221
222The callback only keeps a weak reference to the stream. The stream is owned
223by AudioFlinger.
224
225*/
226
227class StreamCallback : public ::aidl::android::hardware::audio::core::BnStreamCallback {
228 ndk::ScopedAStatus onTransferReady() override {
229 return ndk::ScopedAStatus::ok();
230 }
231 ndk::ScopedAStatus onError() override {
232 return ndk::ScopedAStatus::ok();
233 }
234 ndk::ScopedAStatus onDrainReady() override {
235 return ndk::ScopedAStatus::ok();
236 }
237};
238
239} // namespace
240
241StreamOutHalAidl::StreamOutHalAidl(
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800242 const audio_config& config,
Mikhail Naganov31d46652023-01-10 18:29:25 +0000243 const StreamDescriptor& descriptor, const std::shared_ptr<IStreamOut>& stream)
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800244 : StreamHalAidl("StreamOutHalAidl", false /*isInput*/, config,
245 descriptor, getStreamCommon(stream)),
Mikhail Naganov31d46652023-01-10 18:29:25 +0000246 mStream(stream) {}
247
248status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
249 TIME_CHECK();
250 *latency = 0;
251 if (!mStream) return NO_INIT;
252 ALOGE("%s not implemented yet", __func__);
253 return OK;
254}
255
256status_t StreamOutHalAidl::setVolume(float left __unused, float right __unused) {
257 TIME_CHECK();
258 if (!mStream) return NO_INIT;
259 ALOGE("%s not implemented yet", __func__);
260 return OK;
261}
262
263status_t StreamOutHalAidl::selectPresentation(int presentationId __unused, int programId __unused) {
264 TIME_CHECK();
265 if (!mStream) return NO_INIT;
266 ALOGE("%s not implemented yet", __func__);
267 return OK;
268}
269
270status_t StreamOutHalAidl::write(
271 const void *buffer __unused, size_t bytes __unused, size_t *written __unused) {
272 // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
273 if (!mStream) return NO_INIT;
274 *written = 0;
275 ALOGE("%s not implemented yet", __func__);
276 return OK;
277}
278
279status_t StreamOutHalAidl::getRenderPosition(uint32_t *dspFrames __unused) {
280 // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
281 if (!mStream) return NO_INIT;
282 ALOGE("%s not implemented yet", __func__);
283 return OK;
284}
285
286status_t StreamOutHalAidl::getNextWriteTimestamp(int64_t *timestamp __unused) {
287 TIME_CHECK();
288 if (!mStream) return NO_INIT;
289 ALOGE("%s not implemented yet", __func__);
290 return OK;
291}
292
293status_t StreamOutHalAidl::setCallback(wp<StreamOutHalInterfaceCallback> callback __unused) {
294 TIME_CHECK();
295 if (!mStream) return NO_INIT;
296 ALOGE("%s not implemented yet", __func__);
297 return OK;
298}
299
300status_t StreamOutHalAidl::supportsPauseAndResume(
301 bool *supportsPause __unused, bool *supportsResume __unused) {
302 TIME_CHECK();
303 if (!mStream) return NO_INIT;
304 ALOGE("%s not implemented yet", __func__);
305 return OK;
306}
307
308status_t StreamOutHalAidl::pause() {
309 TIME_CHECK();
310 if (!mStream) return NO_INIT;
311 ALOGE("%s not implemented yet", __func__);
312 return OK;
313}
314
315status_t StreamOutHalAidl::resume() {
316 TIME_CHECK();
317 if (!mStream) return NO_INIT;
318 ALOGE("%s not implemented yet", __func__);
319 return OK;
320}
321
322status_t StreamOutHalAidl::supportsDrain(bool *supportsDrain __unused) {
323 TIME_CHECK();
324 if (!mStream) return NO_INIT;
325 ALOGE("%s not implemented yet", __func__);
326 return OK;
327}
328
329status_t StreamOutHalAidl::drain(bool earlyNotify __unused) {
330 TIME_CHECK();
331 if (!mStream) return NO_INIT;
332 ALOGE("%s not implemented yet", __func__);
333 return OK;
334}
335
336status_t StreamOutHalAidl::flush() {
337 TIME_CHECK();
338 if (!mStream) return NO_INIT;
339 ALOGE("%s not implemented yet", __func__);
340 return OK;
341}
342
343status_t StreamOutHalAidl::getPresentationPosition(
344 uint64_t *frames __unused, struct timespec *timestamp __unused) {
345 // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
346 if (!mStream) return NO_INIT;
347 ALOGE("%s not implemented yet", __func__);
348 return OK;
349}
350
351status_t StreamOutHalAidl::updateSourceMetadata(
352 const StreamOutHalInterface::SourceMetadata& sourceMetadata __unused) {
353 TIME_CHECK();
354 if (!mStream) return NO_INIT;
355 ALOGE("%s not implemented yet", __func__);
356 return OK;
357}
358
359status_t StreamOutHalAidl::getDualMonoMode(audio_dual_mono_mode_t* mode __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800360 TIME_CHECK();
361 if (!mStream) return NO_INIT;
362 ALOGE("%s not implemented yet", __func__);
363 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000364}
365
366status_t StreamOutHalAidl::setDualMonoMode(audio_dual_mono_mode_t mode __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800367 TIME_CHECK();
368 if (!mStream) return NO_INIT;
369 ALOGE("%s not implemented yet", __func__);
370 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000371}
372
373status_t StreamOutHalAidl::getAudioDescriptionMixLevel(float* leveldB __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800374 TIME_CHECK();
375 if (!mStream) return NO_INIT;
376 ALOGE("%s not implemented yet", __func__);
377 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000378}
379
380status_t StreamOutHalAidl::setAudioDescriptionMixLevel(float leveldB __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800381 TIME_CHECK();
382 if (!mStream) return NO_INIT;
383 ALOGE("%s not implemented yet", __func__);
384 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000385}
386
387status_t StreamOutHalAidl::getPlaybackRateParameters(
388 audio_playback_rate_t* playbackRate __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800389 TIME_CHECK();
390 if (!mStream) return NO_INIT;
391 ALOGE("%s not implemented yet", __func__);
392 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000393}
394
395status_t StreamOutHalAidl::setPlaybackRateParameters(
396 const audio_playback_rate_t& playbackRate __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800397 TIME_CHECK();
398 if (!mStream) return NO_INIT;
399 ALOGE("%s not implemented yet", __func__);
400 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000401}
402
403status_t StreamOutHalAidl::setEventCallback(
404 const sp<StreamOutHalInterfaceEventCallback>& callback __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800405 TIME_CHECK();
406 if (!mStream) return NO_INIT;
407 ALOGE("%s not implemented yet", __func__);
408 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000409}
410
411namespace {
412
413struct StreamOutEventCallback {
414 StreamOutEventCallback(const wp<StreamOutHalAidl>& stream) : mStream(stream) {}
415 private:
416 wp<StreamOutHalAidl> mStream;
417};
418
419} // namespace
420
421status_t StreamOutHalAidl::setLatencyMode(audio_latency_mode_t mode __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800422 TIME_CHECK();
423 if (!mStream) return NO_INIT;
424 ALOGE("%s not implemented yet", __func__);
425 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000426};
427
428status_t StreamOutHalAidl::getRecommendedLatencyModes(
429 std::vector<audio_latency_mode_t> *modes __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800430 TIME_CHECK();
431 if (!mStream) return NO_INIT;
432 ALOGE("%s not implemented yet", __func__);
433 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000434};
435
436status_t StreamOutHalAidl::setLatencyModeCallback(
437 const sp<StreamOutHalInterfaceLatencyModeCallback>& callback __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800438 TIME_CHECK();
439 if (!mStream) return NO_INIT;
440 ALOGE("%s not implemented yet", __func__);
441 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000442};
443
444void StreamOutHalAidl::onWriteReady() {
445 sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
446 if (callback == 0) return;
447 ALOGV("asyncCallback onWriteReady");
448 callback->onWriteReady();
449}
450
451void StreamOutHalAidl::onDrainReady() {
452 sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
453 if (callback == 0) return;
454 ALOGV("asyncCallback onDrainReady");
455 callback->onDrainReady();
456}
457
458void StreamOutHalAidl::onError() {
459 sp<StreamOutHalInterfaceCallback> callback = mCallback.load().promote();
460 if (callback == 0) return;
461 ALOGV("asyncCallback onError");
462 callback->onError();
463}
464
465void StreamOutHalAidl::onCodecFormatChanged(const std::basic_string<uint8_t>& metadataBs __unused) {
466 sp<StreamOutHalInterfaceEventCallback> callback = mEventCallback.load().promote();
467 if (callback == nullptr) return;
468 ALOGV("asyncCodecFormatCallback %s", __func__);
469 callback->onCodecFormatChanged(metadataBs);
470}
471
472void StreamOutHalAidl::onRecommendedLatencyModeChanged(
473 const std::vector<audio_latency_mode_t>& modes __unused) {
474 sp<StreamOutHalInterfaceLatencyModeCallback> callback = mLatencyModeCallback.load().promote();
475 if (callback == nullptr) return;
476 callback->onRecommendedLatencyModeChanged(modes);
477}
478
479status_t StreamOutHalAidl::exit() {
480 // FIXME this is using hard-coded strings but in the future, this functionality will be
481 // converted to use audio HAL extensions required to support tunneling
482 if (!mStream) return NO_INIT;
483 ALOGE("%s not implemented yet", __func__);
484 return OK;
485}
486
487StreamInHalAidl::StreamInHalAidl(
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800488 const audio_config& config,
Mikhail Naganov31d46652023-01-10 18:29:25 +0000489 const StreamDescriptor& descriptor, const std::shared_ptr<IStreamIn>& stream)
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800490 : StreamHalAidl("StreamInHalAidl", true /*isInput*/, config,
491 descriptor, getStreamCommon(stream)),
Mikhail Naganov31d46652023-01-10 18:29:25 +0000492 mStream(stream) {}
493
494status_t StreamInHalAidl::setGain(float gain __unused) {
495 TIME_CHECK();
496 if (!mStream) return NO_INIT;
497 ALOGE("%s not implemented yet", __func__);
498 return OK;
499}
500
501status_t StreamInHalAidl::read(
502 void *buffer __unused, size_t bytes __unused, size_t *read __unused) {
503 // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
504 if (!mStream) return NO_INIT;
505 ALOGE("%s not implemented yet", __func__);
506 // FIXME: Don't forget to update mPowerLog
507 return OK;
508}
509
510status_t StreamInHalAidl::getInputFramesLost(uint32_t *framesLost __unused) {
511 TIME_CHECK();
512 if (!mStream) return NO_INIT;
513 ALOGE("%s not implemented yet", __func__);
514 return OK;
515}
516
517status_t StreamInHalAidl::getCapturePosition(int64_t *frames __unused, int64_t *time __unused) {
518 // TIME_CHECK(); // TODO(b/238654698) reenable only when optimized.
519 if (!mStream) return NO_INIT;
520 ALOGE("%s not implemented yet", __func__);
521 return OK;
522}
523
524status_t StreamInHalAidl::getActiveMicrophones(
525 std::vector<media::MicrophoneInfo> *microphones __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800526 TIME_CHECK();
527 if (!mStream) return NO_INIT;
528 ALOGE("%s not implemented yet", __func__);
529 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000530}
531
532status_t StreamInHalAidl::updateSinkMetadata(
533 const StreamInHalInterface::SinkMetadata& sinkMetadata __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800534 TIME_CHECK();
535 if (!mStream) return NO_INIT;
536 ALOGE("%s not implemented yet", __func__);
537 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000538}
539
540status_t StreamInHalAidl::setPreferredMicrophoneDirection(
541 audio_microphone_direction_t direction __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800542 TIME_CHECK();
543 if (!mStream) return NO_INIT;
544 ALOGE("%s not implemented yet", __func__);
545 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000546}
547
548status_t StreamInHalAidl::setPreferredMicrophoneFieldDimension(float zoom __unused) {
Mikhail Naganov5b1eed12023-01-25 11:29:11 -0800549 TIME_CHECK();
550 if (!mStream) return NO_INIT;
551 ALOGE("%s not implemented yet", __func__);
552 return OK;
Mikhail Naganov31d46652023-01-10 18:29:25 +0000553}
554
555} // namespace android