Merge "aaudio loopback: improve latency tester" into oc-dr1-dev
diff --git a/camera/Android.bp b/camera/Android.bp
index 849f560..c76ae50 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -31,9 +31,11 @@
// include libcamera_client, at the path "aidl/package/path/BnFoo.h"
"aidl/android/hardware/ICameraService.aidl",
"aidl/android/hardware/ICameraServiceListener.aidl",
+ "aidl/android/hardware/ICameraServiceProxy.aidl",
"aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl",
"aidl/android/hardware/camera2/ICameraDeviceUser.aidl",
+
// Source for camera interface parcelables, and manually-written interfaces
"Camera.cpp",
"CameraMetadata.cpp",
@@ -42,7 +44,6 @@
"CameraParameters2.cpp",
"ICamera.cpp",
"ICameraClient.cpp",
- "ICameraServiceProxy.cpp",
"ICameraRecordingProxy.cpp",
"ICameraRecordingProxyListener.cpp",
"camera2/CaptureRequest.cpp",
diff --git a/camera/ICameraServiceProxy.cpp b/camera/ICameraServiceProxy.cpp
deleted file mode 100644
index a9d0836..0000000
--- a/camera/ICameraServiceProxy.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "BpCameraServiceProxy"
-
-#include <stdint.h>
-
-#include <binder/Parcel.h>
-
-#include <camera/ICameraServiceProxy.h>
-
-namespace android {
-
-class BpCameraServiceProxy: public BpInterface<ICameraServiceProxy> {
-public:
- explicit BpCameraServiceProxy(const sp<IBinder>& impl)
- : BpInterface<ICameraServiceProxy>(impl) {}
-
- virtual void pingForUserUpdate() {
- Parcel data;
- data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor());
- remote()->transact(BnCameraServiceProxy::PING_FOR_USER_UPDATE, data, nullptr,
- IBinder::FLAG_ONEWAY);
- }
-
- virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) {
- Parcel data;
- data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor());
- data.writeString16(cameraId);
- data.writeInt32(newCameraState);
- remote()->transact(BnCameraServiceProxy::NOTIFY_CAMERA_STATE, data, nullptr,
- IBinder::FLAG_ONEWAY);
- }
-
-};
-
-
-IMPLEMENT_META_INTERFACE(CameraServiceProxy, "android.hardware.ICameraServiceProxy");
-
-status_t BnCameraServiceProxy::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags) {
- switch(code) {
- case PING_FOR_USER_UPDATE: {
- CHECK_INTERFACE(ICameraServiceProxy, data, reply);
- pingForUserUpdate();
- return NO_ERROR;
- } break;
- case NOTIFY_CAMERA_STATE: {
- CHECK_INTERFACE(ICameraServiceProxy, data, reply);
- String16 cameraId = data.readString16();
- CameraState newCameraState =
- static_cast<CameraState>(data.readInt32());
- notifyCameraState(cameraId, newCameraState);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-}; // namespace android
diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
index 0e654d5..5dc23eb 100644
--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
@@ -31,7 +31,23 @@
oneway void pingForUserUpdate();
/**
- * Update the status of a camera device
+ * Values for notifyCameraState newCameraState
*/
- oneway void notifyCameraState(String cameraId, int newCameraState);
+ const int CAMERA_STATE_OPEN = 0;
+ const int CAMERA_STATE_ACTIVE = 1;
+ const int CAMERA_STATE_IDLE = 2;
+ const int CAMERA_STATE_CLOSED = 3;
+
+ /**
+ * Values for notifyCameraState facing
+ */
+ const int CAMERA_FACING_BACK = 0;
+ const int CAMERA_FACING_FRONT = 1;
+ const int CAMERA_FACING_EXTERNAL = 2;
+
+ /**
+ * Update the status of a camera device.
+ */
+ oneway void notifyCameraState(String cameraId, int facing, int newCameraState,
+ String clientName);
}
diff --git a/camera/include/camera/ICameraServiceProxy.h b/camera/include/camera/ICameraServiceProxy.h
deleted file mode 100644
index 2613c01..0000000
--- a/camera/include/camera/ICameraServiceProxy.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HARDWARE_ICAMERASERVICEPROXY_H
-#define ANDROID_HARDWARE_ICAMERASERVICEPROXY_H
-
-#include <utils/RefBase.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-/**
- * Interface from native camera service to managed-side camera service proxy.
- *
- * Keep in sync with frameworks/base/core/java/android/hardware/ICameraServiceProxy.aidl
- *
- */
-class ICameraServiceProxy : public IInterface {
-public:
- enum {
- PING_FOR_USER_UPDATE = IBinder::FIRST_CALL_TRANSACTION,
- NOTIFY_CAMERA_STATE
- };
-
- enum CameraState {
- CAMERA_STATE_OPEN,
- CAMERA_STATE_ACTIVE,
- CAMERA_STATE_IDLE,
- CAMERA_STATE_CLOSED
- };
-
- DECLARE_META_INTERFACE(CameraServiceProxy);
-
- virtual void pingForUserUpdate() = 0;
- virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) = 0;
-};
-
-class BnCameraServiceProxy: public BnInterface<ICameraServiceProxy>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-
-
-}; // namespace android
-
-#endif // ANDROID_HARDWARE_ICAMERASERVICEPROXY_H
diff --git a/include/media/AudioClient.h b/include/media/AudioClient.h
new file mode 120000
index 0000000..a0530e4
--- /dev/null
+++ b/include/media/AudioClient.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/AudioClient.h
\ No newline at end of file
diff --git a/include/media/MmapStreamInterface.h b/include/media/MmapStreamInterface.h
index 7dbc19e..d689e25 100644
--- a/include/media/MmapStreamInterface.h
+++ b/include/media/MmapStreamInterface.h
@@ -18,6 +18,7 @@
#define ANDROID_AUDIO_MMAP_STREAM_INTERFACE_H
#include <system/audio.h>
+#include <media/AudioClient.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -37,12 +38,6 @@
DIRECTION_INPUT, /**< open a capture mmap stream */
} stream_direction_t;
- class Client {
- public:
- uid_t clientUid;
- pid_t clientPid;
- String16 packageName;
- };
/**
* Open a playback or capture stream in MMAP mode at the audio HAL.
*
@@ -53,13 +48,14 @@
* \param[in,out] config audio parameters (sampling rate, format ...) for the stream.
* Requested parameters as input,
* Actual parameters as output
- * \param[in] client a Client struct describing the first client using this stream.
+ * \param[in] client a AudioClient struct describing the first client using this stream.
* \param[in,out] deviceId audio device the stream should preferably be routed to/from
* Requested as input,
* Actual as output
* \param[in] callback the MmapStreamCallback interface used by AudioFlinger to notify
* condition changes affecting the stream operation
* \param[out] interface the MmapStreamInterface interface controlling the created stream
+ * \param[out] same unique handle as the one used for the first client stream started.
* \return OK if the stream was successfully created.
* NO_INIT if AudioFlinger is not properly initialized
* BAD_VALUE if the stream cannot be opened because of invalid arguments
@@ -68,10 +64,11 @@
static status_t openMmapStream(stream_direction_t direction,
const audio_attributes_t *attr,
audio_config_base_t *config,
- const Client& client,
+ const AudioClient& client,
audio_port_handle_t *deviceId,
const sp<MmapStreamCallback>& callback,
- sp<MmapStreamInterface>& interface);
+ sp<MmapStreamInterface>& interface,
+ audio_port_handle_t *handle);
/**
* Retrieve information on the mmap buffer used for audio samples transfer.
@@ -105,13 +102,13 @@
* Start a stream operating in mmap mode.
* createMmapBuffer() must be called before calling start()
*
- * \param[in] client a Client struct describing the client starting on this stream.
+ * \param[in] client a AudioClient struct describing the client starting on this stream.
* \param[out] handle unique handle for this instance. Used with stop().
* \return OK in case of success.
* NO_INIT in case of initialization error
* INVALID_OPERATION if called out of sequence
*/
- virtual status_t start(const Client& client, audio_port_handle_t *handle) = 0;
+ virtual status_t start(const AudioClient& client, audio_port_handle_t *handle) = 0;
/**
* Stop a stream operating in mmap mode.
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h
index 469f0a8..89ae85c 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.h
+++ b/media/libaaudio/src/binding/AAudioBinderClient.h
@@ -97,6 +97,17 @@
aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
pid_t clientThreadId) override;
+ aaudio_result_t startClient(aaudio_handle_t streamHandle __unused,
+ const android::AudioClient& client __unused,
+ audio_port_handle_t *clientHandle) override {
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+
+ aaudio_result_t stopClient(aaudio_handle_t streamHandle __unused,
+ audio_port_handle_t clientHandle __unused) override {
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+
void onStreamChange(aaudio_handle_t handle, int32_t opcode, int32_t value) {
// TODO This is just a stub so we can have a client Binder to pass to the service.
// TODO Implemented in a later CL.
diff --git a/media/libaaudio/src/binding/AAudioServiceInterface.h b/media/libaaudio/src/binding/AAudioServiceInterface.h
index 7368062..a64405b 100644
--- a/media/libaaudio/src/binding/AAudioServiceInterface.h
+++ b/media/libaaudio/src/binding/AAudioServiceInterface.h
@@ -18,6 +18,7 @@
#define ANDROID_AAUDIO_BINDING_AAUDIO_SERVICE_INTERFACE_H
#include <utils/StrongPointer.h>
+#include <media/AudioClient.h>
#include "binding/AAudioServiceDefinitions.h"
#include "binding/AAudioStreamRequest.h"
@@ -86,6 +87,13 @@
virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
pid_t clientThreadId) = 0;
+
+ virtual aaudio_result_t startClient(aaudio_handle_t streamHandle,
+ const android::AudioClient& client,
+ audio_port_handle_t *clientHandle) = 0;
+
+ virtual aaudio_result_t stopClient(aaudio_handle_t streamHandle,
+ audio_port_handle_t clientHandle) = 0;
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.cpp b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
index 8a765ad..abdcf5b 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
@@ -52,8 +52,12 @@
status = parcel->writeBool(mSharingModeMatchRequired);
if (status != NO_ERROR) goto error;
+ status = parcel->writeBool(mInService);
+ if (status != NO_ERROR) goto error;
+
status = mConfiguration.writeToParcel(parcel);
if (status != NO_ERROR) goto error;
+
return NO_ERROR;
error:
@@ -74,8 +78,12 @@
status = parcel->readBool(&mSharingModeMatchRequired);
if (status != NO_ERROR) goto error;
+ status = parcel->readBool(&mInService);
+ if (status != NO_ERROR) goto error;
+
status = mConfiguration.readFromParcel(parcel);
if (status != NO_ERROR) goto error;
+
return NO_ERROR;
error:
@@ -91,5 +99,7 @@
ALOGD("AAudioStreamRequest mUserId = %d", mUserId);
ALOGD("AAudioStreamRequest mProcessId = %d", mProcessId);
ALOGD("AAudioStreamRequest mDirection = %d", mDirection);
+ ALOGD("AAudioStreamRequest mSharingModeMatchRequired = %d", mSharingModeMatchRequired);
+ ALOGD("AAudioStreamRequest mInService = %d", mInService);
mConfiguration.dump();
}
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.h b/media/libaaudio/src/binding/AAudioStreamRequest.h
index 462246b..b0fa96a 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.h
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.h
@@ -76,6 +76,14 @@
return mConfiguration;
}
+ bool isInService() const {
+ return mInService;
+ }
+
+ void setInService(bool inService) {
+ mInService = inService;
+ }
+
virtual status_t writeToParcel(Parcel* parcel) const override;
virtual status_t readFromParcel(const Parcel* parcel) override;
@@ -90,6 +98,7 @@
pid_t mProcessId;
aaudio_direction_t mDirection;
bool mSharingModeMatchRequired = false;
+ bool mInService = false; // Stream opened by AAudioservice
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index ff13fc2..7b01e44 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -16,7 +16,7 @@
// This file is used in both client and server processes.
// This is needed to make sense of the logs more easily.
-#define LOG_TAG (mInService ? "AAudioService" : "AAudio")
+#define LOG_TAG (mInService ? "AudioStreamInternal_Service" : "AudioStreamInternal_Client")
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -93,6 +93,7 @@
request.setProcessId(getpid());
request.setDirection(getDirection());
request.setSharingModeMatchRequired(isSharingModeMatchRequired());
+ request.setInService(mInService);
request.getConfiguration().setDeviceId(getDeviceId());
request.getConfiguration().setSampleRate(getSampleRate());
@@ -326,6 +327,21 @@
return mServiceInterface.unregisterAudioThread(mServiceStreamHandle, gettid());
}
+aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& client,
+ audio_port_handle_t *clientHandle) {
+ if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return mServiceInterface.startClient(mServiceStreamHandle, client, clientHandle);
+}
+
+aaudio_result_t AudioStreamInternal::stopClient(audio_port_handle_t clientHandle) {
+ if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
+ return AAUDIO_ERROR_INVALID_STATE;
+ }
+ return mServiceInterface.stopClient(mServiceStreamHandle, clientHandle);
+}
+
aaudio_result_t AudioStreamInternal::getTimestamp(clockid_t clockId,
int64_t *framePosition,
int64_t *timeNanoseconds) {
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 257a702..109e425 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -87,6 +87,11 @@
//PlayerBase virtuals
virtual void destroy();
+ aaudio_result_t startClient(const android::AudioClient& client,
+ audio_port_handle_t *clientHandle);
+
+ aaudio_result_t stopClient(audio_port_handle_t clientHandle);
+
protected:
aaudio_result_t processData(void *buffer,
@@ -170,7 +175,6 @@
AudioEndpointParcelable mEndPointParcelable; // description of the buffers filled by service
EndpointDescriptor mEndpointDescriptor; // buffer description with resolved addresses
-
};
} /* namespace aaudio */
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index d320320..ceba211 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -323,6 +323,7 @@
return BAD_VALUE;
}
data.write(attr, sizeof(audio_attributes_t));
+ data.writeInt32(*input);
data.writeInt32(session);
data.writeInt32(pid);
data.writeInt32(uid);
@@ -1024,6 +1025,7 @@
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_attributes_t attr;
data.read(&attr, sizeof(audio_attributes_t));
+ audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
audio_session_t session = (audio_session_t)data.readInt32();
pid_t pid = (pid_t)data.readInt32();
uid_t uid = (uid_t)data.readInt32();
@@ -1033,7 +1035,6 @@
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
- audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
status_t status = getInputForAttr(&attr, &input, session, pid, uid,
&config,
flags, &selectedDeviceId, &portId);
diff --git a/media/libaudioclient/include/media/AudioClient.h b/media/libaudioclient/include/media/AudioClient.h
new file mode 100644
index 0000000..9efd76d
--- /dev/null
+++ b/media/libaudioclient/include/media/AudioClient.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_AUDIO_CLIENT_H
+#define ANDROID_AUDIO_CLIENT_H
+
+#include <system/audio.h>
+#include <utils/String16.h>
+
+namespace android {
+
+class AudioClient {
+ public:
+ AudioClient() :
+ clientUid(-1), clientPid(-1), packageName("") {}
+
+ uid_t clientUid;
+ pid_t clientPid;
+ String16 packageName;
+};
+
+}; // namespace android
+
+#endif // ANDROID_AUDIO_CLIENT_H
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d850aa9..38c9687 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -260,10 +260,11 @@
status_t MmapStreamInterface::openMmapStream(MmapStreamInterface::stream_direction_t direction,
const audio_attributes_t *attr,
audio_config_base_t *config,
- const MmapStreamInterface::Client& client,
+ const AudioClient& client,
audio_port_handle_t *deviceId,
const sp<MmapStreamCallback>& callback,
- sp<MmapStreamInterface>& interface)
+ sp<MmapStreamInterface>& interface,
+ audio_port_handle_t *handle)
{
sp<AudioFlinger> af;
{
@@ -273,7 +274,7 @@
status_t ret = NO_INIT;
if (af != 0) {
ret = af->openMmapStream(
- direction, attr, config, client, deviceId, callback, interface);
+ direction, attr, config, client, deviceId, callback, interface, handle);
}
return ret;
}
@@ -281,10 +282,11 @@
status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t direction,
const audio_attributes_t *attr,
audio_config_base_t *config,
- const MmapStreamInterface::Client& client,
+ const AudioClient& client,
audio_port_handle_t *deviceId,
const sp<MmapStreamCallback>& callback,
- sp<MmapStreamInterface>& interface)
+ sp<MmapStreamInterface>& interface,
+ audio_port_handle_t *handle)
{
status_t ret = initCheck();
if (ret != NO_ERROR) {
@@ -293,7 +295,7 @@
audio_session_t sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
audio_stream_type_t streamType = AUDIO_STREAM_DEFAULT;
- audio_io_handle_t io;
+ audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
audio_config_t fullConfig = AUDIO_CONFIG_INITIALIZER;
@@ -325,6 +327,7 @@
if (thread != 0) {
interface = new MmapThreadHandle(thread);
thread->configure(attr, streamType, sessionId, callback, portId);
+ *handle = portId;
} else {
ret = NO_INIT;
}
@@ -1279,7 +1282,7 @@
if (thread == NULL) {
thread = (ThreadBase *)checkMmapThread_l(ioHandle);
if (thread == NULL) {
- String8("");
+ return String8("");
}
}
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2e0bc66..8a96c1d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -294,10 +294,11 @@
status_t openMmapStream(MmapStreamInterface::stream_direction_t direction,
const audio_attributes_t *attr,
audio_config_base_t *config,
- const MmapStreamInterface::Client& client,
+ const AudioClient& client,
audio_port_handle_t *deviceId,
const sp<MmapStreamCallback>& callback,
- sp<MmapStreamInterface>& interface);
+ sp<MmapStreamInterface>& interface,
+ audio_port_handle_t *handle);
private:
// FIXME The 400 is temporarily too high until a leak of writers in media.log is fixed.
static const size_t kLogMemorySize = 400 * 1024;
@@ -596,7 +597,7 @@
virtual status_t createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info);
virtual status_t getMmapPosition(struct audio_mmap_position *position);
- virtual status_t start(const MmapStreamInterface::Client& client,
+ virtual status_t start(const AudioClient& client,
audio_port_handle_t *handle);
virtual status_t stop(audio_port_handle_t handle);
virtual status_t standby();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 085be00..d932483 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7523,7 +7523,7 @@
return mThread->getMmapPosition(position);
}
-status_t AudioFlinger::MmapThreadHandle::start(const MmapStreamInterface::Client& client,
+status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client,
audio_port_handle_t *handle)
{
@@ -7616,77 +7616,75 @@
return mHalStream->getMmapPosition(position);
}
-status_t AudioFlinger::MmapThread::start(const MmapStreamInterface::Client& client,
+status_t AudioFlinger::MmapThread::start(const AudioClient& client,
audio_port_handle_t *handle)
{
- ALOGV("%s clientUid %d mStandby %d", __FUNCTION__, client.clientUid, mStandby);
+ ALOGV("%s clientUid %d mStandby %d mPortId %d *handle %d", __FUNCTION__,
+ client.clientUid, mStandby, mPortId, *handle);
if (mHalStream == 0) {
return NO_INIT;
}
status_t ret;
- audio_session_t sessionId;
- audio_port_handle_t portId;
- if (mActiveTracks.size() == 0) {
+ if (*handle == mPortId) {
// for the first track, reuse portId and session allocated when the stream was opened
ret = mHalStream->start();
if (ret != NO_ERROR) {
ALOGE("%s: error mHalStream->start() = %d for first track", __FUNCTION__, ret);
return ret;
}
- portId = mPortId;
- sessionId = mSessionId;
mStandby = false;
+ return NO_ERROR;
+ }
+
+ audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
+
+ audio_io_handle_t io = mId;
+ if (isOutput()) {
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = mSampleRate;
+ config.channel_mask = mChannelMask;
+ config.format = mFormat;
+ audio_stream_type_t stream = streamType();
+ audio_output_flags_t flags =
+ (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
+ audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
+ ret = AudioSystem::getOutputForAttr(&mAttr, &io,
+ mSessionId,
+ &stream,
+ client.clientUid,
+ &config,
+ flags,
+ &deviceId,
+ &portId);
} else {
- // for other tracks than first one, get a new port ID from APM.
- sessionId = (audio_session_t)mAudioFlinger->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
- audio_io_handle_t io;
- if (isOutput()) {
- audio_config_t config = AUDIO_CONFIG_INITIALIZER;
- config.sample_rate = mSampleRate;
- config.channel_mask = mChannelMask;
- config.format = mFormat;
- audio_stream_type_t stream = streamType();
- audio_output_flags_t flags =
- (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT);
- audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
- ret = AudioSystem::getOutputForAttr(&mAttr, &io,
- sessionId,
- &stream,
- client.clientUid,
- &config,
- flags,
- &deviceId,
- &portId);
- } else {
- audio_config_base_t config;
- config.sample_rate = mSampleRate;
- config.channel_mask = mChannelMask;
- config.format = mFormat;
- audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
- ret = AudioSystem::getInputForAttr(&mAttr, &io,
- sessionId,
- client.clientPid,
- client.clientUid,
- &config,
- AUDIO_INPUT_FLAG_MMAP_NOIRQ,
- &deviceId,
- &portId);
- }
- // APM should not chose a different input or output stream for the same set of attributes
- // and audo configuration
- if (ret != NO_ERROR || io != mId) {
- ALOGE("%s: error getting output or input from APM (error %d, io %d expected io %d)",
- __FUNCTION__, ret, io, mId);
- return BAD_VALUE;
- }
+ audio_config_base_t config;
+ config.sample_rate = mSampleRate;
+ config.channel_mask = mChannelMask;
+ config.format = mFormat;
+ audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
+ ret = AudioSystem::getInputForAttr(&mAttr, &io,
+ mSessionId,
+ client.clientPid,
+ client.clientUid,
+ &config,
+ AUDIO_INPUT_FLAG_MMAP_NOIRQ,
+ &deviceId,
+ &portId);
+ }
+ // APM should not chose a different input or output stream for the same set of attributes
+ // and audo configuration
+ if (ret != NO_ERROR || io != mId) {
+ ALOGE("%s: error getting output or input from APM (error %d, io %d expected io %d)",
+ __FUNCTION__, ret, io, mId);
+ return BAD_VALUE;
}
if (isOutput()) {
- ret = AudioSystem::startOutput(mId, streamType(), sessionId);
+ ret = AudioSystem::startOutput(mId, streamType(), mSessionId);
} else {
- ret = AudioSystem::startInput(mId, sessionId);
+ ret = AudioSystem::startInput(mId, mSessionId);
}
// abort if start is rejected by audio policy manager
@@ -7694,9 +7692,9 @@
ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret);
if (mActiveTracks.size() != 0) {
if (isOutput()) {
- AudioSystem::releaseOutput(mId, streamType(), sessionId);
+ AudioSystem::releaseOutput(mId, streamType(), mSessionId);
} else {
- AudioSystem::releaseInput(mId, sessionId);
+ AudioSystem::releaseInput(mId, mSessionId);
}
} else {
mHalStream->stop();
@@ -7704,11 +7702,11 @@
return PERMISSION_DENIED;
}
- sp<MmapTrack> track = new MmapTrack(this, mSampleRate, mFormat, mChannelMask, sessionId,
+ sp<MmapTrack> track = new MmapTrack(this, mSampleRate, mFormat, mChannelMask, mSessionId,
client.clientUid, portId);
mActiveTracks.add(track);
- sp<EffectChain> chain = getEffectChain_l(sessionId);
+ sp<EffectChain> chain = getEffectChain_l(mSessionId);
if (chain != 0) {
chain->setStrategy(AudioSystem::getStrategyForStream(streamType()));
chain->incTrackCnt();
@@ -7716,10 +7714,9 @@
}
*handle = portId;
-
broadcast_l();
- ALOGV("%s DONE handle %d stream %p", __FUNCTION__, portId, mHalStream.get());
+ ALOGV("%s DONE handle %d stream %p", __FUNCTION__, *handle, mHalStream.get());
return NO_ERROR;
}
@@ -7732,6 +7729,11 @@
return NO_INIT;
}
+ if (handle == mPortId) {
+ mHalStream->stop();
+ return NO_ERROR;
+ }
+
sp<MmapTrack> track;
for (const sp<MmapTrack> &t : mActiveTracks) {
if (handle == t->portId()) {
@@ -7747,14 +7749,10 @@
if (isOutput()) {
AudioSystem::stopOutput(mId, streamType(), track->sessionId());
- if (mActiveTracks.size() != 0) {
- AudioSystem::releaseOutput(mId, streamType(), track->sessionId());
- }
+ AudioSystem::releaseOutput(mId, streamType(), track->sessionId());
} else {
AudioSystem::stopInput(mId, track->sessionId());
- if (mActiveTracks.size() != 0) {
- AudioSystem::releaseInput(mId, track->sessionId());
- }
+ AudioSystem::releaseInput(mId, track->sessionId());
}
sp<EffectChain> chain = getEffectChain_l(track->sessionId());
@@ -7765,9 +7763,6 @@
broadcast_l();
- if (mActiveTracks.size() == 0) {
- mHalStream->stop();
- }
return NO_ERROR;
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 9db19d6..65266b0 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1478,7 +1478,7 @@
status_t createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info);
status_t getMmapPosition(struct audio_mmap_position *position);
- status_t start(const MmapStreamInterface::Client& client, audio_port_handle_t *handle);
+ status_t start(const AudioClient& client, audio_port_handle_t *handle);
status_t stop(audio_port_handle_t handle);
status_t standby();
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index 18fba25..ca070cf 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -51,6 +51,7 @@
audio_channel_mask_t channelMask() const { return mConfig.channel_mask; }
audio_input_flags_t flags() const { return mFlags; }
uid_t uid() const { return mUid; }
+ void setUid(uid_t uid) { mUid = uid; }
bool matches(const sp<AudioSession> &other) const;
bool isSoundTrigger() const { return mIsSoundTrigger; }
uint32_t openCount() const { return mOpenCount; } ;
@@ -68,7 +69,7 @@
const audio_source_t mInputSource;
const struct audio_config_base mConfig;
const audio_input_flags_t mFlags;
- const uid_t mUid;
+ uid_t mUid;
bool mIsSoundTrigger;
uint32_t mOpenCount;
uint32_t mActiveCount;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 3dcb22d..55c364f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1495,6 +1495,43 @@
"session %d, flags %#x",
attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
+ // special case for mmap capture: if an input IO handle is specified, we reuse this input if
+ // possible
+ if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) == AUDIO_INPUT_FLAG_MMAP_NOIRQ &&
+ *input != AUDIO_IO_HANDLE_NONE) {
+ ssize_t index = mInputs.indexOfKey(*input);
+ if (index < 0) {
+ ALOGW("getInputForAttr() unknown MMAP input %d", *input);
+ return BAD_VALUE;
+ }
+ sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
+ sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
+ if (audioSession == 0) {
+ ALOGW("getInputForAttr() unknown session %d on input %d", session, *input);
+ return BAD_VALUE;
+ }
+ // For MMAP mode, the first call to getInputForAttr() is made on behalf of audioflinger.
+ // The second call is for the first active client and sets the UID. Any further call
+ // corresponds to a new client and is only permitted from the same UId.
+ if (audioSession->openCount() == 1) {
+ audioSession->setUid(uid);
+ } else if (audioSession->uid() != uid) {
+ ALOGW("getInputForAttr() bad uid %d for session %d uid %d",
+ uid, session, audioSession->uid());
+ return INVALID_OPERATION;
+ }
+ audioSession->changeOpenCount(1);
+ *inputType = API_INPUT_LEGACY;
+ if (*portId == AUDIO_PORT_HANDLE_NONE) {
+ *portId = AudioPort::getNextUniqueId();
+ }
+ DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(inputDesc->mDevice);
+ *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
+ : AUDIO_PORT_HANDLE_NONE;
+ ALOGI("%s reusing MMAP input %d for session %d", __FUNCTION__, *input, session);
+ return NO_ERROR;
+ }
+
*input = AUDIO_IO_HANDLE_NONE;
*inputType = API_INPUT_INVALID;
@@ -1898,6 +1935,11 @@
continue;
}
+ if ((audioSession->flags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0 &&
+ activeDesc->getId() == inputDesc->getId()) {
+ continue;
+ }
+
audio_source_t activeSource = activeDesc->inputSource(true);
if (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) {
if (activeSource == AUDIO_SOURCE_HOTWORD) {
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c175259..20bd5e4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -73,6 +73,7 @@
using binder::Status;
using hardware::ICamera;
using hardware::ICameraClient;
+using hardware::ICameraServiceProxy;
using hardware::ICameraServiceListener;
using hardware::camera::common::V1_0::CameraDeviceStatus;
using hardware::camera::common::V1_0::TorchModeStatus;
@@ -2213,7 +2214,7 @@
// Transition device state to OPEN
sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
- mCameraIdStr);
+ mCameraIdStr, mCameraFacing, mClientPackageName);
return OK;
}
@@ -2237,7 +2238,7 @@
// Transition device state to CLOSED
sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
- mCameraIdStr);
+ mCameraIdStr, mCameraFacing, mClientPackageName);
}
// Always stop watching, even if no camera op is active
if (mOpsCallback != NULL) {
@@ -2741,12 +2742,12 @@
onStatusUpdatedLocked(cameraId, status);
}
-void CameraService::updateProxyDeviceState(ICameraServiceProxy::CameraState newState,
- const String8& cameraId) {
+void CameraService::updateProxyDeviceState(int newState,
+ const String8& cameraId, int facing, const String16& clientName) {
sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
if (proxyBinder == nullptr) return;
String16 id(cameraId);
- proxyBinder->notifyCameraState(id, newState);
+ proxyBinder->notifyCameraState(id, newState, facing, clientName);
}
status_t CameraService::getTorchStatusLocked(
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 87603a3..6d5dde8 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -19,6 +19,7 @@
#include <android/hardware/BnCameraService.h>
#include <android/hardware/ICameraServiceListener.h>
+#include <android/hardware/ICameraServiceProxy.h>
#include <cutils/multiuser.h>
#include <utils/Vector.h>
@@ -26,7 +27,6 @@
#include <binder/AppOpsManager.h>
#include <binder/BinderService.h>
#include <binder/IAppOpsCallback.h>
-#include <camera/ICameraServiceProxy.h>
#include <hardware/camera.h>
#include <android/hardware/camera/common/1.0/types.h>
@@ -182,8 +182,10 @@
* the camera proxy service in the system service
*/
static void updateProxyDeviceState(
- ICameraServiceProxy::CameraState newState,
- const String8& cameraId);
+ int newState,
+ const String8& cameraId,
+ int facing,
+ const String16& clientName);
/////////////////////////////////////////////////////////////////////
// CameraDeviceFactory functionality
@@ -772,7 +774,7 @@
static StatusInternal mapToInternal(hardware::camera::common::V1_0::CameraDeviceStatus status);
static int32_t mapToInterface(StatusInternal status);
- static sp<ICameraServiceProxy> getCameraServiceProxy();
+ static sp<hardware::ICameraServiceProxy> getCameraServiceProxy();
static void pingCameraServiceProxy();
};
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 075c2e3..a407d0b 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -256,8 +256,8 @@
disableMsgType(CAMERA_MSG_ALL_MSGS);
mHardware->stopPreview();
sCameraService->updateProxyDeviceState(
- ICameraServiceProxy::CAMERA_STATE_IDLE,
- String8::format("%d", mCameraId));
+ hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
+ mCameraIdStr, mCameraFacing, mClientPackageName);
mHardware->cancelPicture();
// Release the hardware resources.
mHardware->release();
@@ -418,8 +418,8 @@
result = mHardware->startPreview();
if (result == NO_ERROR) {
sCameraService->updateProxyDeviceState(
- ICameraServiceProxy::CAMERA_STATE_ACTIVE,
- String8::format("%d", mCameraId));
+ hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
+ mCameraIdStr, mCameraFacing, mClientPackageName);
}
return result;
}
@@ -461,8 +461,8 @@
disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
mHardware->stopPreview();
sCameraService->updateProxyDeviceState(
- ICameraServiceProxy::CAMERA_STATE_IDLE,
- String8::format("%d", mCameraId));
+ hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
+ mCameraIdStr, mCameraFacing, mClientPackageName);
mPreviewBuffer.clear();
}
@@ -960,8 +960,8 @@
// Shutters only happen in response to takePicture, so mark device as
// idle now, until preview is restarted
sCameraService->updateProxyDeviceState(
- ICameraServiceProxy::CAMERA_STATE_IDLE,
- String8::format("%d", mCameraId));
+ hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
+ mCameraIdStr, mCameraFacing, mClientPackageName);
mLock.unlock();
}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 32ee273..51ef160 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -248,7 +248,8 @@
void Camera2ClientBase<TClientBase>::notifyIdle() {
if (mDeviceActive) {
getCameraService()->updateProxyDeviceState(
- ICameraServiceProxy::CAMERA_STATE_IDLE, TClientBase::mCameraIdStr);
+ hardware::ICameraServiceProxy::CAMERA_STATE_IDLE, TClientBase::mCameraIdStr,
+ TClientBase::mCameraFacing, TClientBase::mClientPackageName);
}
mDeviceActive = false;
@@ -263,7 +264,8 @@
if (!mDeviceActive) {
getCameraService()->updateProxyDeviceState(
- ICameraServiceProxy::CAMERA_STATE_ACTIVE, TClientBase::mCameraIdStr);
+ hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE, TClientBase::mCameraIdStr,
+ TClientBase::mCameraFacing, TClientBase::mClientPackageName);
}
mDeviceActive = true;
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index 02d4a19..ec2f5b9 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AAudioService"
+#define LOG_TAG "AAudioEndpointManager"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -104,6 +104,8 @@
// If we can't find an existing one then open a new one.
if (endpoint == nullptr) {
+ // we must call openStream with audioserver identity
+ int64_t token = IPCThreadState::self()->clearCallingIdentity();
switch(direction) {
case AAUDIO_DIRECTION_INPUT:
capture = new AAudioServiceEndpointCapture(audioService);
@@ -138,6 +140,7 @@
}
ALOGD("AAudioEndpointManager::openEndpoint(), created %p for device = %d, dir = %d",
endpoint, configuration.getDeviceId(), (int)direction);
+ IPCThreadState::self()->restoreCallingIdentity(token);
}
if (endpoint != nullptr) {
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 669bb54..3992719 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -50,8 +50,9 @@
android::AAudioService::AAudioService()
: BnAAudioService() {
- mCachedProcessId = getpid();
- mCachedUserId = getuid(); // TODO consider using geteuid()
+ mAudioClient.clientUid = getuid(); // TODO consider using geteuid()
+ mAudioClient.clientPid = getpid();
+ mAudioClient.packageName = String16("");
AAudioClientTracker::getInstance().setAAudioService(this);
}
@@ -92,7 +93,7 @@
// Enforce limit on client processes.
pid_t pid = request.getProcessId();
- if (pid != mCachedProcessId) {
+ if (pid != mAudioClient.clientPid) {
int32_t count = AAudioClientTracker::getInstance().getStreamCount(pid);
if (count >= MAX_STREAMS_PER_PROCESS) {
ALOGE("AAudioService::openStream(): exceeded max streams per process %d >= %d",
@@ -107,7 +108,13 @@
}
if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) {
- serviceStream = new AAudioServiceStreamMMAP(mCachedUserId);
+ // only trust audioserver for in service indication
+ bool inService = false;
+ if (mAudioClient.clientPid == IPCThreadState::self()->getCallingPid() &&
+ mAudioClient.clientUid == IPCThreadState::self()->getCallingUid()) {
+ inService = request.isInService();
+ }
+ serviceStream = new AAudioServiceStreamMMAP(mAudioClient, inService);
result = serviceStream->open(request, configurationOutput);
if (result != AAUDIO_OK) {
// fall back to using a shared stream
@@ -132,8 +139,6 @@
result, AAudio_convertResultToText(result));
return result;
} else {
- const uid_t ownerUserId = request.getUserId(); // only set by service, not by client
- serviceStream->setOwnerUserId(ownerUserId);
aaudio_handle_t handle = mHandleTracker.put(AAUDIO_HANDLE_TYPE_STREAM, serviceStream.get());
if (handle < 0) {
ALOGE("AAudioService::openStream(): handle table full");
@@ -143,7 +148,6 @@
ALOGD("AAudioService::openStream(): handle = 0x%08X", handle);
serviceStream->setHandle(handle);
pid_t pid = request.getProcessId();
- serviceStream->setOwnerProcessId(pid);
AAudioClientTracker::getInstance().registerClientStream(pid, serviceStream);
}
return handle;
@@ -181,8 +185,8 @@
const uid_t callingUserId = IPCThreadState::self()->getCallingUid();
const uid_t ownerUserId = serviceStream->getOwnerUserId();
bool callerOwnsIt = callingUserId == ownerUserId;
- bool serverCalling = callingUserId == mCachedUserId;
- bool serverOwnsIt = ownerUserId == mCachedUserId;
+ bool serverCalling = callingUserId == mAudioClient.clientUid;
+ bool serverOwnsIt = ownerUserId == mAudioClient.clientUid;
bool allowed = callerOwnsIt || serverCalling || serverOwnsIt;
if (!allowed) {
ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d",
@@ -212,6 +216,7 @@
ALOGE("AAudioService::startStream(), illegal stream handle = 0x%0x", streamHandle);
return AAUDIO_ERROR_INVALID_HANDLE;
}
+
aaudio_result_t result = serviceStream->start();
return result;
}
@@ -286,3 +291,26 @@
serviceStream->setRegisteredThread(0);
return AAUDIO_OK;
}
+
+aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle,
+ const android::AudioClient& client,
+ audio_port_handle_t *clientHandle) {
+ AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
+ if (serviceStream == nullptr) {
+ ALOGE("AAudioService::startClient(), illegal stream handle = 0x%0x",
+ streamHandle);
+ return AAUDIO_ERROR_INVALID_HANDLE;
+ }
+ return serviceStream->startClient(client, clientHandle);
+}
+
+aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle,
+ audio_port_handle_t clientHandle) {
+ AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
+ if (serviceStream == nullptr) {
+ ALOGE("AAudioService::stopClient(), illegal stream handle = 0x%0x",
+ streamHandle);
+ return AAUDIO_ERROR_INVALID_HANDLE;
+ }
+ return serviceStream->stopClient(clientHandle);
+}
diff --git a/services/oboeservice/AAudioService.h b/services/oboeservice/AAudioService.h
index f84ac4c..8421efc 100644
--- a/services/oboeservice/AAudioService.h
+++ b/services/oboeservice/AAudioService.h
@@ -21,6 +21,7 @@
#include <pthread.h>
#include <binder/BinderService.h>
+#include <media/AudioClient.h>
#include <aaudio/AAudio.h>
#include "utility/HandleTracker.h"
@@ -72,14 +73,20 @@
virtual aaudio_result_t unregisterAudioThread(aaudio_handle_t streamHandle,
pid_t tid);
+ virtual aaudio_result_t startClient(aaudio_handle_t streamHandle,
+ const android::AudioClient& client,
+ audio_port_handle_t *clientHandle);
+
+ virtual aaudio_result_t stopClient(aaudio_handle_t streamHandle,
+ audio_port_handle_t clientHandle);
+
private:
aaudio::AAudioServiceStreamBase *convertHandleToServiceStream(aaudio_handle_t streamHandle) const;
HandleTracker mHandleTracker;
- uid_t mCachedUserId = -1;
- pid_t mCachedProcessId = -1;
+ android::AudioClient mAudioClient;
enum constants {
DEFAULT_AUDIO_PRIORITY = 2
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index b519829..5895974 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AAudioService"
+#define LOG_TAG "AAudioServiceEndpoint"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -94,7 +94,7 @@
}
aaudio_result_t AAudioServiceEndpoint::close() {
- return getStreamInternal()->close();
+ return getStreamInternal()->close();
}
// TODO, maybe use an interface to reduce exposure
@@ -113,26 +113,25 @@
aaudio_result_t AAudioServiceEndpoint::startStream(sp<AAudioServiceStreamShared> sharedStream) {
// TODO use real-time technique to avoid mutex, eg. atomic command FIFO
+ aaudio_result_t result = AAUDIO_OK;
std::lock_guard<std::mutex> lock(mLockStreams);
- mRunningStreams.push_back(sharedStream);
- if (mRunningStreams.size() == 1) {
+ if (++mRunningStreams == 1) {
+ result = getStreamInternal()->requestStart();
startSharingThread_l();
}
- return AAUDIO_OK;
+ return result;
}
aaudio_result_t AAudioServiceEndpoint::stopStream(sp<AAudioServiceStreamShared> sharedStream) {
int numRunningStreams = 0;
{
std::lock_guard<std::mutex> lock(mLockStreams);
- mRunningStreams.erase(
- std::remove(mRunningStreams.begin(), mRunningStreams.end(), sharedStream),
- mRunningStreams.end());
- numRunningStreams = mRunningStreams.size();
+ numRunningStreams = --mRunningStreams;
}
if (numRunningStreams == 0) {
// Don't call this under a lock because the callbackLoop also uses the lock.
stopSharingThread();
+ getStreamInternal()->requestStop();
}
return AAUDIO_OK;
}
@@ -163,11 +162,8 @@
void AAudioServiceEndpoint::disconnectRegisteredStreams() {
std::lock_guard<std::mutex> lock(mLockStreams);
- for(auto baseStream : mRunningStreams) {
- baseStream->onStop();
- }
- mRunningStreams.clear();
for(auto sharedStream : mRegisteredStreams) {
+ sharedStream->stop();
sharedStream->disconnect();
}
mRegisteredStreams.clear();
@@ -189,3 +185,4 @@
return true;
}
+
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index a78d3fa..ed995e5 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -79,7 +79,7 @@
std::vector<android::sp<AAudioServiceStreamShared>> mRegisteredStreams;
- std::vector<android::sp<AAudioServiceStreamShared>> mRunningStreams;
+ size_t mRunningStreams = 0;
private:
aaudio_result_t startSharingThread_l();
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index a144c54..6a37330 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -57,9 +57,7 @@
void *AAudioServiceEndpointCapture::callbackLoop() {
ALOGD("AAudioServiceEndpointCapture(): callbackLoop() entering");
int32_t underflowCount = 0;
-
- aaudio_result_t result = getStreamInternal()->requestStart();
-
+ aaudio_result_t result = AAUDIO_OK;
int64_t timeoutNanos = getStreamInternal()->calculateReasonableTimeout();
// result might be a frame count
@@ -78,21 +76,21 @@
// Distribute data to each active stream.
{ // use lock guard
std::lock_guard <std::mutex> lock(mLockStreams);
- for (sp<AAudioServiceStreamShared> sharedStream : mRunningStreams) {
- FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
- if (fifo->getFifoControllerBase()->getEmptyFramesAvailable() <
- getFramesPerBurst()) {
- underflowCount++;
- } else {
- fifo->write(mDistributionBuffer, getFramesPerBurst());
+ for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
+ if (sharedStream->isRunning()) {
+ FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
+ if (fifo->getFifoControllerBase()->getEmptyFramesAvailable() <
+ getFramesPerBurst()) {
+ underflowCount++;
+ } else {
+ fifo->write(mDistributionBuffer, getFramesPerBurst());
+ }
+ sharedStream->markTransferTime(AudioClock::getNanoseconds());
}
- sharedStream->markTransferTime(AudioClock::getNanoseconds());
}
}
}
- result = getStreamInternal()->requestStop();
-
ALOGD("AAudioServiceEndpointCapture(): callbackLoop() exiting, %d underflows", underflowCount);
return NULL; // TODO review
}
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index 1afcc1e..86ccde0 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -68,9 +68,7 @@
void *AAudioServiceEndpointPlay::callbackLoop() {
ALOGD("AAudioServiceEndpointPlay(): callbackLoop() entering");
int32_t underflowCount = 0;
-
- aaudio_result_t result = getStreamInternal()->requestStart();
-
+ aaudio_result_t result = AAUDIO_OK;
int64_t timeoutNanos = getStreamInternal()->calculateReasonableTimeout();
// result might be a frame count
@@ -79,13 +77,15 @@
mMixer.clear();
{ // use lock guard
std::lock_guard <std::mutex> lock(mLockStreams);
- for (sp<AAudioServiceStreamShared> sharedStream : mRunningStreams) {
- FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
- float volume = 1.0; // to match legacy volume
- bool underflowed = mMixer.mix(fifo, volume);
- underflowCount += underflowed ? 1 : 0;
- // TODO log underflows in each stream
- sharedStream->markTransferTime(AudioClock::getNanoseconds());
+ for (sp<AAudioServiceStreamShared> sharedStream : mRegisteredStreams) {
+ if (sharedStream->isRunning()) {
+ FifoBuffer *fifo = sharedStream->getDataFifoBuffer();
+ float volume = 1.0; // to match legacy volume
+ bool underflowed = mMixer.mix(fifo, volume);
+ underflowCount += underflowed ? 1 : 0;
+ // TODO log underflows in each stream
+ sharedStream->markTransferTime(AudioClock::getNanoseconds());
+ }
}
}
@@ -102,8 +102,6 @@
}
}
- result = getStreamInternal()->requestStop();
-
ALOGD("AAudioServiceEndpointPlay(): callbackLoop() exiting, %d underflows", underflowCount);
return NULL; // TODO review
}
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 52b1801..e0f6ad4 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AAudioService"
+#define LOG_TAG "AAudioServiceStreamBase"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -38,6 +38,9 @@
AAudioServiceStreamBase::AAudioServiceStreamBase()
: mUpMessageQueue(nullptr)
, mAAudioThread() {
+ mMmapClient.clientUid = -1;
+ mMmapClient.clientPid = -1;
+ mMmapClient.packageName = String16("");
}
AAudioServiceStreamBase::~AAudioServiceStreamBase() {
@@ -45,7 +48,8 @@
// If the stream is deleted when OPEN or in use then audio resources will leak.
// This would indicate an internal error. So we want to find this ASAP.
LOG_ALWAYS_FATAL_IF(!(mState == AAUDIO_STREAM_STATE_CLOSED
- || mState == AAUDIO_STREAM_STATE_UNINITIALIZED),
+ || mState == AAUDIO_STREAM_STATE_UNINITIALIZED
+ || mState == AAUDIO_STREAM_STATE_DISCONNECTED),
"service stream still open, state = %d", mState);
}
@@ -58,13 +62,18 @@
result << " framesPerBurst = " << mFramesPerBurst << "\n";
result << " channelCount = " << mSamplesPerFrame << "\n";
result << " capacityFrames = " << mCapacityInFrames << "\n";
- result << " owner uid = " << mOwnerUserId << "\n";
+ result << " owner uid = " << mMmapClient.clientUid << "\n";
return result.str();
}
aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest &request,
aaudio::AAudioStreamConfiguration &configurationOutput) {
+
+ mMmapClient.clientUid = request.getUserId();
+ mMmapClient.clientPid = request.getProcessId();
+ mMmapClient.packageName.setTo(String16("")); // FIXME what should we do here?
+
std::lock_guard<std::mutex> lock(mLockUpMessageQueue);
if (mUpMessageQueue != nullptr) {
return AAUDIO_ERROR_INVALID_STATE;
@@ -86,6 +95,9 @@
}
aaudio_result_t AAudioServiceStreamBase::start() {
+ if (isRunning()) {
+ return AAUDIO_OK;
+ }
sendServiceEvent(AAUDIO_SERVICE_EVENT_STARTED);
mState = AAUDIO_STREAM_STATE_STARTED;
mThreadEnabled.store(true);
@@ -94,32 +106,34 @@
aaudio_result_t AAudioServiceStreamBase::pause() {
aaudio_result_t result = AAUDIO_OK;
- if (isRunning()) {
- sendCurrentTimestamp();
- mThreadEnabled.store(false);
- result = mAAudioThread.stop();
- if (result != AAUDIO_OK) {
- disconnect();
- return result;
- }
- sendServiceEvent(AAUDIO_SERVICE_EVENT_PAUSED);
+ if (!isRunning()) {
+ return result;
}
+ sendCurrentTimestamp();
+ mThreadEnabled.store(false);
+ result = mAAudioThread.stop();
+ if (result != AAUDIO_OK) {
+ disconnect();
+ return result;
+ }
+ sendServiceEvent(AAUDIO_SERVICE_EVENT_PAUSED);
mState = AAUDIO_STREAM_STATE_PAUSED;
return result;
}
aaudio_result_t AAudioServiceStreamBase::stop() {
aaudio_result_t result = AAUDIO_OK;
- if (isRunning()) {
- // TODO wait for data to be played out
- sendCurrentTimestamp(); // warning - this calls a virtual function
- result = stopTimestampThread();
- if (result != AAUDIO_OK) {
- disconnect();
- return result;
- }
- sendServiceEvent(AAUDIO_SERVICE_EVENT_STOPPED);
+ if (!isRunning()) {
+ return result;
}
+ // TODO wait for data to be played out
+ sendCurrentTimestamp(); // warning - this calls a virtual function
+ result = stopTimestampThread();
+ if (result != AAUDIO_OK) {
+ disconnect();
+ return result;
+ }
+ sendServiceEvent(AAUDIO_SERVICE_EVENT_STOPPED);
mState = AAUDIO_STREAM_STATE_STOPPED;
return result;
}
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index c7df6f3..93a522e 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -27,6 +27,7 @@
#include "binding/AudioEndpointParcelable.h"
#include "binding/AAudioServiceMessage.h"
#include "utility/AAudioUtilities.h"
+#include <media/AudioClient.h>
#include "SharedRingBuffer.h"
#include "AAudioThread.h"
@@ -85,9 +86,19 @@
*/
virtual aaudio_result_t flush();
+ virtual aaudio_result_t startClient(const android::AudioClient& client __unused,
+ audio_port_handle_t *clientHandle __unused) {
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+
+ virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) {
+ return AAUDIO_ERROR_UNAVAILABLE;
+ }
+
bool isRunning() const {
return mState == AAUDIO_STREAM_STATE_STARTED;
}
+
// -------------------------------------------------------------------
/**
@@ -124,17 +135,11 @@
void disconnect();
uid_t getOwnerUserId() const {
- return mOwnerUserId;
- }
- void setOwnerUserId(uid_t uid) {
- mOwnerUserId = uid;
+ return mMmapClient.clientUid;
}
pid_t getOwnerProcessId() const {
- return mOwnerProcessId;
- }
- void setOwnerProcessId(pid_t pid) {
- mOwnerProcessId = pid;
+ return mMmapClient.clientPid;
}
aaudio_handle_t getHandle() const {
@@ -164,24 +169,25 @@
aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
- pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID;
+ pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID;
- SharedRingBuffer* mUpMessageQueue;
- std::mutex mLockUpMessageQueue;
+ SharedRingBuffer* mUpMessageQueue;
+ std::mutex mLockUpMessageQueue;
- AAudioThread mAAudioThread;
+ AAudioThread mAAudioThread;
// This is used by one thread to tell another thread to exit. So it must be atomic.
- std::atomic<bool> mThreadEnabled;
+ std::atomic<bool> mThreadEnabled;
- aaudio_format_t mAudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
- int32_t mFramesPerBurst = 0;
- int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
- int32_t mSampleRate = AAUDIO_UNSPECIFIED;
- int32_t mCapacityInFrames = AAUDIO_UNSPECIFIED;
- uid_t mOwnerUserId = -1;
- pid_t mOwnerProcessId = -1;
+ aaudio_format_t mAudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
+ int32_t mFramesPerBurst = 0;
+ int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
+ int32_t mSampleRate = AAUDIO_UNSPECIFIED;
+ int32_t mCapacityInFrames = AAUDIO_UNSPECIFIED;
+ android::AudioClient mMmapClient;
+ audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE;
+
private:
- aaudio_handle_t mHandle = -1;
+ aaudio_handle_t mHandle = -1;
};
} /* namespace aaudio */
diff --git a/services/oboeservice/AAudioServiceStreamExclusive.h b/services/oboeservice/AAudioServiceStreamExclusive.h
deleted file mode 100644
index db382a3..0000000
--- a/services/oboeservice/AAudioServiceStreamExclusive.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AAUDIO_AAUDIO_SERVICE_STREAM_EXCLUSIVE_H
-#define AAUDIO_AAUDIO_SERVICE_STREAM_EXCLUSIVE_H
-
-#include "AAudioServiceStreamMMAP.h"
-
-namespace aaudio {
-
-/**
- * Exclusive mode stream in the AAudio service.
- *
- * This is currently a stub.
- * We may move code from AAudioServiceStreamMMAP into this class.
- * If not, then it will be removed.
- */
-class AAudioServiceStreamExclusive : public AAudioServiceStreamMMAP {
-
-public:
- AAudioServiceStreamExclusive() {};
- virtual ~AAudioServiceStreamExclusive() = default;
-};
-
-} /* namespace aaudio */
-
-#endif //AAUDIO_AAUDIO_SERVICE_STREAM_EXCLUSIVE_H
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index 1b80486..68be3c3 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AAudioService"
+#define LOG_TAG "AAudioServiceStreamMMAP"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -41,19 +41,21 @@
* Service Stream that uses an MMAP buffer.
*/
-AAudioServiceStreamMMAP::AAudioServiceStreamMMAP(uid_t serviceUid)
+AAudioServiceStreamMMAP::AAudioServiceStreamMMAP(const android::AudioClient& serviceClient,
+ bool inService)
: AAudioServiceStreamBase()
, mMmapStreamCallback(new MyMmapStreamCallback(*this))
, mPreviousFrameCounter(0)
, mMmapStream(nullptr)
- , mCachedUserId(serviceUid) {
+ , mServiceClient(serviceClient)
+ , mInService(inService) {
}
aaudio_result_t AAudioServiceStreamMMAP::close() {
if (mState == AAUDIO_STREAM_STATE_CLOSED) {
return AAUDIO_OK;
}
-
+ stop();
if (mMmapStream != 0) {
mMmapStream.clear(); // TODO review. Is that all we have to do?
// Apparently the above close is asynchronous. An attempt to open a new device
@@ -90,9 +92,6 @@
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
audio_port_handle_t deviceId = configurationInput.getDeviceId();
-
- mMmapClient.clientUid = request.getUserId();
- mMmapClient.clientPid = request.getProcessId();
aaudio_direction_t direction = request.getDirection();
// Fill in config
@@ -123,8 +122,6 @@
return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
}
- mMmapClient.packageName.setTo(String16("aaudio_service")); // FIXME what should we do here?
-
MmapStreamInterface::stream_direction_t streamDirection = (direction == AAUDIO_DIRECTION_OUTPUT)
? MmapStreamInterface::DIRECTION_OUTPUT : MmapStreamInterface::DIRECTION_INPUT;
@@ -135,7 +132,8 @@
mMmapClient,
&deviceId,
mMmapStreamCallback,
- mMmapStream);
+ mMmapStream,
+ &mPortHandle);
if (status != OK) {
ALOGE("openMmapStream returned status %d", status);
return AAUDIO_ERROR_UNAVAILABLE;
@@ -172,7 +170,7 @@
mCapacityInFrames = -mCapacityInFrames;
} else {
// exclusive mode is only possible if the final fd destination is inside audioserver
- if ((mMmapClient.clientUid != mCachedUserId) &&
+ if ((mMmapClient.clientUid != mServiceClient.clientUid) &&
configurationInput.getSharingMode() == AAUDIO_SHARING_MODE_EXCLUSIVE) {
// Fallback is handled by caller but indicate what is possible in case
// this is used in the future
@@ -223,15 +221,21 @@
* Start the flow of data.
*/
aaudio_result_t AAudioServiceStreamMMAP::start() {
+ if (isRunning()) {
+ return AAUDIO_OK;
+ }
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
aaudio_result_t result;
- status_t status = mMmapStream->start(mMmapClient, &mPortHandle);
+ status_t status = mMmapStream->start(mServiceClient, &mPortHandle);
if (status != OK) {
ALOGE("AAudioServiceStreamMMAP::start() mMmapStream->start() returned %d", status);
disconnect();
result = AAudioConvert_androidToAAudioResult(status);
} else {
result = AAudioServiceStreamBase::start();
+ if (!mInService && result == AAUDIO_OK) {
+ startClient(mMmapClient, &mClientHandle);
+ }
}
return result;
}
@@ -240,18 +244,28 @@
* Stop the flow of data such that start() can resume with loss of data.
*/
aaudio_result_t AAudioServiceStreamMMAP::pause() {
+ if (!isRunning()) {
+ return AAUDIO_OK;
+ }
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
-
aaudio_result_t result1 = AAudioServiceStreamBase::pause();
+ if (!mInService) {
+ stopClient(mClientHandle);
+ }
status_t status = mMmapStream->stop(mPortHandle);
mFramesRead.reset32();
return (result1 != AAUDIO_OK) ? result1 : AAudioConvert_androidToAAudioResult(status);
}
aaudio_result_t AAudioServiceStreamMMAP::stop() {
+ if (!isRunning()) {
+ return AAUDIO_OK;
+ }
if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
-
aaudio_result_t result1 = AAudioServiceStreamBase::stop();
+ if (!mInService) {
+ stopClient(mClientHandle);
+ }
aaudio_result_t status = mMmapStream->stop(mPortHandle);
mFramesRead.reset32();
return (result1 != AAUDIO_OK) ? result1 : AAudioConvert_androidToAAudioResult(status);
@@ -266,6 +280,15 @@
return AAudioServiceStreamBase::flush();;
}
+aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client,
+ audio_port_handle_t *clientHandle) {
+ return AAudioConvert_androidToAAudioResult(mMmapStream->start(client, clientHandle));
+}
+
+aaudio_result_t AAudioServiceStreamMMAP::stopClient(audio_port_handle_t clientHandle) {
+ return AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
+}
+
aaudio_result_t AAudioServiceStreamMMAP::getFreeRunningPosition(int64_t *positionFrames,
int64_t *timeNanos) {
struct audio_mmap_position position;
@@ -301,11 +324,11 @@
void AAudioServiceStreamMMAP::onRoutingChanged(audio_port_handle_t deviceId) {
ALOGD("AAudioServiceStreamMMAP::onRoutingChanged() called with %d, old = %d",
- deviceId, mPortHandle);
- if (mPortHandle > 0 && mPortHandle != deviceId) {
+ deviceId, mDeviceId);
+ if (mDeviceId != AUDIO_PORT_HANDLE_NONE && mDeviceId != deviceId) {
disconnect();
}
- mPortHandle = deviceId;
+ mDeviceId = deviceId;
};
/**
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index 257bea9..533e5a8 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -43,7 +43,7 @@
, public android::MmapStreamCallback {
public:
- AAudioServiceStreamMMAP(uid_t serviceUid);
+ AAudioServiceStreamMMAP(const android::AudioClient& serviceClient, bool inService);
virtual ~AAudioServiceStreamMMAP() = default;
aaudio_result_t open(const aaudio::AAudioStreamRequest &request,
@@ -77,6 +77,11 @@
aaudio_result_t close() override;
+ virtual aaudio_result_t startClient(const android::AudioClient& client,
+ audio_port_handle_t *clientHandle);
+
+ virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle);
+
/**
* Send a MMAP/NOIRQ buffer timestamp to the client.
*/
@@ -131,9 +136,10 @@
// Interface to the AudioFlinger MMAP support.
android::sp<android::MmapStreamInterface> mMmapStream;
struct audio_mmap_buffer_info mMmapBufferinfo;
- android::MmapStreamInterface::Client mMmapClient;
- audio_port_handle_t mPortHandle = -1; // TODO review best default
- uid_t mCachedUserId = -1;
+ audio_port_handle_t mPortHandle = AUDIO_PORT_HANDLE_NONE;
+ audio_port_handle_t mDeviceId = AUDIO_PORT_HANDLE_NONE;
+ android::AudioClient mServiceClient;
+ bool mInService = false;
};
} // namespace aaudio
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 8bb34d1..fe488cb 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "AAudioService"
+#define LOG_TAG "AAudioServiceStreamShared"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -191,6 +191,9 @@
* An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete.
*/
aaudio_result_t AAudioServiceStreamShared::start() {
+ if (isRunning()) {
+ return AAUDIO_OK;
+ }
AAudioServiceEndpoint *endpoint = mServiceEndpoint;
if (endpoint == nullptr) {
return AAUDIO_ERROR_INVALID_STATE;
@@ -201,7 +204,10 @@
ALOGE("AAudioServiceStreamShared::start() mServiceEndpoint returned %d", result);
disconnect();
} else {
- result = AAudioServiceStreamBase::start();
+ result = endpoint->getStreamInternal()->startClient(mMmapClient, &mClientHandle);
+ if (result == AAUDIO_OK) {
+ result = AAudioServiceStreamBase::start();
+ }
}
return result;
}
@@ -212,10 +218,14 @@
* An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete.
*/
aaudio_result_t AAudioServiceStreamShared::pause() {
+ if (!isRunning()) {
+ return AAUDIO_OK;
+ }
AAudioServiceEndpoint *endpoint = mServiceEndpoint;
if (endpoint == nullptr) {
return AAUDIO_ERROR_INVALID_STATE;
}
+ endpoint->getStreamInternal()->stopClient(mClientHandle);
aaudio_result_t result = endpoint->stopStream(this);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
@@ -225,10 +235,14 @@
}
aaudio_result_t AAudioServiceStreamShared::stop() {
+ if (!isRunning()) {
+ return AAUDIO_OK;
+ }
AAudioServiceEndpoint *endpoint = mServiceEndpoint;
if (endpoint == nullptr) {
return AAUDIO_ERROR_INVALID_STATE;
}
+ endpoint->getStreamInternal()->stopClient(mClientHandle);
aaudio_result_t result = endpoint->stopStream(this);
if (result != AAUDIO_OK) {
ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
@@ -248,7 +262,7 @@
return AAUDIO_ERROR_INVALID_STATE;
}
if (mState != AAUDIO_STREAM_STATE_PAUSED) {
- ALOGE("AAudioServiceStreamShared::flush() stream not paused, state = %s",
+ ALOGE("AAudioServiceStreamShared::flush() stream not paused, state = %s",
AAudio_convertStreamStateToText(mState));
return AAUDIO_ERROR_INVALID_STATE;
}
@@ -261,11 +275,12 @@
return AAUDIO_OK;
}
+ stop();
+
AAudioServiceEndpoint *endpoint = mServiceEndpoint;
if (endpoint == nullptr) {
return AAUDIO_ERROR_INVALID_STATE;
}
- endpoint->stopStream(this);
endpoint->unregisterStream(this);
@@ -277,7 +292,6 @@
delete mAudioDataQueue;
mAudioDataQueue = nullptr;
}
-
return AAudioServiceStreamBase::close();
}
@@ -293,9 +307,6 @@
return AAUDIO_OK;
}
-void AAudioServiceStreamShared::onStop() {
-}
-
void AAudioServiceStreamShared::markTransferTime(int64_t nanoseconds) {
mMarkedPosition = mAudioDataQueue->getFifoBuffer()->getReadCounter();
mMarkedTime = nanoseconds;
diff --git a/services/oboeservice/AAudioServiceStreamShared.h b/services/oboeservice/AAudioServiceStreamShared.h
index 742c5af..6b67337 100644
--- a/services/oboeservice/AAudioServiceStreamShared.h
+++ b/services/oboeservice/AAudioServiceStreamShared.h
@@ -87,8 +87,6 @@
*/
void markTransferTime(int64_t nanoseconds);
- void onStop();
-
protected:
aaudio_result_t getDownDataDescription(AudioEndpointParcelable &parcelable) override;