Merge "AudioFlinger: Prevent multiple effect chains with same sessionId"
diff --git a/camera/OWNERS b/camera/OWNERS
index 18acfee..d6b95da 100644
--- a/camera/OWNERS
+++ b/camera/OWNERS
@@ -1,6 +1,8 @@
-cychen@google.com
epeev@google.com
etalvala@google.com
+jchowdhary@google.com
shuzhenwang@google.com
yinchiayeh@google.com
+# backup owner
+cychen@google.com
zhijunhe@google.com
diff --git a/camera/ndk/NdkCameraCaptureSession.cpp b/camera/ndk/NdkCameraCaptureSession.cpp
index ab796fb..1ac8482 100644
--- a/camera/ndk/NdkCameraCaptureSession.cpp
+++ b/camera/ndk/NdkCameraCaptureSession.cpp
@@ -105,7 +105,9 @@
if (session->isClosed()) {
ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ if (captureSequenceId) {
+ *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ }
return ACAMERA_ERROR_SESSION_CLOSED;
}
@@ -127,7 +129,9 @@
if (session->isClosed()) {
ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ if (captureSequenceId) {
+ *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ }
return ACAMERA_ERROR_SESSION_CLOSED;
}
@@ -149,7 +153,9 @@
if (session->isClosed()) {
ALOGE("%s: session %p is already closed", __FUNCTION__, session);
- *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ if (captureSequenceId) {
+ *captureSequenceId = CAPTURE_SEQUENCE_ID_NONE;
+ }
return ACAMERA_ERROR_SESSION_CLOSED;
}
diff --git a/camera/ndk/NdkCameraManager.cpp b/camera/ndk/NdkCameraManager.cpp
index 8742d9c..23d01ef 100644
--- a/camera/ndk/NdkCameraManager.cpp
+++ b/camera/ndk/NdkCameraManager.cpp
@@ -105,6 +105,60 @@
}
EXPORT
+camera_status_t ACameraManager_registerExtendedAvailabilityCallback(
+ ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+ ATRACE_CALL();
+ if (callback == nullptr) {
+ ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+ if ((callback->availabilityCallbacks.onCameraAvailable == nullptr) ||
+ (callback->availabilityCallbacks.onCameraUnavailable == nullptr) ||
+ (callback->onCameraAccessPrioritiesChanged == nullptr)) {
+ ALOGE("%s: invalid argument! callback %p, "
+ "onCameraAvailable %p, onCameraUnavailable %p onCameraAccessPrioritiesChanged %p",
+ __FUNCTION__, callback,
+ callback->availabilityCallbacks.onCameraAvailable,
+ callback->availabilityCallbacks.onCameraUnavailable,
+ callback->onCameraAccessPrioritiesChanged);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+ auto reservedEntriesCount = sizeof(callback->reserved) / sizeof(callback->reserved[0]);
+ for (size_t i = 0; i < reservedEntriesCount; i++) {
+ if (callback->reserved[i] != nullptr) {
+ ALOGE("%s: invalid argument! callback reserved entries must be set to NULL",
+ __FUNCTION__);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+ }
+ CameraManagerGlobal::getInstance().registerExtendedAvailabilityCallback(callback);
+ return ACAMERA_OK;
+}
+
+EXPORT
+camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback(
+ ACameraManager* /*manager*/, const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+ ATRACE_CALL();
+ if (callback == nullptr) {
+ ALOGE("%s: invalid argument! callback is null!", __FUNCTION__);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+ if ((callback->availabilityCallbacks.onCameraAvailable == nullptr) ||
+ (callback->availabilityCallbacks.onCameraUnavailable == nullptr) ||
+ (callback->onCameraAccessPrioritiesChanged == nullptr)) {
+ ALOGE("%s: invalid argument! callback %p, "
+ "onCameraAvailable %p, onCameraUnavailable %p onCameraAccessPrioritiesChanged %p",
+ __FUNCTION__, callback,
+ callback->availabilityCallbacks.onCameraAvailable,
+ callback->availabilityCallbacks.onCameraUnavailable,
+ callback->onCameraAccessPrioritiesChanged);
+ return ACAMERA_ERROR_INVALID_PARAMETER;
+ }
+ CameraManagerGlobal::getInstance().unregisterExtendedAvailabilityCallback(callback);
+ return ACAMERA_OK;
+}
+
+EXPORT
camera_status_t ACameraManager_getCameraCharacteristics(
ACameraManager* mgr, const char* cameraId, ACameraMetadata** chars){
ATRACE_CALL();
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 7d6ecac..9d40fd7 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -193,6 +193,20 @@
}
}
+void CameraManagerGlobal::registerExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+ Mutex::Autolock _l(mLock);
+ Callback cb(callback);
+ mCallbacks.insert(cb);
+}
+
+void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+ Mutex::Autolock _l(mLock);
+ Callback cb(callback);
+ mCallbacks.erase(cb);
+}
+
void CameraManagerGlobal::registerAvailabilityCallback(
const ACameraManager_AvailabilityCallbacks *callback) {
Mutex::Autolock _l(mLock);
@@ -289,12 +303,40 @@
(*cb)(context, cameraId.c_str());
break;
}
+ case kWhatSendSingleAccessCallback:
+ {
+ ACameraManager_AccessPrioritiesChangedCallback cb;
+ void* context;
+ AString cameraId;
+ bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
+ if (!found) {
+ ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
+ return;
+ }
+ found = msg->findPointer(kContextKey, &context);
+ if (!found) {
+ ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+ return;
+ }
+ (*cb)(context);
+ break;
+ }
default:
ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
break;
}
}
+binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
+ sp<CameraManagerGlobal> cm = mCameraManager.promote();
+ if (cm != nullptr) {
+ cm->onCameraAccessPrioritiesChanged();
+ } else {
+ ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
+ }
+ return binder::Status::ok();
+}
+
binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
int32_t status, const String16& cameraId) {
sp<CameraManagerGlobal> cm = mCameraManager.promote();
@@ -306,6 +348,19 @@
return binder::Status::ok();
}
+void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
+ Mutex::Autolock _l(mLock);
+ for (auto cb : mCallbacks) {
+ sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
+ ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
+ if (cbFp != nullptr) {
+ msg->setPointer(kCallbackFpKey, (void *) cbFp);
+ msg->setPointer(kContextKey, cb.mContext);
+ msg->post();
+ }
+ }
+}
+
void CameraManagerGlobal::onStatusChanged(
int32_t status, const String8& cameraId) {
Mutex::Autolock _l(mLock);
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index c3407f0..8c1da36 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -54,6 +54,11 @@
void unregisterAvailabilityCallback(
const ACameraManager_AvailabilityCallbacks *callback);
+ void registerExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback);
+ void unregisterExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback);
+
/**
* Return camera IDs that support camera2
*/
@@ -86,10 +91,7 @@
return binder::Status::ok();
}
- // Access priority API not implemented yet
- virtual binder::Status onCameraAccessPrioritiesChanged() {
- return binder::Status::ok();
- }
+ virtual binder::Status onCameraAccessPrioritiesChanged();
private:
const wp<CameraManagerGlobal> mCameraManager;
@@ -101,11 +103,19 @@
explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
mAvailable(callback->onCameraAvailable),
mUnavailable(callback->onCameraUnavailable),
+ mAccessPriorityChanged(nullptr),
mContext(callback->context) {}
+ explicit Callback(const ACameraManager_ExtendedAvailabilityCallbacks *callback) :
+ mAvailable(callback->availabilityCallbacks.onCameraAvailable),
+ mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
+ mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
+ mContext(callback->availabilityCallbacks.context) {}
+
bool operator == (const Callback& other) const {
return (mAvailable == other.mAvailable &&
mUnavailable == other.mUnavailable &&
+ mAccessPriorityChanged == other.mAccessPriorityChanged &&
mContext == other.mContext);
}
bool operator != (const Callback& other) const {
@@ -114,6 +124,9 @@
bool operator < (const Callback& other) const {
if (*this == other) return false;
if (mContext != other.mContext) return mContext < other.mContext;
+ if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
+ return mAccessPriorityChanged < other.mAccessPriorityChanged;
+ }
if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
return mUnavailable < other.mUnavailable;
}
@@ -122,13 +135,15 @@
}
ACameraManager_AvailabilityCallback mAvailable;
ACameraManager_AvailabilityCallback mUnavailable;
+ ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
void* mContext;
};
std::set<Callback> mCallbacks;
// definition of handler and message
enum {
- kWhatSendSingleCallback
+ kWhatSendSingleCallback,
+ kWhatSendSingleAccessCallback,
};
static const char* kCameraIdKey;
static const char* kCallbackFpKey;
@@ -141,6 +156,7 @@
sp<CallbackHandler> mHandler;
sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on
+ void onCameraAccessPrioritiesChanged();
void onStatusChanged(int32_t status, const String8& cameraId);
void onStatusChangedLocked(int32_t status, const String8& cameraId);
// Utils for status
diff --git a/camera/ndk/include/camera/NdkCameraManager.h b/camera/ndk/include/camera/NdkCameraManager.h
index 8d05ddb..136a497 100644
--- a/camera/ndk/include/camera/NdkCameraManager.h
+++ b/camera/ndk/include/camera/NdkCameraManager.h
@@ -272,6 +272,105 @@
#endif /* __ANDROID_API__ >= 24 */
+#if __ANDROID_API__ >= 29
+
+/**
+ * Definition of camera access permission change callback.
+ *
+ * <p>Notification that camera access priorities have changed and the camera may
+ * now be openable. An application that was previously denied camera access due to
+ * a higher-priority user already using the camera, or that was disconnected from an
+ * active camera session due to a higher-priority user trying to open the camera,
+ * should try to open the camera again if it still wants to use it. Note that
+ * multiple applications may receive this callback at the same time, and only one of
+ * them will succeed in opening the camera in practice, depending on exact access
+ * priority levels and timing. This method is useful in cases where multiple
+ * applications may be in the resumed state at the same time, and the user switches
+ * focus between them, or if the current camera-using application moves between
+ * full-screen and Picture-in-Picture (PiP) states. In such cases, the camera
+ * available/unavailable callbacks will not be invoked, but another application may
+ * now have higher priority for camera access than the current camera-using
+ * application.</p>
+
+ * @param context The optional application context provided by user in
+ * {@link ACameraManager_AvailabilityListener}.
+ */
+typedef void (*ACameraManager_AccessPrioritiesChangedCallback)(void* context);
+
+/**
+ * A listener for camera devices becoming available/unavailable to open or when
+ * the camera access permissions change.
+ *
+ * <p>Cameras become available when they are no longer in use, or when a new
+ * removable camera is connected. They become unavailable when some
+ * application or service starts using a camera, or when a removable camera
+ * is disconnected.</p>
+ *
+ * @see ACameraManager_registerExtendedAvailabilityCallback
+ */
+typedef struct ACameraManager_ExtendedAvailabilityListener {
+ ///
+ ACameraManager_AvailabilityCallbacks availabilityCallbacks;
+
+ /// Called when there is camera access permission change
+ ACameraManager_AccessPrioritiesChangedCallback onCameraAccessPrioritiesChanged;
+
+ /// Reserved for future use, please ensure that all entries are set to NULL
+ void *reserved[6];
+} ACameraManager_ExtendedAvailabilityCallbacks;
+
+/**
+ * Register camera extended availability callbacks.
+ *
+ * <p>onCameraUnavailable will be called whenever a camera device is opened by any camera API
+ * client. Other camera API clients may still be able to open such a camera device, evicting the
+ * existing client if they have higher priority than the existing client of a camera device.
+ * See {@link ACameraManager_openCamera} for more details.</p>
+ *
+ * <p>The callbacks will be called on a dedicated thread shared among all ACameraManager
+ * instances.</p>
+ *
+ * <p>Since this callback will be registered with the camera service, remember to unregister it
+ * once it is no longer needed; otherwise the callback will continue to receive events
+ * indefinitely and it may prevent other resources from being released. Specifically, the
+ * callbacks will be invoked independently of the general activity lifecycle and independently
+ * of the state of individual ACameraManager instances.</p>
+ *
+ * @param manager the {@link ACameraManager} of interest.
+ * @param callback the {@link ACameraManager_ExtendedAvailabilityCallbacks} to be registered.
+ *
+ * @return <ul>
+ * <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ * <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if manager or callback is NULL, or
+ * {ACameraManager_ExtendedAvailabilityCallbacks#onCameraAccessPrioritiesChanged}
+ * or {ACameraManager_AvailabilityCallbacks#onCameraAvailable} or
+ * {ACameraManager_AvailabilityCallbacks#onCameraUnavailable} is NULL.</li></ul>
+ */
+camera_status_t ACameraManager_registerExtendedAvailabilityCallback(
+ ACameraManager* manager,
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) __INTRODUCED_IN(29);
+
+/**
+ * Unregister camera extended availability callbacks.
+ *
+ * <p>Removing a callback that isn't registered has no effect.</p>
+ *
+ * @param manager the {@link ACameraManager} of interest.
+ * @param callback the {@link ACameraManager_ExtendedAvailabilityCallbacks} to be unregistered.
+ *
+ * @return <ul>
+ * <li>{@link ACAMERA_OK} if the method call succeeds.</li>
+ * <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if callback,
+ * {ACameraManager_ExtendedAvailabilityCallbacks#onCameraAccessPrioritiesChanged}
+ * or {ACameraManager_AvailabilityCallbacks#onCameraAvailable} or
+ * {ACameraManager_AvailabilityCallbacks#onCameraUnavailable} is NULL.</li></ul>
+ */
+camera_status_t ACameraManager_unregisterExtendedAvailabilityCallback(
+ ACameraManager* manager,
+ const ACameraManager_ExtendedAvailabilityCallbacks* callback) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
+
__END_DECLS
#endif /* _NDK_CAMERA_MANAGER_H */
diff --git a/camera/ndk/libcamera2ndk.map.txt b/camera/ndk/libcamera2ndk.map.txt
index 2441830..946a98e 100644
--- a/camera/ndk/libcamera2ndk.map.txt
+++ b/camera/ndk/libcamera2ndk.map.txt
@@ -23,6 +23,8 @@
ACameraManager_openCamera;
ACameraManager_registerAvailabilityCallback;
ACameraManager_unregisterAvailabilityCallback;
+ ACameraManager_registerExtendedAvailabilityCallback; # introduced=29
+ ACameraManager_unregisterExtendedAvailabilityCallback; # introduced=29
ACameraMetadata_copy;
ACameraMetadata_free;
ACameraMetadata_getAllTags;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 6b1365a..df69353 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -64,6 +64,11 @@
void unregisterAvailabilityCallback(
const ACameraManager_AvailabilityCallbacks *callback);
+ void registerExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* /*callback*/) {}
+ void unregisterExtendedAvailabilityCallback(
+ const ACameraManager_ExtendedAvailabilityCallbacks* /*callback*/) {}
+
/**
* Return camera IDs that support camera2
*/
diff --git a/media/libmedia/xsd/Android.bp b/media/libmedia/xsd/Android.bp
new file mode 100644
index 0000000..1635f70
--- /dev/null
+++ b/media/libmedia/xsd/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2019 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.
+//
+
+xsd_config {
+ name: "media_profiles",
+ srcs: ["media_profiles.xsd"],
+ package_name: "media.profiles",
+}
diff --git a/media/libmedia/xsd/api/current.txt b/media/libmedia/xsd/api/current.txt
new file mode 100644
index 0000000..0924dd9
--- /dev/null
+++ b/media/libmedia/xsd/api/current.txt
@@ -0,0 +1,140 @@
+// Signature format: 2.0
+package media.profiles {
+
+ public class Audio {
+ ctor public Audio();
+ method public int getBitRate();
+ method public int getChannels();
+ method public String getCodec();
+ method public int getSampleRate();
+ method public void setBitRate(int);
+ method public void setChannels(int);
+ method public void setCodec(String);
+ method public void setSampleRate(int);
+ }
+
+ public class AudioDecoderCap {
+ ctor public AudioDecoderCap();
+ method public boolean getEnabled();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setName(String);
+ }
+
+ public class AudioEncoderCap {
+ ctor public AudioEncoderCap();
+ method public boolean getEnabled();
+ method public int getMaxBitRate();
+ method public int getMaxChannels();
+ method public int getMaxSampleRate();
+ method public int getMinBitRate();
+ method public int getMinChannels();
+ method public int getMinSampleRate();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setMaxBitRate(int);
+ method public void setMaxChannels(int);
+ method public void setMaxSampleRate(int);
+ method public void setMinBitRate(int);
+ method public void setMinChannels(int);
+ method public void setMinSampleRate(int);
+ method public void setName(String);
+ }
+
+ public class CamcorderProfiles {
+ ctor public CamcorderProfiles();
+ method public int getCameraId();
+ method public java.util.List<media.profiles.EncoderProfile> getEncoderProfile();
+ method public java.util.List<media.profiles.CamcorderProfiles.ImageEncoding> getImageEncoding();
+ method public void setCameraId(int);
+ }
+
+ public static class CamcorderProfiles.ImageEncoding {
+ ctor public CamcorderProfiles.ImageEncoding();
+ method public int getQuality();
+ method public void setQuality(int);
+ }
+
+ public class EncoderProfile {
+ ctor public EncoderProfile();
+ method public java.util.List<media.profiles.Audio> getAudio();
+ method public int getDuration();
+ method public String getFileFormat();
+ method public String getQuality();
+ method public java.util.List<media.profiles.Video> getVideo();
+ method public void setDuration(int);
+ method public void setFileFormat(String);
+ method public void setQuality(String);
+ }
+
+ public class MediaSettings {
+ ctor public MediaSettings();
+ method public java.util.List<media.profiles.AudioDecoderCap> getAudioDecoderCap();
+ method public java.util.List<media.profiles.AudioEncoderCap> getAudioEncoderCap();
+ method public java.util.List<media.profiles.CamcorderProfiles> getCamcorderProfiles();
+ method public java.util.List<media.profiles.MediaSettings.EncoderOutputFileFormat> getEncoderOutputFileFormat();
+ method public java.util.List<media.profiles.VideoDecoderCap> getVideoDecoderCap();
+ method public java.util.List<media.profiles.VideoEncoderCap> getVideoEncoderCap();
+ }
+
+ public static class MediaSettings.EncoderOutputFileFormat {
+ ctor public MediaSettings.EncoderOutputFileFormat();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class Video {
+ ctor public Video();
+ method public int getBitRate();
+ method public String getCodec();
+ method public int getFrameRate();
+ method public int getHeight();
+ method public int getWidth();
+ method public void setBitRate(int);
+ method public void setCodec(String);
+ method public void setFrameRate(int);
+ method public void setHeight(int);
+ method public void setWidth(int);
+ }
+
+ public class VideoDecoderCap {
+ ctor public VideoDecoderCap();
+ method public boolean getEnabled();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setName(String);
+ }
+
+ public class VideoEncoderCap {
+ ctor public VideoEncoderCap();
+ method public boolean getEnabled();
+ method public int getMaxBitRate();
+ method public int getMaxFrameHeight();
+ method public int getMaxFrameRate();
+ method public int getMaxFrameWidth();
+ method public int getMinBitRate();
+ method public int getMinFrameHeight();
+ method public int getMinFrameRate();
+ method public int getMinFrameWidth();
+ method public String getName();
+ method public void setEnabled(boolean);
+ method public void setMaxBitRate(int);
+ method public void setMaxFrameHeight(int);
+ method public void setMaxFrameRate(int);
+ method public void setMaxFrameWidth(int);
+ method public void setMinBitRate(int);
+ method public void setMinFrameHeight(int);
+ method public void setMinFrameRate(int);
+ method public void setMinFrameWidth(int);
+ method public void setName(String);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static media.profiles.MediaSettings read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/media/libmedia/xsd/api/last_current.txt b/media/libmedia/xsd/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libmedia/xsd/api/last_current.txt
diff --git a/media/libmedia/xsd/api/last_removed.txt b/media/libmedia/xsd/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libmedia/xsd/api/last_removed.txt
diff --git a/media/libmedia/xsd/api/removed.txt b/media/libmedia/xsd/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libmedia/xsd/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libmedia/xsd/media_profiles.xsd b/media/libmedia/xsd/media_profiles.xsd
new file mode 100644
index 0000000..a9687b0
--- /dev/null
+++ b/media/libmedia/xsd/media_profiles.xsd
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="MediaSettings">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="CamcorderProfiles" type="CamcorderProfiles" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="EncoderOutputFileFormat" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="VideoEncoderCap" type="VideoEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="AudioEncoderCap" type="AudioEncoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="VideoDecoderCap" type="VideoDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="AudioDecoderCap" type="AudioDecoderCap" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="CamcorderProfiles">
+ <xs:sequence>
+ <xs:element name="EncoderProfile" type="EncoderProfile" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="ImageEncoding" minOccurs="0" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="quality" type="xs:int"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="cameraId" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="EncoderProfile">
+ <xs:sequence>
+ <xs:element name="Video" type="Video" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="Audio" type="Audio" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="quality" type="xs:string"/>
+ <xs:attribute name="fileFormat" type="xs:string"/>
+ <xs:attribute name="duration" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="Video">
+ <xs:attribute name="codec" type="xs:string"/>
+ <xs:attribute name="bitRate" type="xs:int"/>
+ <xs:attribute name="width" type="xs:int"/>
+ <xs:attribute name="height" type="xs:int"/>
+ <xs:attribute name="frameRate" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="Audio">
+ <xs:attribute name="codec" type="xs:string"/>
+ <xs:attribute name="bitRate" type="xs:int"/>
+ <xs:attribute name="sampleRate" type="xs:int"/>
+ <xs:attribute name="channels" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="VideoEncoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ <xs:attribute name="minBitRate" type="xs:int"/>
+ <xs:attribute name="maxBitRate" type="xs:int"/>
+ <xs:attribute name="minFrameWidth" type="xs:int"/>
+ <xs:attribute name="maxFrameWidth" type="xs:int"/>
+ <xs:attribute name="minFrameHeight" type="xs:int"/>
+ <xs:attribute name="maxFrameHeight" type="xs:int"/>
+ <xs:attribute name="minFrameRate" type="xs:int"/>
+ <xs:attribute name="maxFrameRate" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="AudioEncoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ <xs:attribute name="minBitRate" type="xs:int"/>
+ <xs:attribute name="maxBitRate" type="xs:int"/>
+ <xs:attribute name="minSampleRate" type="xs:int"/>
+ <xs:attribute name="maxSampleRate" type="xs:int"/>
+ <xs:attribute name="minChannels" type="xs:int"/>
+ <xs:attribute name="maxChannels" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="VideoDecoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ </xs:complexType>
+ <xs:complexType name="AudioDecoderCap">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="enabled" type="xs:boolean"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 3e3872d..77777b8 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -400,14 +400,15 @@
return -EBADF;
}
- // start with a clean, empty file
- ftruncate(fd, 0);
- int nextFd = dup(fd);
- if (mWriter == NULL) {
+ if (mWriter == nullptr) {
ALOGE("setNextOutputFile failed. Writer has been freed");
return INVALID_OPERATION;
}
- return mWriter->setNextFd(nextFd);
+
+ // start with a clean, empty file
+ ftruncate(fd, 0);
+
+ return mWriter->setNextFd(fd);
}
// Attempt to parse an float literal optionally surrounded by whitespace,
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index 9eba7e9..e173974 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -154,11 +154,11 @@
mDone = true;
void *dummy;
+ status_t status = mSource->stop();
pthread_join(mThread, &dummy);
status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
{
- status_t status = mSource->stop();
if (err == OK &&
(status != OK && status != ERROR_END_OF_STREAM)) {
err = status;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 1dee4f7..f00c895 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -6667,7 +6667,7 @@
return false;
}
- mDeathNotifier = new DeathNotifier(notify);
+ mDeathNotifier = new DeathNotifier(new AMessage(kWhatOMXDied, mCodec));
auto tOmxNode = omxNode->getHalInterface<IOmxNode>();
if (tOmxNode && !tOmxNode->linkToDeath(mDeathNotifier, 0)) {
mDeathNotifier.clear();
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 41106a1..24f6f0b 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -149,11 +149,11 @@
mDone = true;
void *dummy;
+ status_t status = mSource->stop();
pthread_join(mThread, &dummy);
status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
{
- status_t status = mSource->stop();
if (err == OK &&
(status != OK && status != ERROR_END_OF_STREAM)) {
err = status;
diff --git a/media/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index 0c38f2e..482a1a7 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -312,14 +312,23 @@
for (uint32_t j = 0; j < numPics; ++j) {
skipUE(&reader); // delta_poc_s0|1_minus1[i]
reader.skipBits(1); // used_by_curr_pic_s0|1_flag[i]
+ if (reader.overRead()) {
+ return ERROR_MALFORMED;
+ }
}
}
+ if (reader.overRead()) {
+ return ERROR_MALFORMED;
+ }
}
if (reader.getBitsWithFallback(1, 0)) { // long_term_ref_pics_present_flag
uint32_t numLongTermRefPicSps = parseUEWithFallback(&reader, 0);
for (uint32_t i = 0; i < numLongTermRefPicSps; ++i) {
reader.skipBits(log2MaxPicOrderCntLsb); // lt_ref_pic_poc_lsb_sps[i]
reader.skipBits(1); // used_by_curr_pic_lt_sps_flag[i]
+ if (reader.overRead()) {
+ return ERROR_MALFORMED;
+ }
}
}
reader.skipBits(1); // sps_temporal_mvp_enabled_flag
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index f6ed0f1..a52da45 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -460,7 +460,7 @@
};
MPEG4Writer::MPEG4Writer(int fd) {
- initInternal(fd, true /*isFirstSession*/);
+ initInternal(dup(fd), true /*isFirstSession*/);
}
MPEG4Writer::~MPEG4Writer() {
@@ -481,7 +481,7 @@
void MPEG4Writer::initInternal(int fd, bool isFirstSession) {
ALOGV("initInternal");
- mFd = dup(fd);
+ mFd = fd;
mNextFd = -1;
mInitCheck = mFd < 0? NO_INIT: OK;
@@ -1044,6 +1044,10 @@
void MPEG4Writer::release() {
close(mFd);
mFd = -1;
+ if (mNextFd != -1) {
+ close(mNextFd);
+ mNextFd = -1;
+ }
mInitCheck = NO_INIT;
mStarted = false;
free(mInMemoryCache);
@@ -1981,7 +1985,7 @@
// No need to set a new FD yet.
return INVALID_OPERATION;
}
- mNextFd = fd;
+ mNextFd = dup(fd);
return OK;
}
@@ -2180,11 +2184,11 @@
switch (msg->what()) {
case kWhatSwitch:
{
- finishCurrentSession();
mLock.lock();
int fd = mNextFd;
mNextFd = -1;
mLock.unlock();
+ finishCurrentSession();
initInternal(fd, false /*isFirstSession*/);
start(mStartMeta.get());
mSwitchPending = false;
diff --git a/media/libstagefright/xmlparser/Android.bp b/media/libstagefright/xmlparser/Android.bp
index 819058c..202e964 100644
--- a/media/libstagefright/xmlparser/Android.bp
+++ b/media/libstagefright/xmlparser/Android.bp
@@ -10,7 +10,6 @@
vndk: {
enabled: true,
},
- double_loadable: true,
srcs: [
"MediaCodecsXmlParser.cpp",
@@ -47,3 +46,9 @@
}
+xsd_config {
+ name: "media_codecs",
+ srcs: ["media_codecs.xsd"],
+ package_name: "media.codecs",
+}
+
diff --git a/media/libstagefright/xmlparser/api/current.txt b/media/libstagefright/xmlparser/api/current.txt
new file mode 100644
index 0000000..f5245c1
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/current.txt
@@ -0,0 +1,108 @@
+// Signature format: 2.0
+package media.codecs {
+
+ public class Decoders {
+ ctor public Decoders();
+ method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+ }
+
+ public class Encoders {
+ ctor public Encoders();
+ method public java.util.List<media.codecs.MediaCodec> getMediaCodec();
+ }
+
+ public class Feature {
+ ctor public Feature();
+ method public String getName();
+ method public String getOptional();
+ method public String getRequired();
+ method public String getValue();
+ method public void setName(String);
+ method public void setOptional(String);
+ method public void setRequired(String);
+ method public void setValue(String);
+ }
+
+ public class Limit {
+ ctor public Limit();
+ method public String getIn();
+ method public String getMax();
+ method public String getMin();
+ method public String getName();
+ method public String getRange();
+ method public String getRanges();
+ method public String getScale();
+ method public String getValue();
+ method public String get_default();
+ method public void setIn(String);
+ method public void setMax(String);
+ method public void setMin(String);
+ method public void setName(String);
+ method public void setRange(String);
+ method public void setRanges(String);
+ method public void setScale(String);
+ method public void setValue(String);
+ method public void set_default(String);
+ }
+
+ public class MediaCodec {
+ ctor public MediaCodec();
+ method public java.util.List<media.codecs.Feature> getFeature();
+ method public java.util.List<media.codecs.Limit> getLimit();
+ method public String getName();
+ method public java.util.List<media.codecs.Quirk> getQuirk();
+ method public java.util.List<media.codecs.Type> getType();
+ method public String getType();
+ method public String getUpdate();
+ method public void setName(String);
+ method public void setType(String);
+ method public void setUpdate(String);
+ }
+
+ public class MediaCodecs {
+ ctor public MediaCodecs();
+ method public java.util.List<media.codecs.Decoders> getDecoders();
+ method public java.util.List<media.codecs.Encoders> getEncoders();
+ method public java.util.List<media.codecs.Settings> getSettings();
+ }
+
+ public class Quirk {
+ ctor public Quirk();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class Setting {
+ ctor public Setting();
+ method public String getName();
+ method public String getUpdate();
+ method public String getValue();
+ method public void setName(String);
+ method public void setUpdate(String);
+ method public void setValue(String);
+ }
+
+ public class Settings {
+ ctor public Settings();
+ method public java.util.List<media.codecs.Setting> getSetting();
+ }
+
+ public class Type {
+ ctor public Type();
+ method public java.util.List<media.codecs.Feature> getFeature();
+ method public java.util.List<media.codecs.Limit> getLimit();
+ method public String getName();
+ method public String getUpdate();
+ method public void setName(String);
+ method public void setUpdate(String);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static media.codecs.MediaCodecs read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/media/libstagefright/xmlparser/api/last_current.txt b/media/libstagefright/xmlparser/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/last_current.txt
diff --git a/media/libstagefright/xmlparser/api/last_removed.txt b/media/libstagefright/xmlparser/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/last_removed.txt
diff --git a/media/libstagefright/xmlparser/api/removed.txt b/media/libstagefright/xmlparser/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/media/libstagefright/xmlparser/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/media/libstagefright/xmlparser/media_codecs.xsd b/media/libstagefright/xmlparser/media_codecs.xsd
new file mode 100644
index 0000000..4faba87
--- /dev/null
+++ b/media/libstagefright/xmlparser/media_codecs.xsd
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="MediaCodecs">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Decoders" type="Decoders" maxOccurs="unbounded"/>
+ <xs:element name="Encoders" type="Encoders" maxOccurs="unbounded"/>
+ <xs:element name="Settings" type="Settings" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="Decoders">
+ <xs:sequence>
+ <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="Encoders">
+ <xs:sequence>
+ <xs:element name="MediaCodec" type="MediaCodec" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="Settings">
+ <xs:sequence>
+ <xs:element name="Setting" type="Setting" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="MediaCodec">
+ <xs:sequence>
+ <xs:element name="Quirk" type="Quirk" maxOccurs="unbounded"/>
+ <xs:element name="Type" type="Type" maxOccurs="unbounded"/>
+ <xs:element name="Limit" type="Limit" maxOccurs="unbounded"/>
+ <xs:element name="Feature" type="Feature" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="type" type="xs:string"/>
+ <xs:attribute name="update" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Quirk">
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Type">
+ <xs:sequence>
+ <xs:element name="Limit" type="Limit" maxOccurs="unbounded"/>
+ <xs:element name="Feature" type="Feature" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="update" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Limit">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="default" type="xs:string"/>
+ <xs:attribute name="in" type="xs:string"/>
+ <xs:attribute name="max" type="xs:string"/>
+ <xs:attribute name="min" type="xs:string"/>
+ <xs:attribute name="range" type="xs:string"/>
+ <xs:attribute name="ranges" type="xs:string"/>
+ <xs:attribute name="scale" type="xs:string"/>
+ <xs:attribute name="value" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Feature">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="optional" type="xs:string"/>
+ <xs:attribute name="required" type="xs:string"/>
+ <xs:attribute name="value" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="Setting">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="value" type="xs:string"/>
+ <xs:attribute name="update" type="xs:string"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/media/ndk/OWNERS b/media/ndk/OWNERS
index 11e8340..9dc441e 100644
--- a/media/ndk/OWNERS
+++ b/media/ndk/OWNERS
@@ -1,5 +1,3 @@
marcone@google.com
# For AImage/AImageReader
-etalvala@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 9e4eebc..3badda1 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -62,10 +62,6 @@
$(error Configurable policy does not support legacy conf file)
endif #ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-LOCAL_REQUIRED_MODULES := \
- parameter-framework.policy \
- audio_policy_criteria.conf \
-
LOCAL_C_INCLUDES += frameworks/av/services/audiopolicy/engineconfigurable/include
LOCAL_C_INCLUDES += frameworks/av/include
diff --git a/services/audiopolicy/common/include/Volume.h b/services/audiopolicy/common/include/Volume.h
index 48b5271..561f100 100644
--- a/services/audiopolicy/common/include/Volume.h
+++ b/services/audiopolicy/common/include/Volume.h
@@ -16,19 +16,22 @@
#pragma once
+#include <media/AudioCommonTypes.h>
#include <system/audio.h>
#include <utils/Log.h>
#include <math.h>
namespace android {
+
/**
* VolumeSource is the discriminent for volume management on an output.
* It used to be the stream type by legacy, it may be host volume group or a volume curves if
- * we allow to have more than one curve per volume group.
+ * we allow to have more than one curve per volume group (mandatory to get rid of AudioServer
+ * stream aliases.
*/
-enum VolumeSource : std::underlying_type<audio_stream_type_t>::type;
-static const VolumeSource VOLUME_SOURCE_NONE = static_cast<VolumeSource>(AUDIO_STREAM_DEFAULT);
+enum VolumeSource : std::underlying_type<volume_group_t>::type;
+static const VolumeSource VOLUME_SOURCE_NONE = static_cast<VolumeSource>(VOLUME_GROUP_NONE);
static inline VolumeSource streamToVolumeSource(audio_stream_type_t stream) {
return static_cast<VolumeSource>(stream);
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 73a8249..cd54085 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -107,7 +107,7 @@
};
/**
* Note: volume activities shall be indexed by CurvesId if we want to allow multiple
- * curves per volume group, inferring a mute management or volume balancing between HW and SW is
+ * curves per volume source, inferring a mute management or volume balancing between HW and SW is
* done
*/
using VolumeActivities = std::map<VolumeSource, VolumeActivity>;
@@ -157,7 +157,7 @@
virtual uint32_t latency() { return 0; }
virtual bool isFixedVolume(audio_devices_t device);
virtual bool setVolume(float volumeDb,
- audio_stream_type_t stream,
+ VolumeSource volumeSource, const StreamTypeVector &streams,
audio_devices_t device,
uint32_t delayMs,
bool force);
@@ -221,7 +221,7 @@
}
void setCurVolume(VolumeSource vs, float volumeDb)
{
- // Even if not activity for this group registered, need to create anyway
+ // Even if not activity for this source registered, need to create anyway
mVolumeActivities[vs].setVolume(volumeDb);
}
float getCurVolume(VolumeSource vs) const
@@ -280,6 +280,11 @@
return mActiveClients;
}
+ bool useHwGain() const
+ {
+ return !devices().isEmpty() ? devices().itemAt(0)->hasGainController() : false;
+ }
+
DeviceVector mDevices; /**< current devices this output is routed to */
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
@@ -328,7 +333,7 @@
}
}
virtual bool setVolume(float volumeDb,
- audio_stream_type_t stream,
+ VolumeSource volumeSource, const StreamTypeVector &streams,
audio_devices_t device,
uint32_t delayMs,
bool force);
@@ -402,7 +407,7 @@
void dump(String8 *dst) const override;
virtual bool setVolume(float volumeDb,
- audio_stream_type_t stream,
+ VolumeSource volumeSource, const StreamTypeVector &streams,
audio_devices_t device,
uint32_t delayMs,
bool force);
@@ -422,7 +427,7 @@
bool isActive(VolumeSource volumeSource, uint32_t inPastMs = 0) const;
/**
- * return whether any source contributing to VolumeSource is playing remotely, override
+ * return whether any source contributing to VolumeSource is playing remotely, override
* to change the definition of
* local/remote playback, used for instance by notification manager to not make
* media players lose audio focus when not playing locally
@@ -488,8 +493,8 @@
/**
* @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
* hold the volume source to be ignored
- * @param volumeSourceToIgnore source not considered in the activity detection
- * @return true if any output is active for any source except the one to be ignored
+ * @param volumeSourceToIgnore source not to be considered in the activity detection
+ * @return true if any output is active for any volume source except the one to be ignored
*/
bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
{
@@ -518,8 +523,8 @@
/**
* @brief isAnyOutputActive checks if any output is active (aka playing) except the one(s) that
* hold the volume source to be ignored
- * @param volumeSourceToIgnore source not considered in the activity detection
- * @return true if any output is active for any source except the one to be ignored
+ * @param volumeSourceToIgnore source not to be considered in the activity detection
+ * @return true if any output is active for any volume source except the one to be ignored
*/
bool isAnyOutputActive(VolumeSource volumeSourceToIgnore) const
{
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 833c7b9..97b7a01 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -24,6 +24,7 @@
#include "AudioGain.h"
#include "Volume.h"
#include "HwModule.h"
+#include "TypeConverter.h"
#include <media/AudioParameter.h>
#include <media/AudioPolicy.h>
@@ -152,17 +153,18 @@
}
bool AudioOutputDescriptor::setVolume(float volumeDb,
- audio_stream_type_t stream,
- audio_devices_t device __unused,
+ VolumeSource volumeSource,
+ const StreamTypeVector &/*streams*/,
+ audio_devices_t /*device*/,
uint32_t delayMs,
bool force)
{
// We actually change the volume if:
// - the float value returned by computeVolume() changed
// - the force flag is set
- if (volumeDb != getCurVolume(static_cast<VolumeSource>(stream)) || force) {
- ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volumeDb, delayMs);
- setCurVolume(static_cast<VolumeSource>(stream), volumeDb);
+ if (volumeDb != getCurVolume(volumeSource) || force) {
+ ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
+ setCurVolume(volumeSource, volumeDb);
return true;
}
return false;
@@ -391,23 +393,33 @@
}
bool SwAudioOutputDescriptor::setVolume(float volumeDb,
- audio_stream_type_t stream,
+ VolumeSource vs, const StreamTypeVector &streamTypes,
audio_devices_t device,
uint32_t delayMs,
bool force)
{
- if (!AudioOutputDescriptor::setVolume(volumeDb, stream, device, delayMs, force)) {
+ StreamTypeVector streams = streamTypes;
+ if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, device, delayMs, force)) {
return false;
}
- if (!devices().isEmpty()) {
- // Assume first device to check upon Gain Crontroller availability
- const auto &devicePort = devices().itemAt(0);
- ALOGV("%s: device %s hasGC %d", __FUNCTION__,
- devicePort->toString().c_str(), devices().itemAt(0)->hasGainController(true));
- if (devicePort->hasGainController(true)) {
+ if (streams.empty()) {
+ streams.push_back(AUDIO_STREAM_MUSIC);
+ }
+ for (const auto& devicePort : devices()) {
+ // APM loops on all group, so filter on active group to set the port gain,
+ // let the other groups set the stream volume as per legacy
+ // TODO: Pass in the device address and check against it.
+ if (device == devicePort->type() &&
+ devicePort->hasGainController(true) && isActive(vs)) {
+ ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
+ // @todo: here we might be in trouble if the SwOutput has several active clients with
+ // different Volume Source (or if we allow several curves within same volume group)
+ //
// @todo: default stream volume to max (0) when using HW Port gain?
float volumeAmpl = Volume::DbToAmpl(0);
- mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
+ for (const auto &stream : streams) {
+ mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
+ }
AudioGains gains = devicePort->getGains();
int gainMinValueInMb = gains[0]->getMinValueInMb();
@@ -424,11 +436,15 @@
}
}
// Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
- float volumeAmpl = Volume::DbToAmpl(getCurVolume(static_cast<VolumeSource>(stream)));
- if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
+ float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
+ if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
}
- mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
+ for (const auto &stream : streams) {
+ ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
+ mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
+ mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
+ }
return true;
}
@@ -618,12 +634,13 @@
bool HwAudioOutputDescriptor::setVolume(float volumeDb,
- audio_stream_type_t stream,
+ VolumeSource volumeSource, const StreamTypeVector &streams,
audio_devices_t device,
uint32_t delayMs,
bool force)
{
- bool changed = AudioOutputDescriptor::setVolume(volumeDb, stream, device, delayMs, force);
+ bool changed =
+ AudioOutputDescriptor::setVolume(volumeDb, volumeSource, streams, device, delayMs, force);
if (changed) {
// TODO: use gain controller on source device if any to adjust volume
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 6ff8512..cedc78f 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -84,10 +84,6 @@
volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const override;
- StreamTypeVector getStreamTypesForVolumeGroup(volume_group_t volumeGroup) const override;
-
- AttributesVector getAllAttributesForVolumeGroup(volume_group_t volumeGroup) const override;
-
status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const override;
void dump(String8 *dst) const override;
@@ -112,7 +108,7 @@
VolumeSource toVolumeSource(audio_stream_type_t stream) const
{
- return static_cast<VolumeSource>(stream);
+ return static_cast<VolumeSource>(getVolumeGroupForStreamType(stream));
}
status_t switchVolumeCurve(audio_stream_type_t streamSrc, audio_stream_type_t streamDst);
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index 767a8ed..1a2a198 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -152,6 +152,8 @@
volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;
+ volume_group_t getDefaultVolumeGroup() const;
+
product_strategy_t getDefault() const;
void dump(String8 *dst, int spaces = 0) const;
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 4fe7b42..07a7e65 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -218,6 +218,9 @@
VolumeCurves *EngineBase::getVolumeCurvesForStreamType(audio_stream_type_t stream) const
{
volume_group_t volGr = mProductStrategies.getVolumeGroupForStreamType(stream);
+ if (volGr == VOLUME_GROUP_NONE) {
+ volGr = mProductStrategies.getDefaultVolumeGroup();
+ }
const auto &iter = mVolumeGroups.find(volGr);
LOG_ALWAYS_FATAL_IF(iter == std::end(mVolumeGroups), "No volume groups for %s",
toString(stream).c_str());
@@ -260,20 +263,6 @@
return mProductStrategies.getVolumeGroupForStreamType(stream);
}
-StreamTypeVector EngineBase::getStreamTypesForVolumeGroup(volume_group_t volumeGroup) const
-{
- // @TODO default music stream to control volume if no group?
- return (mVolumeGroups.find(volumeGroup) != end(mVolumeGroups)) ?
- mVolumeGroups.at(volumeGroup)->getStreamTypes() :
- StreamTypeVector(AUDIO_STREAM_MUSIC);
-}
-
-AttributesVector EngineBase::getAllAttributesForVolumeGroup(volume_group_t volumeGroup) const
-{
- return (mVolumeGroups.find(volumeGroup) != end(mVolumeGroups)) ?
- mVolumeGroups.at(volumeGroup)->getSupportedAttributes() : AttributesVector();
-}
-
status_t EngineBase::listAudioVolumeGroups(AudioVolumeGroupVector &groups) const
{
for (const auto &iter : mVolumeGroups) {
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index 16e6690..f74f190 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -270,11 +270,7 @@
return group;
}
}
- product_strategy_t defaultStrategy = getDefault();
- if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
- return VOLUME_GROUP_NONE;
- }
- return at(defaultStrategy)->getDefaultVolumeGroup();
+ return getDefaultVolumeGroup();
}
volume_group_t ProductStrategyMap::getVolumeGroupForStreamType(audio_stream_type_t stream) const
@@ -285,6 +281,12 @@
return group;
}
}
+ ALOGW("%s: no volume group for %s, using default", __func__, toString(stream).c_str());
+ return getDefaultVolumeGroup();
+}
+
+volume_group_t ProductStrategyMap::getDefaultVolumeGroup() const
+{
product_strategy_t defaultStrategy = getDefault();
if (defaultStrategy == PRODUCT_STRATEGY_NONE) {
return VOLUME_GROUP_NONE;
diff --git a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
index 4315061..b7fd031 100644
--- a/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
+++ b/services/audiopolicy/engine/interface/AudioPolicyManagerInterface.h
@@ -283,10 +283,6 @@
*/
virtual volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const = 0;
- virtual StreamTypeVector getStreamTypesForVolumeGroup(volume_group_t volumeGroup) const = 0;
-
- virtual AttributesVector getAllAttributesForVolumeGroup(volume_group_t volumeGroup) const = 0;
-
/**
* @brief listAudioVolumeGroups introspection API to get the Audio Volume Groups, aka
* former stream aliases in Audio Service, defining volume curves attached to one or more
diff --git a/services/audiopolicy/engineconfigurable/config/example/Android.mk b/services/audiopolicy/engineconfigurable/config/example/Android.mk
index 45419f0..37271b5 100644
--- a/services/audiopolicy/engineconfigurable/config/example/Android.mk
+++ b/services/audiopolicy/engineconfigurable/config/example/Android.mk
@@ -10,16 +10,15 @@
ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_configuration_phone.xml
-LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+LOCAL_MODULE := audio_policy_engine_configuration.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
LOCAL_REQUIRED_MODULES := \
- audio_policy_engine_product_strategies_phone.xml \
+ audio_policy_engine_product_strategies.xml \
audio_policy_engine_stream_volumes.xml \
audio_policy_engine_default_stream_volumes.xml \
audio_policy_engine_criteria.xml \
@@ -28,12 +27,11 @@
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_product_strategies_phone.xml
-LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
@@ -55,39 +53,40 @@
endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_configurable)
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),automotive_configurable caremu_configurable))
##################################################################
# AUTOMOTIVE CONFIGURATION TOP FILE
##################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_configuration_automotive.xml
-LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
-
+LOCAL_MODULE := audio_policy_engine_configuration.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
LOCAL_REQUIRED_MODULES := \
- audio_policy_engine_product_strategies_automotive.xml \
+ audio_policy_engine_product_strategies.xml \
audio_policy_engine_criteria.xml \
audio_policy_engine_criterion_types.xml \
audio_policy_engine_volumes.xml
include $(BUILD_PREBUILT)
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),automotive_configurable caremu_configurable))
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
+
##################################################################
# CONFIGURATION FILES
##################################################################
include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_product_strategies_automotive.xml
-LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := automotive/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
@@ -100,7 +99,31 @@
endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), automotive_configurable)
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := caremu/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_policy_engine_volumes.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := caremu/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
include $(CLEAR_VARS)
LOCAL_MODULE := audio_policy_engine_criteria.xml
@@ -123,4 +146,4 @@
include $(PROVISION_CRITERION_TYPES)
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
diff --git a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
index b326b50..9ec3d77 100644
--- a/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
+++ b/services/audiopolicy/engineconfigurable/config/example/automotive/audio_policy_engine_volumes.xml
@@ -159,7 +159,7 @@
<name>phone</name>
<indexMin>1</indexMin>
<indexMax>40</indexMax>
- <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point>
diff --git a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml
new file mode 100644
index 0000000..c487da9
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_product_strategies.xml
@@ -0,0 +1,170 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<ProductStrategies>
+ <!-- OEM Usages -->
+ <!-- product_strategy will be defined according this order
+ product_strategy is oem_traffic_anouncement if all the conditions are satisfied for
+ AudioAttributes aa
+
+ int type = 0;
+ if (bundle != null) {
+ type = bundle.getInt(KEY_OEM_TYPE, 0);
+ }
+ if(
+ ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+ ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+ ( type == 1 ) )
+ -->
+
+ <ProductStrategy name="oem_traffic_anouncement">
+ <AttributesGroup volumeGroup="oem_traffic_anouncement">
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <!-- traffic_annoucement = 1 -->
+ <Bundle key="oem" value="1"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="oem_strategy_1">
+ <AttributesGroup volumeGroup="oem_adas_2">
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <Bundle key="oem" value="2"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="oem_strategy_2">
+ <AttributesGroup volumeGroup="oem_adas_3">
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <Bundle key="oem" value="3"/>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- Car Usages -->
+ <!-- Keep those lines only for car -->
+ <!-- Check car conditions if any OEM conditions matched -->
+ <!-- As defined by CarAudioAttributesUtil.java -->
+ <!-- product_strategy will be defined according this order
+ product_strategy is radio if all the conditions are satisfied for AudioAttributes aa
+
+ int type = CAR_AUDIO_TYPE_DEFAULT;
+ if (bundle != null) {
+ type = bundle.getInt(KEY_CAR_AUDIO_TYPE, CAR_AUDIO_TYPE_DEFAULT);
+ }
+ if(
+ ( aa.mContentType == AudioAttributes.AUDIO_CONTENT_TYPE_SPEECH ) &&
+ ( aa.mUsage == AudioAttributes.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE ) &&
+ ( type == CAR_AUDIO_TYPE_RADIO ) )
+ -->
+ <ProductStrategy name="radio">
+ <AttributesGroup volumeGroup="media_car_audio_type_3">
+ <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+ <Usage value="AUDIO_USAGE_MEDIA"/>
+ <Bundle key="car_audio_type" value="3"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="ext_audio_source">
+ <AttributesGroup volumeGroup="media_car_audio_type_7">
+ <ContentType value="AUDIO_CONTENT_TYPE_MUSIC"/>
+ <Usage value="AUDIO_USAGE_MEDIA"/>
+ <Bundle key="car_audio_type" value="7"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="voice_command">
+ <AttributesGroup volumeGroup="speech">
+ <Attributes>
+ <ContentType value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <!-- CAR_AUDIO_TYPE_VOICE_COMMAND = 1 -->
+ <Bundle key="car_audio_type" value="1"/>
+ </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_ASSISTANT"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="safety_alert">
+ <AttributesGroup volumeGroup="system">
+ <ContentType value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+ <Usage value="AUDIO_USAGE_NOTIFICATION"/>
+ <!-- CAR_AUDIO_TYPE_SAFETY_ALERT = 2 -->
+ <Bundle key="car_audio_type" value="2"/>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <!-- To be checked
+ CAR_AUDIO_TYPE_CARSERVICE_BOTTOM
+ CAR_AUDIO_TYPE_CARSERVICE_CAR_PROXY
+ CAR_AUDIO_TYPE_CARSERVICE_MEDIA_MUTE
+ -->
+
+ <!-- Generic Usages -->
+ <ProductStrategy name="music">
+ <AttributesGroup streamType="AUDIO_STREAM_MUSIC" volumeGroup="media">
+ <Attributes> <Usage value="AUDIO_USAGE_MEDIA"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_GAME"/> </Attributes>
+ <!-- Default product strategy has empty attributes -->
+ <Attributes></Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+
+ <ProductStrategy name="nav_guidance">
+ <AttributesGroup volumeGroup="speech">
+ <Usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="voice_call">
+ <AttributesGroup streamType="AUDIO_STREAM_VOICE_CALL" volumeGroup="phone">
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/> </Attributes>
+ </AttributesGroup>
+ <AttributesGroup streamType="AUDIO_STREAM_BLUETOOTH_SCO" volumeGroup="phone">
+ <Attributes> <Flags value="AUDIO_FLAG_SCO"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="alarm">
+ <AttributesGroup streamType="AUDIO_STREAM_ALARM" volumeGroup="ring">
+ <Usage value="AUDIO_USAGE_ALARM"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="ring">
+ <AttributesGroup streamType="AUDIO_STREAM_RING" volumeGroup="ring">
+ <Usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="notification">
+ <AttributesGroup streamType="AUDIO_STREAM_NOTIFICATION" volumeGroup="ring">
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/> </Attributes>
+ <Attributes> <Usage value="AUDIO_USAGE_NOTIFICATION_EVENT"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="system">
+ <AttributesGroup streamType="AUDIO_STREAM_SYSTEM" volumeGroup="system">
+ <Usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+ </AttributesGroup>
+ </ProductStrategy>
+ <ProductStrategy name="tts">
+ <!-- TTS stream MUST BE MANAGED OUTSIDE default product strategy if NO DEDICATED OUTPUT
+ for TTS, otherwise when beacon happens, default strategy is ... muted.
+ If it is media, it is annoying... -->
+ <AttributesGroup streamType="AUDIO_STREAM_TTS" volumeGroup="tts">
+ <Attributes> <Flags value="AUDIO_FLAG_BEACON"/> </Attributes>
+ </AttributesGroup>
+ </ProductStrategy>
+</ProductStrategies>
+
diff --git a/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml
new file mode 100644
index 0000000..9ec3d77
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/config/example/caremu/audio_policy_engine_volumes.xml
@@ -0,0 +1,192 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Copyright (C) 2018 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.
+ -->
+
+<!-- Volume Groups Tables included by Audio Policy Configuration file -->
+<!-- Note:
+ It is VALID to have a group without attributes if a product strategy is following
+ this group for all attributes.
+ Otherwise, attributes must be specified
+-->
+
+<volumeGroups>
+ <volumeGroup>
+ <name>oem_traffic_anouncement</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+
+<!-- OEM ADAS is a volume group that has a single port gain (this is the reason why it is a group
+ but may host different streams.
+ A priority must be given among them (either they are multualy excluisve, so the volume
+ will be the one of the currently acitve stream, otherwise a priority must be given by
+ any mean. -->
+ <volumeGroup>
+ <name>oem_adas_2</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_HEADSET">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+ <volumeGroup>
+ <name>oem_adas_3</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ <volume deviceCategory="DEVICE_CATEGORY_EARPIECE">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+
+<!-- MEDIA is a volume group that has a single port gain (this is the reason why it is a group
+ but may host different streams.
+ A priority must be given among them (either they are multualy exclusive, so the volume
+ will be the one of the active stream with highest priority (ORDER MATTERS) unless the curves
+ followed will the the curves for the requested attributes.-->
+ <volumeGroup>
+ <name>media_car_audio_type_3</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+ <volumeGroup>
+ <name>media_car_audio_type_7</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+ <volumeGroup>
+ <name>media</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-2400</point>
+ <point>33,-1600</point>
+ <point>66,-800</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+
+ <volumeGroup>
+ <name>speech</name>
+ <indexMin>1</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+
+ <volumeGroup>
+ <name>system</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+
+ <volumeGroup>
+ <name>phone</name>
+ <indexMin>1</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+
+ <volumeGroup>
+ <name>ring</name>
+ <indexMin>0</indexMin>
+ <indexMax>40</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-4200</point>
+ <point>33,-2800</point>
+ <point>66,-1400</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+
+ <volumeGroup>
+ <name>tts</name>
+ <indexMin>0</indexMin>
+ <indexMax>15</indexMax>
+ <volume deviceCategory="DEVICE_CATEGORY_SPEAKER">
+ <point>0,-0</point>
+ <point>100,0</point>
+ </volume>
+ </volumeGroup>
+</volumeGroups>
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index 060830b..782fe83 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -9,7 +9,7 @@
LOCAL_PATH := $(call my-dir)
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable no-output_configurable no-input_configurable))
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable no-output_configurable no-input_configurable))
PFW_CORE := external/parameter-framework
#@TODO: upstream new domain generator
@@ -20,6 +20,8 @@
TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+PROVISION_STRATEGIES_STRUCTURE := $(TOOLS)/provision_strategies_structure.mk
+
endif
##################################################################
@@ -27,7 +29,7 @@
##################################################################
######### Policy PFW top level file #########
-ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
include $(CLEAR_VARS)
LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
@@ -52,12 +54,27 @@
########## Policy PFW Common Structures #########
include $(CLEAR_VARS)
+LOCAL_MODULE := PolicySubsystem.xml
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_REQUIRED_MODULES := \
+ PolicySubsystem-CommonTypes.xml \
+ ProductStrategies.xml \
+ PolicySubsystem-Volume.xml \
+ libpolicy-subsystem \
+
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
LOCAL_MODULE := PolicySubsystem-CommonTypes.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
@@ -66,16 +83,29 @@
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE)
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
-endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := ProductStrategies.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_configuration.xml
+AUDIO_POLICY_ENGINE_CONFIGURATION_FILE := \
+ $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_configuration.xml
+STRATEGIES_STRUCTURE_FILE := $(LOCAL_PATH)/common/Structure/$(LOCAL_MODULE).in
+
+include $(PROVISION_STRATEGIES_STRUCTURE)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
########## Policy PFW Example Structures #########
ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem.xml.common
+LOCAL_MODULE := PolicySubsystem-no-strategy.xml
LOCAL_MODULE_STEM := PolicySubsystem.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
@@ -86,7 +116,7 @@
libpolicy-subsystem \
LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE_STEM)
include $(BUILD_PREBUILT)
endif # ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
@@ -95,7 +125,7 @@
ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable)
include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy.no-output
+LOCAL_MODULE := parameter-framework.policy
LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoOutputDevice.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
@@ -103,7 +133,7 @@
LOCAL_REQUIRED_MODULES := \
audio_policy_engine_criteria.xml \
audio_policy_engine_criterion_types.xml \
- PolicySubsystem.xml.common \
+ PolicySubsystem-no-strategy.xml \
PolicyClass.xml \
ParameterFrameworkConfigurationPolicy.xml
@@ -121,7 +151,7 @@
ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-input_configurable)
include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy.no-input
+LOCAL_MODULE := parameter-framework.policy
LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoInputDevice.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
@@ -129,7 +159,7 @@
LOCAL_REQUIRED_MODULES := \
audio_policy_engine_criteria.xml \
audio_policy_engine_criterion_types.xml \
- PolicySubsystem.xml.common \
+ PolicySubsystem-no-strategy.xml \
PolicyClass.xml \
ParameterFrameworkConfigurationPolicy.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
index ea4a58f..20ca8e2 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Android.mk
@@ -23,37 +23,9 @@
##################################################################
########## Policy PFW Structures #########
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem.xml.car
-LOCAL_MODULE_STEM := PolicySubsystem.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_REQUIRED_MODULES := \
- ProductStrategies.xml.car \
- PolicySubsystem-Volume.xml \
- PolicySubsystem-CommonTypes.xml \
- libpolicy-subsystem
-
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
-include $(BUILD_PREBUILT)
-
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ProductStrategies.xml.car
-LOCAL_MODULE_STEM := ProductStrategies.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
-include $(BUILD_PREBUILT)
-
######### Policy PFW Settings #########
include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy.car
+LOCAL_MODULE := parameter-framework.policy
LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
@@ -68,7 +40,7 @@
$(PFW_EDD_FILES)
LOCAL_REQUIRED_MODULES := \
- PolicySubsystem.xml.car \
+ PolicySubsystem.xml \
PolicyClass.xml \
audio_policy_engine_criteria.xml \
audio_policy_engine_criterion_types.xml \
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
index 196d82c..57ad592 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Settings/device_for_product_strategies.pfw
@@ -714,4 +714,47 @@
speaker = 0
bus = 0
+ supDomain: Tts
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/tts/device_address = BUS00_MEDIA
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+ bus = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml
deleted file mode 100644
index 53bba03..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/ProductStrategies.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
-
- <ComponentType Name="ProductStrategies" Description="">
- <Component Name="oem_traffic_anouncement" Type="ProductStrategy"/>
- <Component Name="oem_strategy_1" Type="ProductStrategy"/>
- <Component Name="oem_strategy_2" Type="ProductStrategy"/>
-
- <Component Name="radio" Type="ProductStrategy"/>
- <Component Name="ext_audio_source" Type="ProductStrategy"/>
- <Component Name="voice_command" Type="ProductStrategy"/>
- <Component Name="safety_alert" Type="ProductStrategy"/>
-
- <Component Name="music" Type="ProductStrategy"/>
- <Component Name="nav_guidance" Type="ProductStrategy"/>
- <Component Name="voice_call" Type="ProductStrategy"/>
- <Component Name="alarm" Type="ProductStrategy"/>
- <Component Name="ring" Type="ProductStrategy"/>
- <Component Name="notification" Type="ProductStrategy"/>
- <Component Name="system" Type="ProductStrategy"/>
- </ComponentType>
-
-</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk
new file mode 100644
index 0000000..8fa8f0a
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Android.mk
@@ -0,0 +1,58 @@
+################################################################################################
+#
+# @NOTE:
+# Audio Policy Engine configurable example for generic device build
+#
+# Any vendor shall have its own configuration within the corresponding device folder
+#
+################################################################################################
+
+ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
+LOCAL_PATH := $(call my-dir)
+
+PFW_CORE := external/parameter-framework
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
+BUILD_PFW_SETTINGS := $(TOOLS)/build_audio_pfw_settings.mk
+
+
+##################################################################
+# CONFIGURATION FILES
+##################################################################
+
+########## Policy PFW Structures #########
+######### Policy PFW Settings #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy
+LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+
+PFW_EDD_FILES := \
+ $(LOCAL_PATH)/Settings/device_for_product_strategies.pfw \
+ $(LOCAL_PATH)/../Settings/device_for_input_source.pfw \
+ $(LOCAL_PATH)/../Settings/volumes.pfw
+
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+ $(PFW_EDD_FILES)
+
+LOCAL_REQUIRED_MODULES := \
+ PolicySubsystem.xml \
+ PolicyClass.xml \
+ audio_policy_engine_criteria.xml \
+ audio_policy_engine_criterion_types.xml \
+ ParameterFrameworkConfigurationPolicy.xml
+
+PFW_CRITERION_TYPES_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criterion_types.xml
+PFW_CRITERIA_FILE := $(TARGET_OUT_VENDOR_ETC)/audio_policy_engine_criteria.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_VENDOR_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+
+PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
+
+include $(BUILD_PFW_SETTINGS)
+
+endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), caremu_configurable)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Settings/device_for_product_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Settings/device_for_product_strategies.pfw
new file mode 100644
index 0000000..ca3464f
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/CarEmu/Settings/device_for_product_strategies.pfw
@@ -0,0 +1,690 @@
+supDomain: DeviceForProductStrategies
+ supDomain: OemTrafficAnouncement
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/oem_traffic_anouncement/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/oem_traffic_anouncement/selected_output_devices/mask
+ bus = 0
+
+ supDomain: OemStrategy1
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/oem_strategy_1/device_address = BUS02_OEM1
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS02_OEM1
+
+ component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/oem_strategy_1/selected_output_devices/mask
+ bus = 0
+
+
+
+ supDomain: OemStrategy2
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/oem_strategy_2/device_address = BUS01_NAV_GUIDANCE
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS01_NAV_GUIDANCE
+
+ component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/oem_strategy_2/selected_output_devices/mask
+ bus = 0
+
+
+
+ supDomain: Radio
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/radio/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/radio/selected_output_devices/mask
+ bus = 0
+
+ supDomain: ExtAudioSource
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/ext_audio_source/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/ext_audio_source/selected_output_devices/mask
+ bus = 0
+
+
+
+ supDomain: VoiceCommand
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/voice_command/device_address = BUS04_VOICE
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS04_VOICE
+
+ component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/voice_command/selected_output_devices/mask
+ bus = 0
+
+
+ supDomain: SafetyAlert
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/safety_alert/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/safety_alert/selected_output_devices/mask
+ bus = 0
+
+
+ supDomain: Music
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/music/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/music/selected_output_devices/mask
+ bus = 0
+
+
+
+ supDomain: NavGuidance
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/nav_guidance/device_address = BUS01_NAV_GUIDANCE
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS01_NAV_GUIDANCE
+
+ component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/nav_guidance/selected_output_devices/mask
+ bus = 0
+
+
+ supDomain: VoiceCall
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/voice_call/device_address = BUS04_VOICE
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS04_VOICE
+
+ component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/voice_call/selected_output_devices/mask
+ bus = 0
+
+
+ supDomain: Alarm
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/alarm/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/alarm/selected_output_devices/mask
+ bus = 0
+
+
+ supDomain: Ring
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/ring/device_address = BUS04_VOICE
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS04_VOICE
+
+ component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/ring/selected_output_devices/mask
+ bus = 0
+
+
+ supDomain: Notification
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/notification/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/notification/selected_output_devices/mask
+ bus = 0
+
+
+ supDomain: System
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/system/device_address = BUS03_SYSTEM_SOUND
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS03_SYSTEM_SOUND
+
+ component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/system/selected_output_devices/mask
+ bus = 0
+
+ supDomain: Tts
+ domain: UnreachableDevices
+ conf: calibration
+ component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+ earpiece = 0
+ speaker = 0
+ wired_headset = 0
+ wired_headphone = 0
+ bluetooth_sco = 0
+ bluetooth_sco_headset = 0
+ bluetooth_sco_carkit = 0
+ bluetooth_a2dp = 0
+ bluetooth_a2dp_headphones = 0
+ bluetooth_a2dp_speaker = 0
+ hdmi = 0
+ angl_dock_headset = 0
+ dgtl_dock_headset = 0
+ usb_accessory = 0
+ usb_device = 0
+ remote_submix = 0
+ telephony_tx = 0
+ line = 0
+ hdmi_arc = 0
+ spdif = 0
+ fm = 0
+ aux_line = 0
+ speaker_safe = 0
+ ip = 0
+ proxy = 0
+ usb_headset = 0
+ stub = 0
+ /Policy/policy/product_strategies/tts/device_address = BUS00_MEDIA
+
+ domain: SelectedDevice
+ conf: Bus
+ AvailableOutputDevices Includes Bus
+ AvailableOutputDevicesAddresses Includes BUS00_MEDIA
+
+ component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+ bus = 1
+
+ conf: Default
+ component: /Policy/policy/product_strategies/tts/selected_output_devices/mask
+ bus = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
index e9d67e9..d1845b8 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Android.mk
@@ -22,37 +22,9 @@
# CONFIGURATION FILES
##################################################################
########## Policy PFW Structures #########
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem.xml.phone
-LOCAL_MODULE_STEM := PolicySubsystem.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_REQUIRED_MODULES := \
- PolicySubsystem-CommonTypes.xml \
- ProductStrategies.xml.phone \
- PolicySubsystem-Volume.xml \
- libpolicy-subsystem \
-
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
-include $(BUILD_PREBUILT)
-
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := ProductStrategies.xml.phone
-LOCAL_MODULE_STEM := ProductStrategies.xml
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := ETC
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := Structure/$(LOCAL_MODULE_STEM)
-include $(BUILD_PREBUILT)
-
######### Policy PFW Settings #########
include $(CLEAR_VARS)
-LOCAL_MODULE := parameter-framework.policy.phone
+LOCAL_MODULE := parameter-framework.policy
LOCAL_MODULE_STEM := PolicyConfigurableDomains.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
@@ -68,15 +40,15 @@
$(LOCAL_PATH)/Settings/device_for_product_strategy_phone.pfw \
$(LOCAL_PATH)/Settings/device_for_product_strategy_sonification.pfw \
$(LOCAL_PATH)/Settings/device_for_product_strategy_sonification_respectful.pfw \
- $(LOCAL_PATH)/Settings/device_for_product_strategy_rerouting.pfw \
$(LOCAL_PATH)/Settings/device_for_product_strategy_transmitted_through_speaker.pfw \
- $(LOCAL_PATH)/Settings/device_for_product_strategy_unknown.pfw
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_rerouting.pfw \
+ $(LOCAL_PATH)/Settings/device_for_product_strategy_patch.pfw
LOCAL_ADDITIONAL_DEPENDENCIES := \
$(PFW_EDD_FILES)
LOCAL_REQUIRED_MODULES := \
- PolicySubsystem.xml.phone \
+ PolicySubsystem.xml \
PolicyClass.xml \
audio_policy_engine_criteria.xml \
audio_policy_engine_criterion_types.xml \
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_patch.pfw
similarity index 79%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_patch.pfw
index c46cf56..d2cc090 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_unknown.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_patch.pfw
@@ -1,8 +1,8 @@
supDomain: DeviceForProductStrategy
- supDomain: Unknown
+ supDomain: Patch
domain: UnreachableDevices
conf: calibration
- component: /Policy/policy/product_strategies/unknown/selected_output_devices/mask
+ component: /Policy/policy/product_strategies/patch/selected_output_devices/mask
earpiece = 0
speaker = 0
wired_headset = 0
@@ -31,6 +31,6 @@
usb_headset = 0
bus = 0
stub = 0
- /Policy/policy/product_strategies/unknown/device_address =
+ /Policy/policy/product_strategies/patch/device_address =
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
index c064c18..10f8814 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Settings/device_for_product_strategy_rerouting.pfw
@@ -29,15 +29,8 @@
ip = 0
proxy = 0
usb_headset = 0
+ bus = 0
stub = 0
/Policy/policy/product_strategies/rerouting/device_address =
- domain: SelectedDevice
- conf: Bus
- component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
- bus = 1
-
- conf: Default
- component: /Policy/policy/product_strategies/rerouting/selected_output_devices/mask
- bus = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml
deleted file mode 100644
index b55ce2c..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/PolicySubsystem.xml
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
- Name="policy" Type="Policy">
-
- <ComponentLibrary>
- <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
- <!-- Common Types defintion -->
- <xi:include href="PolicySubsystem-CommonTypes.xml"/>
- <xi:include href="ProductStrategies.xml"/>
-
-
- <!--#################### GLOBAL COMPONENTS END ####################-->
-
- <!--#################### STREAM BEGIN ####################-->
-
- <ComponentType Name="Streams" Description="associated to audio_stream_type_t definition">
- <Component Name="voice_call" Type="Stream" Mapping="Name:AUDIO_STREAM_VOICE_CALL"/>
- <Component Name="system" Type="Stream" Mapping="Name:AUDIO_STREAM_SYSTEM"/>
- <Component Name="ring" Type="Stream" Mapping="Name:AUDIO_STREAM_RING"/>
- <Component Name="music" Type="Stream" Mapping="Name:AUDIO_STREAM_MUSIC"/>
- <Component Name="alarm" Type="Stream" Mapping="Name:AUDIO_STREAM_ALARM"/>
- <Component Name="notification" Type="Stream" Mapping="Name:AUDIO_STREAM_NOTIFICATION"/>
- <Component Name="bluetooth_sco" Type="Stream" Mapping="Name:AUDIO_STREAM_BLUETOOTH_SCO"/>
- <Component Name="enforced_audible" Type="Stream" Mapping="Name:AUDIO_STREAM_ENFORCED_AUDIBLE"
- Description="Sounds that cannot be muted by user and must be routed to speaker"/>
- <Component Name="dtmf" Type="Stream" Mapping="Name:AUDIO_STREAM_DTMF"/>
- <Component Name="tts" Type="Stream" Mapping="Name:AUDIO_STREAM_TTS"
- Description="Transmitted Through Speaker. Plays over speaker only, silent on other devices"/>
- <Component Name="accessibility" Type="Stream" Mapping="Name:AUDIO_STREAM_ACCESSIBILITY"
- Description="For accessibility talk back prompts"/>
- <Component Name="rerouting" Type="Stream" Mapping="Name:AUDIO_STREAM_REROUTING"
- Description="For dynamic policy output mixes"/>
- <Component Name="patch" Type="Stream" Mapping="Name:AUDIO_STREAM_PATCH"
- Description="For internal audio flinger tracks. Fixed volume"/>
- </ComponentType>
-
- <!--#################### STREAM END ####################-->
-
- <!--#################### INPUT SOURCE BEGIN ####################-->
-
- <ComponentType Name="InputSources" Description="associated to audio_source_t definition,
- identifier mapping must match the value of the enum">
- <Component Name="default" Type="InputSource" Mapping="Name:AUDIO_SOURCE_DEFAULT"/>
- <Component Name="mic" Type="InputSource" Mapping="Name:AUDIO_SOURCE_MIC"/>
- <Component Name="voice_uplink" Type="InputSource"
- Mapping="Name:AUDIO_SOURCE_VOICE_UPLINK"/>
- <Component Name="voice_downlink" Type="InputSource"
- Mapping="Name:AUDIO_SOURCE_VOICE_DOWNLINK"/>
- <Component Name="voice_call" Type="InputSource"
- Mapping="Name:AUDIO_SOURCE_VOICE_CALL"/>
- <Component Name="camcorder" Type="InputSource" Mapping="Name:AUDIO_SOURCE_CAMCORDER"/>
- <Component Name="voice_recognition" Type="InputSource"
- Mapping="Name:AUDIO_SOURCE_VOICE_RECOGNITION"/>
- <Component Name="voice_communication" Type="InputSource"
- Mapping="Name:AUDIO_SOURCE_VOICE_COMMUNICATION"/>
- <Component Name="remote_submix" Type="InputSource"
- Mapping="Name:AUDIO_SOURCE_REMOTE_SUBMIX"/>
- <Component Name="unprocessed" Type="InputSource"
- Mapping="Name:AUDIO_SOURCE_UNPROCESSED"/>
- <Component Name="fm_tuner" Type="InputSource" Mapping="Name:AUDIO_SOURCE_FM_TUNER"/>
- <Component Name="hotword" Type="InputSource" Mapping="Name:AUDIO_SOURCE_HOTWORD"/>
- </ComponentType>
-
- <!--#################### INPUT SOURCE END ####################-->
- </ComponentLibrary>
-
- <InstanceDefinition>
- <Component Name="streams" Type="Streams"/>
- <Component Name="input_sources" Type="InputSources"/>
- <Component Name="product_strategies" Type="ProductStrategies"/>
- </InstanceDefinition>
-</Subsystem>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml
deleted file mode 100644
index 4cbb3da..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Phone/Structure/ProductStrategies.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
-
- <ComponentType Name="ProductStrategies" Description="">
- <Component Name="accessibility" Type="ProductStrategy"/>
- <Component Name="enforced_audible" Type="ProductStrategy"/>
- <Component Name="transmitted_through_speaker" Type="ProductStrategy"/>
-
- <Component Name="media" Type="ProductStrategy"/>
- <Component Name="phone" Type="ProductStrategy"/>
- <Component Name="dtmf" Type="ProductStrategy"/>
-
- <Component Name="sonification" Type="ProductStrategy"/>
- <Component Name="sonification_respectful" Type="ProductStrategy"/>
- <Component Name="rerouting" Type="ProductStrategy"/>
- <Component Name="unknown" Type="ProductStrategy"/>
- </ComponentType>
-
-</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicyClass.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicyClass.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicyClass.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicyClass.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-CommonTypes.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-CommonTypes.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-no-strategy.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem-no-strategy.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/examples/Car/Structure/PolicySubsystem.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/PolicySubsystem.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/ProductStrategies.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/ProductStrategies.xml.in
new file mode 100644
index 0000000..2760b25
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/common/Structure/ProductStrategies.xml.in
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<ComponentTypeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xsi:noNamespaceSchemaLocation="Schemas/ComponentTypeSet.xsd">
+
+ <!-- automatically populate the strategy structure plugin file from Engine Configuration XML file
+ Component Name="xxx" Type="ProductStrategy"/-->
+ <ComponentType Name="ProductStrategies" Description="">
+ </ComponentType>
+
+</ComponentTypeSet>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
index 65dc9af..4706d7d 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
@@ -36,7 +36,9 @@
LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-LOCAL_STATIC_LIBRARIES := libpfw_utility
+LOCAL_STATIC_LIBRARIES := \
+ libpfw_utility \
+ libaudiopolicycomponents
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libpolicy-subsystem
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
index bfc1bca..8bd7f66 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
@@ -72,7 +72,7 @@
);
addSubsystemObjectFactory(
new TSubsystemObjectFactory<ProductStrategy>(
- mProductStrategyComponentName, 0)
+ mProductStrategyComponentName, (1 << MappingKeyName))
);
}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
index bb29ef1..ebd9456 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/ProductStrategy.cpp
@@ -32,6 +32,8 @@
(MappingKeyAmendEnd - MappingKeyAmend1 + 1),
context)
{
+ std::string name(context.getItem(MappingKeyName));
+
ALOG_ASSERT(instanceConfigurableElement != nullptr, "Invalid Configurable Element");
mPolicySubsystem = static_cast<const PolicySubsystem *>(
instanceConfigurableElement->getBelongingSubsystem());
@@ -40,7 +42,6 @@
mPolicyPluginInterface = mPolicySubsystem->getPolicyPluginInterface();
ALOG_ASSERT(mPolicyPluginInterface != nullptr, "Invalid Policy Plugin Interface");
- std::string name(instanceConfigurableElement->getName());
mId = mPolicyPluginInterface->getProductStrategyByName(name);
ALOG_ASSERT(mId != PRODUCT_STRATEGY_INVALID, "Product Strategy %s not found", name.c_str());
diff --git a/services/audiopolicy/engineconfigurable/tools/Android.bp b/services/audiopolicy/engineconfigurable/tools/Android.bp
index d8f29dc..8c16972 100644
--- a/services/audiopolicy/engineconfigurable/tools/Android.bp
+++ b/services/audiopolicy/engineconfigurable/tools/Android.bp
@@ -12,13 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-python_binary_host {
- name: "buildPolicyCriterionTypes.py",
- owner: "renault",
- main: "buildPolicyCriterionTypes.py",
- srcs: [
- "buildPolicyCriterionTypes.py",
- ],
+python_defaults {
+ name: "tools_default",
version: {
py2: {
enabled: true,
@@ -29,3 +24,37 @@
},
}
+python_binary_host {
+ name: "buildPolicyCriterionTypes.py",
+ main: "buildPolicyCriterionTypes.py",
+ srcs: [
+ "buildPolicyCriterionTypes.py",
+ ],
+ defaults: ["tools_default"],
+}
+
+python_binary_host {
+ name: "domainGeneratorPolicy.py",
+ main: "domainGeneratorPolicy.py",
+ srcs: [
+ "domainGeneratorPolicy.py",
+ ],
+ defaults: ["tools_default"],
+ libs: [
+ "EddParser.py",
+ "hostConfig.py",
+ "PFWScriptGenerator.py",
+ ],
+ required: [
+ "domainGeneratorConnector",
+ ],
+}
+
+python_binary_host {
+ name: "buildStrategiesStructureFile.py",
+ main: "buildStrategiesStructureFile.py",
+ srcs: [
+ "buildStrategiesStructureFile.py",
+ ],
+ defaults: ["tools_default"],
+}
diff --git a/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py b/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py
new file mode 100755
index 0000000..ee70b26
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/buildStrategiesStructureFile.py
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+
+#
+# Copyright 2019, 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.
+#
+
+import argparse
+import re
+import sys
+import tempfile
+import os
+import logging
+import subprocess
+import xml.etree.ElementTree as ET
+import xml.etree.ElementInclude as EI
+import xml.dom.minidom as MINIDOM
+from collections import OrderedDict
+
+#
+# Helper script that helps to feed at build time the XML Product Strategies Structure file file used
+# by the engineconfigurable to start the parameter-framework.
+# It prevents to fill them manually and avoid divergences with android.
+#
+# The Product Strategies Structure file is fed from the audio policy engine configuration file
+# in order to discover all the strategies available for the current platform.
+# --audiopolicyengineconfigurationfile <path/to/audio_policy_engine_configuration.xml>
+#
+# The reference file of ProductStrategies structure must also be set as an input of the script:
+# --productstrategiesstructurefile <path/to/structure/file/ProductStrategies.xml.in>
+#
+# At last, the output of the script shall be set also:
+# --outputfile <path/to/out/<system|vendor|odm>/etc/ProductStrategies.xml>
+#
+
+def parseArgs():
+ argparser = argparse.ArgumentParser(description="Parameter-Framework XML \
+ product strategies structure file generator.\n\
+ Exit with the number of (recoverable or not) error that occured.")
+ argparser.add_argument('--audiopolicyengineconfigurationfile',
+ help="Android Audio Policy Engine Configuration file, Mandatory.",
+ metavar="(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)",
+ type=argparse.FileType('r'),
+ required=True)
+ argparser.add_argument('--productstrategiesstructurefile',
+ help="Product Strategies Structure XML base file, Mandatory.",
+ metavar="STRATEGIES_STRUCTURE_FILE",
+ type=argparse.FileType('r'),
+ required=True)
+ argparser.add_argument('--outputfile',
+ help="Product Strategies Structure output file, Mandatory.",
+ metavar="STRATEGIES_STRUCTURE_OUTPUT_FILE",
+ type=argparse.FileType('w'),
+ required=True)
+ argparser.add_argument('--verbose',
+ action='store_true')
+
+ return argparser.parse_args()
+
+
+def generateXmlStructureFile(strategies, strategyStructureInFile, outputFile):
+
+ logging.info("Importing strategyStructureInFile {}".format(strategyStructureInFile))
+ strategies_in_tree = ET.parse(strategyStructureInFile)
+
+ strategies_root = strategies_in_tree.getroot()
+ strategy_components = strategies_root.find('ComponentType')
+
+ for strategy_name in strategies:
+ context_mapping = "".join(map(str, ["Name:", strategy_name]))
+ strategy_pfw_name = strategy_name.replace('STRATEGY_', '').lower()
+ strategy_component_node = ET.SubElement(strategy_components, "Component", Name=strategy_pfw_name, Type="ProductStrategy", Mapping=context_mapping)
+
+ xmlstr = ET.tostring(strategies_root, encoding='utf8', method='xml')
+ reparsed = MINIDOM.parseString(xmlstr)
+ prettyXmlStr = reparsed.toprettyxml(newl='\r\n')
+ prettyXmlStr = os.linesep.join([s for s in prettyXmlStr.splitlines() if s.strip()])
+ outputFile.write(prettyXmlStr.encode('utf-8'))
+
+def capitalizeLine(line):
+ return ' '.join((w.capitalize() for w in line.split(' ')))
+
+
+#
+# Parse the audio policy configuration file and output a dictionary of device criteria addresses
+#
+def parseAndroidAudioPolicyEngineConfigurationFile(audiopolicyengineconfigurationfile):
+
+ logging.info("Checking Audio Policy Engine Configuration file {}".format(audiopolicyengineconfigurationfile))
+ #
+ # extract all product strategies name from audio policy engine configuration file
+ #
+ strategy_names = []
+
+ oldWorkingDir = os.getcwd()
+ print "Current working directory %s" % oldWorkingDir
+
+ newDir = os.path.join(oldWorkingDir , audiopolicyengineconfigurationfile.name)
+
+ policy_engine_in_tree = ET.parse(audiopolicyengineconfigurationfile)
+ os.chdir(os.path.dirname(os.path.normpath(newDir)))
+
+ print "new working directory %s" % os.getcwd()
+
+ policy_engine_root = policy_engine_in_tree.getroot()
+ EI.include(policy_engine_root)
+
+ os.chdir(oldWorkingDir)
+
+ for strategy in policy_engine_root.iter('ProductStrategy'):
+ strategy_names.append(strategy.get('name'))
+
+ return strategy_names
+
+
+def main():
+ logging.root.setLevel(logging.INFO)
+ args = parseArgs()
+
+ strategies = parseAndroidAudioPolicyEngineConfigurationFile(args.audiopolicyengineconfigurationfile)
+
+ product_strategies_structure = args.productstrategiesstructurefile
+
+ generateXmlStructureFile(strategies, product_strategies_structure, args.outputfile)
+
+# If this file is directly executed
+if __name__ == "__main__":
+ exit(main())
diff --git a/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk b/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk
new file mode 100644
index 0000000..72c938c
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/tools/provision_strategies_structure.mk
@@ -0,0 +1,21 @@
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): MY_STRATEGIES_STRUCTURE_FILE := $(STRATEGIES_STRUCTURE_FILE)
+$(LOCAL_BUILT_MODULE): MY_AUDIO_POLICY_ENGINE_CONFIGURATION_FILE := $(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)
+$(LOCAL_BUILT_MODULE): MY_PROVISION_TOOL := $(HOST_OUT)/bin/buildStrategiesStructureFile.py
+$(LOCAL_BUILT_MODULE): $(LOCAL_REQUIRED_MODULES) $(LOCAL_ADDITIONAL_DEPENDENCIES) \
+ buildStrategiesStructureFile.py \
+ $(STRATEGIES_STRUCTURE_FILE) \
+ $(AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)
+
+ "$(MY_PROVISION_TOOL)" \
+ --audiopolicyengineconfigurationfile "$(MY_AUDIO_POLICY_ENGINE_CONFIGURATION_FILE)" \
+ --productstrategiesstructurefile "$(MY_STRATEGIES_STRUCTURE_FILE)" \
+ --outputfile "$(@)"
+
+# Clear variables for further use
+STRATEGIES_STRUCTURE_FILE :=
+AUDIO_POLICY_ENGINE_CONFIGURATION_FILE :=
diff --git a/services/audiopolicy/enginedefault/config/example/Android.mk b/services/audiopolicy/enginedefault/config/example/Android.mk
index f06ee4c..0badac8 100644
--- a/services/audiopolicy/enginedefault/config/example/Android.mk
+++ b/services/audiopolicy/enginedefault/config/example/Android.mk
@@ -7,28 +7,26 @@
ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION), phone_default)
include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_configuration_phone.xml
-LOCAL_MODULE_STEM := audio_policy_engine_configuration.xml
+LOCAL_MODULE := audio_policy_engine_configuration.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
LOCAL_REQUIRED_MODULES := \
- audio_policy_engine_product_strategies_phone.xml \
+ audio_policy_engine_product_strategies.xml \
audio_policy_engine_stream_volumes.xml \
audio_policy_engine_default_stream_volumes.xml
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
-LOCAL_MODULE := audio_policy_engine_product_strategies_phone.xml
-LOCAL_MODULE_STEM := audio_policy_engine_product_strategies.xml
+LOCAL_MODULE := audio_policy_engine_product_strategies.xml
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_VENDOR_MODULE := true
-LOCAL_SRC_FILES := phone/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := phone/$(LOCAL_MODULE)
include $(BUILD_PREBUILT)
include $(CLEAR_VARS)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 938445b..4a0e764 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1085,7 +1085,7 @@
new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
sanitizedRequestedPortId, *stream,
mEngine->getProductStrategyForAttributes(resultAttr),
- streamToVolumeSource(*stream),
+ toVolumeSource(resultAttr),
*flags, isRequestedDeviceForExclusiveUse,
std::move(weakSecondaryOutputDescs));
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
@@ -1694,8 +1694,9 @@
setOutputDevices(outputDesc, devices, force, 0, NULL, requiresMuteCheck);
// apply volume rules for current stream and device if necessary
- checkAndSetVolume(stream,
- getVolumeCurves(stream).getVolumeIndex(outputDesc->devices().types()),
+ auto &curves = getVolumeCurves(client->attributes());
+ checkAndSetVolume(curves, client->volumeSource(),
+ curves.getVolumeIndex(outputDesc->devices().types()),
outputDesc,
outputDesc->devices().types());
@@ -2387,107 +2388,27 @@
int index,
audio_devices_t device)
{
- auto &curves = getVolumeCurves(stream);
- // VOICE_CALL and BLUETOOTH_SCO stream have minVolumeIndex > 0 but
- // can be muted directly by an app that has MODIFY_PHONE_STATE permission.
- if (((index < curves.getVolumeIndexMin()) &&
- !((stream == AUDIO_STREAM_VOICE_CALL || stream == AUDIO_STREAM_BLUETOOTH_SCO) &&
- index == 0)) ||
- (index > curves.getVolumeIndexMax())) {
+ auto attributes = mEngine->getAttributesForStreamType(stream);
+ auto volumeGroup = mEngine->getVolumeGroupForStreamType(stream);
+ if (volumeGroup == VOLUME_GROUP_NONE) {
+ ALOGE("%s: no group matching with stream %s", __FUNCTION__, toString(stream).c_str());
return BAD_VALUE;
}
- if (!audio_is_output_device(device)) {
- return BAD_VALUE;
- }
-
- // Force max volume if stream cannot be muted
- if (!curves.canBeMuted()) index = curves.getVolumeIndexMax();
-
- ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
- stream, device, index);
-
- // update other private stream volumes which follow this one
- for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
- if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
- continue;
- }
- auto &curCurves = getVolumeCurves(static_cast<audio_stream_type_t>(curStream));
- curCurves.addCurrentVolumeIndex(device, index);
- }
-
- // update volume on all outputs and streams matching the following:
- // - The requested stream (or a stream matching for volume control) is active on the output
- // - The device (or devices) selected by the engine for this stream includes
- // the requested device
- // - For non default requested device, currently selected device on the output is either the
- // requested device or one of the devices selected by the engine for this stream
- // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
- // no specific device volume value exists for currently selected device.
- status_t status = NO_ERROR;
- for (size_t i = 0; i < mOutputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- audio_devices_t curDevice = desc->devices().types();
- for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
- if (!(streamsMatchForvolume(stream, (audio_stream_type_t)curStream))) {
- continue;
- }
- if (!(desc->isActive(streamToVolumeSource((audio_stream_type_t)curStream)) || isInCall())) {
- continue;
- }
- audio_devices_t curStreamDevice = Volume::getDeviceForVolume(
- mEngine->getOutputDevicesForStream((audio_stream_type_t)curStream,
- false /*fromCache*/).types());
- if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
- ((curStreamDevice & device) == 0)) {
- continue;
- }
- bool applyVolume;
- if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
- curStreamDevice |= device;
- applyVolume = (Volume::getDeviceForVolume(curDevice) & curStreamDevice) != 0;
- } else {
- applyVolume = !curves.hasVolumeIndexForDevice(curStreamDevice);
- }
- // rescale index before applying to curStream as ranges may be different for
- // stream and curStream
- int idx = rescaleVolumeIndex(index, stream, (audio_stream_type_t)curStream);
- if (applyVolume) {
- //FIXME: workaround for truncated touch sounds
- // delayed volume change for system stream to be removed when the problem is
- // handled by system UI
- status_t volStatus = checkAndSetVolume(
- (audio_stream_type_t)curStream, idx, desc, curDevice,
- (stream == AUDIO_STREAM_SYSTEM) ?
- TOUCH_SOUND_FIXED_DELAY_MS : 0);
- if (volStatus != NO_ERROR) {
- status = volStatus;
- }
- }
- }
- }
- return status;
+ ALOGV("%s: stream %s attributes=%s", __func__,
+ toString(stream).c_str(), toString(attributes).c_str());
+ return setVolumeGroupIndex(getVolumeCurves(stream), volumeGroup, index, device, attributes);
}
status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
- int *index,
- audio_devices_t device)
+ int *index,
+ audio_devices_t device)
{
- if (index == NULL) {
- return BAD_VALUE;
- }
- if (!audio_is_output_device(device)) {
- return BAD_VALUE;
- }
// if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device selected for this
// stream by the engine.
if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
device = mEngine->getOutputDevicesForStream(stream, true /*fromCache*/).types();
}
- device = Volume::getDeviceForVolume(device);
-
- *index = getVolumeCurves(stream).getVolumeIndex(device);
- ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
- return NO_ERROR;
+ return getVolumeIndex(getVolumeCurves(stream), *index, device);
}
status_t AudioPolicyManager::setVolumeIndexForAttributes(const audio_attributes_t &attr,
@@ -2500,18 +2421,25 @@
ALOGD("%s: could not find group matching with %s", __FUNCTION__, toString(attr).c_str());
return BAD_VALUE;
}
- ALOGD("%s: FOUND group %d matching with %s", __FUNCTION__, volumeGroup, toString(attr).c_str());
+ ALOGV("%s: group %d matching with %s", __FUNCTION__, volumeGroup, toString(attr).c_str());
return setVolumeGroupIndex(getVolumeCurves(attr), volumeGroup, index, device, attr);
}
status_t AudioPolicyManager::setVolumeGroupIndex(IVolumeCurves &curves, volume_group_t group,
int index,
audio_devices_t device,
- const audio_attributes_t /*attributes*/)
+ const audio_attributes_t attributes)
{
ALOGVV("%s: group=%d", __func__, group);
status_t status = NO_ERROR;
- setVolumeCurveIndex(group, index, device, curves);
+ VolumeSource vs = toVolumeSource(group);
+ product_strategy_t strategy = mEngine->getProductStrategyForAttributes(attributes);
+
+ status = setVolumeCurveIndex(index, device, curves);
+ if (status != NO_ERROR) {
+ ALOGE("%s failed to set curve index for group %d device 0x%X", __func__, group, device);
+ return status;
+ }
// update volume on all outputs and streams matching the following:
// - The requested stream (or a stream matching for volume control) is active on the output
// - The device (or devices) selected by the engine for this stream includes
@@ -2520,21 +2448,116 @@
// requested device or one of the devices selected by the engine for this stream
// - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
// no specific device volume value exists for currently selected device.
- // @TODO
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ audio_devices_t curDevice = Volume::getDeviceForVolume(desc->devices().types());
+
+ // Inter / intra volume group priority management: Loop on strategies arranged by priority
+ // If a higher priority strategy is active, and the output is routed to a device with a
+ // HW Gain management, do not change the volume
+ bool applyVolume = false;
+ if (desc->useHwGain()) {
+ if (!(desc->isActive(group) || isInCall())) {
+ continue;
+ }
+ for (const auto &productStrategy : mEngine->getOrderedProductStrategies()) {
+ auto activeClients = desc->clientsList(true /*activeOnly*/, productStrategy,
+ false /*preferredDevice*/);
+ if (activeClients.empty()) {
+ continue;
+ }
+ bool isPreempted = false;
+ bool isHigherPriority = productStrategy < strategy;
+ for (const auto &client : activeClients) {
+ if (isHigherPriority && (client->volumeSource() != vs)) {
+ ALOGV("%s: Strategy=%d (\nrequester:\n"
+ " group %d, volumeGroup=%d attributes=%s)\n"
+ " higher priority source active:\n"
+ " volumeGroup=%d attributes=%s) \n"
+ " on output %zu, bailing out", __func__, productStrategy,
+ group, group, toString(attributes).c_str(),
+ client->volumeSource(), toString(client->attributes()).c_str(), i);
+ applyVolume = false;
+ isPreempted = true;
+ break;
+ }
+ // However, continue for loop to ensure no higher prio clients running on output
+ if (client->volumeSource() == vs) {
+ applyVolume = true;
+ }
+ }
+ if (isPreempted || applyVolume) {
+ break;
+ }
+ }
+ if (!applyVolume) {
+ continue; // next output
+ }
+ status_t volStatus = checkAndSetVolume(curves, vs, index, desc, curDevice,
+ (vs == toVolumeSource(AUDIO_STREAM_SYSTEM)?
+ TOUCH_SOUND_FIXED_DELAY_MS : 0));
+ if (volStatus != NO_ERROR) {
+ status = volStatus;
+ }
+ continue;
+ }
+ for (auto curVolGroup : getVolumeGroups()) {
+ VolumeSource curVolSrc = toVolumeSource(curVolGroup);
+ if (!(curVolSrc == vs || isInCall())) {
+ continue;
+ }
+ if (!(desc->isActive(vs) || isInCall())) {
+ continue;
+ }
+ audio_devices_t curSrcDevice;
+ auto &curCurves = getVolumeCurves(curVolSrc);
+ auto curCurvAttrs = curCurves.getAttributes();
+ if (!curCurvAttrs.empty() && curCurvAttrs.front() != defaultAttr) {
+ auto attr = curCurvAttrs.front();
+ curSrcDevice = mEngine->getOutputDevicesForAttributes(attr, nullptr, false).types();
+ } else if (!curCurves.getStreamTypes().empty()) {
+ auto stream = curCurves.getStreamTypes().front();
+ curSrcDevice = mEngine->getOutputDevicesForStream(stream, false).types();
+ } else {
+ ALOGE("%s: Invalid src %d: no valid attributes nor stream",__func__, curVolSrc);
+ continue;
+ }
+ curSrcDevice = Volume::getDeviceForVolume(curSrcDevice);
+ if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) && ((curDevice & device) == 0)) {
+ continue;
+ }
+ if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
+ curSrcDevice |= device;
+ applyVolume = (curDevice & curSrcDevice) != 0;
+ } else {
+ applyVolume = !curves.hasVolumeIndexForDevice(curSrcDevice);
+ }
+ if (applyVolume) {
+ //FIXME: workaround for truncated touch sounds
+ // delayed volume change for system stream to be removed when the problem is
+ // handled by system UI
+ status_t volStatus = checkAndSetVolume(
+ curCurves, curVolSrc, index, desc, curDevice,
+ ((vs == toVolumeSource(AUDIO_STREAM_SYSTEM))?
+ TOUCH_SOUND_FIXED_DELAY_MS : 0));
+ if (volStatus != NO_ERROR) {
+ status = volStatus;
+ }
+ }
+ }
+ }
mpClientInterface->onAudioVolumeGroupChanged(group, 0 /*flags*/);
return status;
}
-status_t AudioPolicyManager::setVolumeCurveIndex(volume_group_t volumeGroup,
- int index,
+status_t AudioPolicyManager::setVolumeCurveIndex(int index,
audio_devices_t device,
IVolumeCurves &volumeCurves)
{
// VOICE_CALL stream has minVolumeIndex > 0 but can be muted directly by an
// app that has MODIFY_PHONE_STATE permission.
- // If voice is member of the volume group, it will contaminate all the member of this group
- auto streams = mEngine->getStreamTypesForVolumeGroup(volumeGroup);
- if (((index < volumeCurves.getVolumeIndexMin()) && !(hasVoiceStream(streams) && index == 0)) ||
+ bool hasVoice = hasVoiceStream(volumeCurves.getStreamTypes());
+ if (((index < volumeCurves.getVolumeIndexMin()) && !(hasVoice && index == 0)) ||
(index > volumeCurves.getVolumeIndexMax())) {
ALOGD("%s: wrong index %d min=%d max=%d", __FUNCTION__, index,
volumeCurves.getVolumeIndexMin(), volumeCurves.getVolumeIndexMax());
@@ -2547,7 +2570,7 @@
// Force max volume if stream cannot be muted
if (!volumeCurves.canBeMuted()) index = volumeCurves.getVolumeIndexMax();
- ALOGD("%s device %08x, index %d", __FUNCTION__ , device, index);
+ ALOGV("%s device %08x, index %d", __FUNCTION__ , device, index);
volumeCurves.addCurrentVolumeIndex(device, index);
return NO_ERROR;
}
@@ -2709,19 +2732,12 @@
bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
{
- bool active = false;
- for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT && !active; curStream++) {
- if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
- continue;
- }
- active = mOutputs.isActive(streamToVolumeSource((audio_stream_type_t)curStream), inPastMs);
- }
- return active;
+ return mOutputs.isActive(toVolumeSource(stream), inPastMs);
}
bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
{
- return mOutputs.isActiveRemotely(streamToVolumeSource((audio_stream_type_t)stream), inPastMs);
+ return mOutputs.isActiveRemotely(toVolumeSource(stream), inPastMs);
}
bool AudioPolicyManager::isSourceActive(audio_source_t source) const
@@ -3750,11 +3766,11 @@
struct audio_patch dummyPatch = {};
sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
- sp<SourceClientDescriptor> sourceDesc = new SourceClientDescriptor(
- *portId, uid, *attributes, patchDesc, srcDevice,
- mEngine->getStreamTypeForAttributes(*attributes),
- mEngine->getProductStrategyForAttributes(*attributes),
- streamToVolumeSource(mEngine->getStreamTypeForAttributes(*attributes)));
+ sp<SourceClientDescriptor> sourceDesc =
+ new SourceClientDescriptor(*portId, uid, *attributes, patchDesc, srcDevice,
+ mEngine->getStreamTypeForAttributes(*attributes),
+ mEngine->getProductStrategyForAttributes(*attributes),
+ toVolumeSource(*attributes));
status_t status = connectAudioSource(sourceDesc);
if (status == NO_ERROR) {
@@ -3919,7 +3935,7 @@
float AudioPolicyManager::getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device)
{
- return computeVolume(stream, index, device);
+ return computeVolume(getVolumeCurves(stream), toVolumeSource(stream), index, device);
}
status_t AudioPolicyManager::getSurroundFormats(unsigned int *numSurroundFormats,
@@ -5295,11 +5311,10 @@
// mute/unmute AUDIO_STREAM_TTS on all outputs
ALOGV("\t muting %d", mute);
uint32_t maxLatency = 0;
+ auto ttsVolumeSource = toVolumeSource(AUDIO_STREAM_TTS);
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
- desc,
- 0 /*delay*/, AUDIO_DEVICE_NONE);
+ setVolumeSourceMute(ttsVolumeSource, mute/*on*/, desc, 0 /*delay*/, AUDIO_DEVICE_NONE);
const uint32_t latency = desc->latency() * 2;
if (latency > maxLatency) {
maxLatency = latency;
@@ -5383,15 +5398,12 @@
if (muteWaitMs < tempMuteWaitMs) {
muteWaitMs = tempMuteWaitMs;
}
-
- for (const auto &productStrategy : productStrategies) {
- if (outputDesc->isStrategyActive(productStrategy)) {
- // make sure that we do not start the temporary mute period too early in case of
- // delayed device change
- setStrategyMute(productStrategy, true, outputDesc, delayMs);
- setStrategyMute(productStrategy, false, outputDesc, delayMs + tempMuteDurationMs,
+ for (const auto &activeVs : outputDesc->getActiveVolumeSources()) {
+ // make sure that we do not start the temporary mute period too early in case of
+ // delayed device change
+ setVolumeSourceMute(activeVs, true, outputDesc, delayMs);
+ setVolumeSourceMute(activeVs, false, outputDesc, delayMs + tempMuteDurationMs,
devices.types());
- }
}
}
@@ -5615,51 +5627,51 @@
return NULL;
}
-float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
+float AudioPolicyManager::computeVolume(IVolumeCurves &curves,
+ VolumeSource volumeSource,
int index,
audio_devices_t device)
{
- auto &curves = getVolumeCurves(stream);
float volumeDb = curves.volIndexToDb(Volume::getDeviceCategory(device), index);
// handle the case of accessibility active while a ringtone is playing: if the ringtone is much
// louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
// exploration of the dialer UI. In this situation, bring the accessibility volume closer to
// the ringtone volume
- if ((stream == AUDIO_STREAM_ACCESSIBILITY)
- && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState())
- && isStreamActive(AUDIO_STREAM_RING, 0)) {
- const float ringVolumeDB = computeVolume(AUDIO_STREAM_RING, index, device);
- return ringVolumeDB - 4 > volumeDb ? ringVolumeDB - 4 : volumeDb;
+ const auto callVolumeSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL);
+ const auto ringVolumeSrc = toVolumeSource(AUDIO_STREAM_RING);
+ const auto musicVolumeSrc = toVolumeSource(AUDIO_STREAM_MUSIC);
+ const auto alarmVolumeSrc = toVolumeSource(AUDIO_STREAM_ALARM);
+
+ if (volumeSource == toVolumeSource(AUDIO_STREAM_ACCESSIBILITY)
+ && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState()) &&
+ mOutputs.isActive(ringVolumeSrc, 0)) {
+ auto &ringCurves = getVolumeCurves(AUDIO_STREAM_RING);
+ const float ringVolumeDb = computeVolume(ringCurves, ringVolumeSrc, index, device);
+ return ringVolumeDb - 4 > volumeDb ? ringVolumeDb - 4 : volumeDb;
}
// in-call: always cap volume by voice volume + some low headroom
- if ((stream != AUDIO_STREAM_VOICE_CALL) &&
- (isInCall() || mOutputs.isActiveLocally(streamToVolumeSource(AUDIO_STREAM_VOICE_CALL)))) {
- switch (stream) {
- case AUDIO_STREAM_SYSTEM:
- case AUDIO_STREAM_RING:
- case AUDIO_STREAM_MUSIC:
- case AUDIO_STREAM_ALARM:
- case AUDIO_STREAM_NOTIFICATION:
- case AUDIO_STREAM_ENFORCED_AUDIBLE:
- case AUDIO_STREAM_DTMF:
- case AUDIO_STREAM_ACCESSIBILITY: {
- int voiceVolumeIndex = getVolumeCurves(AUDIO_STREAM_VOICE_CALL).getVolumeIndex(device);
- const float maxVoiceVolDb =
- computeVolume(AUDIO_STREAM_VOICE_CALL, voiceVolumeIndex, device)
+ if ((volumeSource != callVolumeSrc && (isInCall() ||
+ mOutputs.isActiveLocally(callVolumeSrc))) &&
+ (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM) ||
+ volumeSource == ringVolumeSrc || volumeSource == musicVolumeSrc ||
+ volumeSource == alarmVolumeSrc ||
+ volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION) ||
+ volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE) ||
+ volumeSource == toVolumeSource(AUDIO_STREAM_DTMF) ||
+ volumeSource == toVolumeSource(AUDIO_STREAM_ACCESSIBILITY))) {
+ auto &voiceCurves = getVolumeCurves(callVolumeSrc);
+ int voiceVolumeIndex = voiceCurves.getVolumeIndex(device);
+ const float maxVoiceVolDb =
+ computeVolume(voiceCurves, callVolumeSrc, voiceVolumeIndex, device)
+ IN_CALL_EARPIECE_HEADROOM_DB;
- if (volumeDb > maxVoiceVolDb) {
- ALOGV("computeVolume() stream %d at vol=%f overriden by stream %d at vol=%f",
- stream, volumeDb, AUDIO_STREAM_VOICE_CALL, maxVoiceVolDb);
- volumeDb = maxVoiceVolDb;
- }
- } break;
- default:
- break;
+ if (volumeDb > maxVoiceVolDb) {
+ ALOGV("%s volume source %d at vol=%f overriden by volume group %d at vol=%f", __func__,
+ volumeSource, volumeDb, callVolumeSrc, maxVoiceVolDb);
+ volumeDb = maxVoiceVolDb;
}
}
-
// if a headset is connected, apply the following rules to ring tones and notifications
// to avoid sound level bursts in user's ears:
// - always attenuate notifications volume by 6dB
@@ -5667,19 +5679,17 @@
// speaker is part of the select devices
// - if music is playing, always limit the volume to current music volume,
// with a minimum threshold at -36dB so that notification is always perceived.
- if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
- AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_USB_HEADSET |
- AUDIO_DEVICE_OUT_HEARING_AID)) &&
- ((stream == AUDIO_STREAM_ALARM || stream == AUDIO_STREAM_RING)
- || (stream == AUDIO_STREAM_NOTIFICATION)
- || (stream == AUDIO_STREAM_SYSTEM)
- || ((stream == AUDIO_STREAM_ENFORCED_AUDIBLE) &&
- (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
- AUDIO_POLICY_FORCE_NONE))) &&
- getVolumeCurves(stream).canBeMuted()) {
+ if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
+ AUDIO_DEVICE_OUT_WIRED_HEADSET | AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
+ AUDIO_DEVICE_OUT_USB_HEADSET | AUDIO_DEVICE_OUT_HEARING_AID)) &&
+ ((volumeSource == alarmVolumeSrc ||
+ volumeSource == ringVolumeSrc) ||
+ (volumeSource == toVolumeSource(AUDIO_STREAM_NOTIFICATION)) ||
+ (volumeSource == toVolumeSource(AUDIO_STREAM_SYSTEM)) ||
+ ((volumeSource == toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE)) &&
+ (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
+ curves.canBeMuted()) {
+
// when the phone is ringing we must consider that music could have been paused just before
// by the music application and behave as if music was active if the last music track was
// just stopped
@@ -5689,29 +5699,29 @@
audio_devices_t musicDevice =
mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
nullptr, true /*fromCache*/).types();
- float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
- getVolumeCurves(AUDIO_STREAM_MUSIC).getVolumeIndex(musicDevice),
- musicDevice);
- float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
- musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
- if (volumeDb > minVolDB) {
- volumeDb = minVolDB;
- ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
+ auto &musicCurves = getVolumeCurves(AUDIO_STREAM_MUSIC);
+ float musicVolDb = computeVolume(musicCurves, musicVolumeSrc,
+ musicCurves.getVolumeIndex(musicDevice), musicDevice);
+ float minVolDb = (musicVolDb > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
+ musicVolDb : SONIFICATION_HEADSET_VOLUME_MIN_DB;
+ if (volumeDb > minVolDb) {
+ volumeDb = minVolDb;
+ ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDb, musicVolDb);
}
if (device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
- AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
// on A2DP, also ensure notification volume is not too low compared to media when
// intended to be played
if ((volumeDb > -96.0f) &&
- (musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDb)) {
- ALOGV("computeVolume increasing volume for stream=%d device=0x%X from %f to %f",
- stream, device,
- volumeDb, musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
- volumeDb = musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
+ (musicVolDb - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDb)) {
+ ALOGV("%s increasing volume for volume source=%d device=0x%X from %f to %f",
+ __func__, volumeSource, device, volumeDb,
+ musicVolDb - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
+ volumeDb = musicVolDb - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
}
}
} else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
- (stream != AUDIO_STREAM_ALARM && stream != AUDIO_STREAM_RING)) {
+ (!(volumeSource == alarmVolumeSrc || volumeSource == ringVolumeSrc))) {
volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
}
}
@@ -5745,58 +5755,61 @@
return (int)(minDst + ((srcIndex - minSrc) * (maxDst - minDst)) / (maxSrc - minSrc));
}
-status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
+status_t AudioPolicyManager::checkAndSetVolume(IVolumeCurves &curves,
+ VolumeSource volumeSource,
int index,
const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device,
int delayMs,
bool force)
{
- // do not change actual stream volume if the stream is muted
- if (outputDesc->isMuted(streamToVolumeSource(stream))) {
- ALOGVV("%s() stream %d muted count %d", __func__, stream, outputDesc->getMuteCount(stream));
+ // do not change actual attributes volume if the attributes is muted
+ if (outputDesc->isMuted(volumeSource)) {
+ ALOGVV("%s: volume source %d muted count %d active=%d", __func__, volumeSource,
+ outputDesc->getMuteCount(volumeSource), outputDesc->isActive(volumeSource));
return NO_ERROR;
}
+ VolumeSource callVolSrc = toVolumeSource(AUDIO_STREAM_VOICE_CALL);
+ VolumeSource btScoVolSrc = toVolumeSource(AUDIO_STREAM_BLUETOOTH_SCO);
+ bool isVoiceVolSrc = callVolSrc == volumeSource;
+ bool isBtScoVolSrc = btScoVolSrc == volumeSource;
+
audio_policy_forced_cfg_t forceUseForComm =
mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
// do not change in call volume if bluetooth is connected and vice versa
- if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
- (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
- ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
- stream, forceUseForComm);
+ // if sco and call follow same curves, bypass forceUseForComm
+ if ((callVolSrc != btScoVolSrc) &&
+ ((isVoiceVolSrc && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
+ (isBtScoVolSrc && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO))) {
+ ALOGV("%s cannot set volume group %d volume with force use = %d for comm", __func__,
+ volumeSource, forceUseForComm);
return INVALID_OPERATION;
}
-
if (device == AUDIO_DEVICE_NONE) {
device = outputDesc->devices().types();
}
- float volumeDb = computeVolume(stream, index, device);
+ float volumeDb = computeVolume(curves, volumeSource, index, device);
if (outputDesc->isFixedVolume(device) ||
// Force VoIP volume to max for bluetooth SCO
- ((stream == AUDIO_STREAM_VOICE_CALL || stream == AUDIO_STREAM_BLUETOOTH_SCO) &&
- (device & AUDIO_DEVICE_OUT_ALL_SCO) != 0)) {
+ ((isVoiceVolSrc || isBtScoVolSrc) && (device & AUDIO_DEVICE_OUT_ALL_SCO) != 0)) {
volumeDb = 0.0f;
}
+ outputDesc->setVolume(volumeDb, volumeSource, curves.getStreamTypes(), device, delayMs, force);
- outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
-
- if (stream == AUDIO_STREAM_VOICE_CALL ||
- stream == AUDIO_STREAM_BLUETOOTH_SCO) {
+ if (isVoiceVolSrc || isBtScoVolSrc) {
float voiceVolume;
// Force voice volume to max for bluetooth SCO as volume is managed by the headset
- if (stream == AUDIO_STREAM_VOICE_CALL) {
- voiceVolume = (float)index/(float)getVolumeCurves(stream).getVolumeIndexMax();
+ if (isVoiceVolSrc) {
+ voiceVolume = (float)index/(float)curves.getVolumeIndexMax();
} else {
voiceVolume = 1.0;
}
-
if (voiceVolume != mLastVoiceVolume) {
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
mLastVoiceVolume = voiceVolume;
}
}
-
return NO_ERROR;
}
@@ -5806,14 +5819,10 @@
bool force)
{
ALOGVV("applyStreamVolumes() for device %08x", device);
-
- for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
- checkAndSetVolume((audio_stream_type_t)stream,
- getVolumeCurves((audio_stream_type_t)stream).getVolumeIndex(device),
- outputDesc,
- device,
- delayMs,
- force);
+ for (const auto &volumeGroup : mEngine->getVolumeGroups()) {
+ auto &curves = getVolumeCurves(toVolumeSource(volumeGroup));
+ checkAndSetVolume(curves, toVolumeSource(volumeGroup),
+ curves.getVolumeIndex(device), outputDesc, device, delayMs, force);
}
}
@@ -5823,43 +5832,54 @@
int delayMs,
audio_devices_t device)
{
- for (auto stream: mEngine->getStreamTypesForProductStrategy(strategy)) {
- ALOGVV("%s() stream %d, mute %d, output ID %d", __FUNCTION__, stream, on,
- outputDesc->getId());
- setStreamMute(stream, on, outputDesc, delayMs, device);
+ std::vector<VolumeSource> sourcesToMute;
+ for (auto attributes: mEngine->getAllAttributesForProductStrategy(strategy)) {
+ ALOGVV("%s() attributes %s, mute %d, output ID %d", __func__,
+ toString(attributes).c_str(), on, outputDesc->getId());
+ VolumeSource source = toVolumeSource(attributes);
+ if (std::find(begin(sourcesToMute), end(sourcesToMute), source) == end(sourcesToMute)) {
+ sourcesToMute.push_back(source);
+ }
}
+ for (auto source : sourcesToMute) {
+ setVolumeSourceMute(source, on, outputDesc, delayMs, device);
+ }
+
}
-void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
- bool on,
- const sp<AudioOutputDescriptor>& outputDesc,
- int delayMs,
- audio_devices_t device)
+void AudioPolicyManager::setVolumeSourceMute(VolumeSource volumeSource,
+ bool on,
+ const sp<AudioOutputDescriptor>& outputDesc,
+ int delayMs,
+ audio_devices_t device,
+ bool activeOnly)
{
+ if (activeOnly && !outputDesc->isActive(volumeSource)) {
+ return;
+ }
if (device == AUDIO_DEVICE_NONE) {
device = outputDesc->devices().types();
}
-
- ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
- stream, on, outputDesc->getMuteCount(stream), device);
- auto &curves = getVolumeCurves(stream);
+ auto &curves = getVolumeCurves(volumeSource);
if (on) {
- if (!outputDesc->isMuted(streamToVolumeSource(stream))) {
+ if (!outputDesc->isMuted(volumeSource)) {
if (curves.canBeMuted() &&
- ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
- (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
- checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
+ (volumeSource != toVolumeSource(AUDIO_STREAM_ENFORCED_AUDIBLE) ||
+ (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) ==
+ AUDIO_POLICY_FORCE_NONE))) {
+ checkAndSetVolume(curves, volumeSource, 0, outputDesc, device, delayMs);
}
}
- // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
- outputDesc->incMuteCount(streamToVolumeSource(stream));
+ // increment mMuteCount after calling checkAndSetVolume() so that volume change is not
+ // ignored
+ outputDesc->incMuteCount(volumeSource);
} else {
- if (!outputDesc->isMuted(streamToVolumeSource(stream))) {
- ALOGV("setStreamMute() unmuting non muted stream!");
+ if (!outputDesc->isMuted(volumeSource)) {
+ ALOGV("%s unmuting non muted attributes!", __func__);
return;
}
- if (outputDesc->decMuteCount(streamToVolumeSource(stream)) == 0) {
- checkAndSetVolume(stream,
+ if (outputDesc->decMuteCount(volumeSource) == 0) {
+ checkAndSetVolume(curves, volumeSource,
curves.getVolumeIndex(device),
outputDesc,
device,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index b83e9a8..1fc61e5 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -174,8 +174,7 @@
status_t setVolumeGroupIndex(IVolumeCurves &volumeCurves, volume_group_t group, int index,
audio_devices_t device, const audio_attributes_t attributes);
- status_t setVolumeCurveIndex(volume_group_t volumeGroup,
- int index,
+ status_t setVolumeCurveIndex(int index,
audio_devices_t device,
IVolumeCurves &volumeCurves);
@@ -358,6 +357,30 @@
return mDefaultOutputDevice;
}
+ std::vector<volume_group_t> getVolumeGroups() const
+ {
+ return mEngine->getVolumeGroups();
+ }
+
+ VolumeSource toVolumeSource(volume_group_t volumeGroup) const
+ {
+ return static_cast<VolumeSource>(volumeGroup);
+ }
+ VolumeSource toVolumeSource(const audio_attributes_t &attributes) const
+ {
+ return toVolumeSource(mEngine->getVolumeGroupForAttributes(attributes));
+ }
+ VolumeSource toVolumeSource(audio_stream_type_t stream) const
+ {
+ return toVolumeSource(mEngine->getVolumeGroupForStreamType(stream));
+ }
+ IVolumeCurves &getVolumeCurves(VolumeSource volumeSource)
+ {
+ auto *curves = mEngine->getVolumeCurvesForVolumeGroup(
+ static_cast<volume_group_t>(volumeSource));
+ ALOG_ASSERT(curves != nullptr, "No curves for volume source %d", volumeSource);
+ return *curves;
+ }
IVolumeCurves &getVolumeCurves(const audio_attributes_t &attr)
{
auto *curves = mEngine->getVolumeCurvesForAttributes(attr);
@@ -395,7 +418,8 @@
// compute the actual volume for a given stream according to the requested index and a particular
// device
- virtual float computeVolume(audio_stream_type_t stream,
+ virtual float computeVolume(IVolumeCurves &curves,
+ VolumeSource volumeSource,
int index,
audio_devices_t device);
@@ -404,7 +428,8 @@
audio_stream_type_t srcStream,
audio_stream_type_t dstStream);
// check that volume change is permitted, compute and send new volume to audio hardware
- virtual status_t checkAndSetVolume(audio_stream_type_t stream, int index,
+ virtual status_t checkAndSetVolume(IVolumeCurves &curves,
+ VolumeSource volumeSource, int index,
const sp<AudioOutputDescriptor>& outputDesc,
audio_devices_t device,
int delayMs = 0, bool force = false);
@@ -428,12 +453,22 @@
int delayMs = 0,
audio_devices_t device = AUDIO_DEVICE_NONE);
- // Mute or unmute the stream on the specified output
- void setStreamMute(audio_stream_type_t stream,
- bool on,
- const sp<AudioOutputDescriptor>& outputDesc,
- int delayMs = 0,
- audio_devices_t device = (audio_devices_t)0);
+ /**
+ * @brief setVolumeSourceMute Mute or unmute the volume source on the specified output
+ * @param volumeSource to be muted/unmute (may host legacy streams or by extension set of
+ * audio attributes)
+ * @param on true to mute, false to umute
+ * @param outputDesc on which the client following the volume group shall be muted/umuted
+ * @param delayMs
+ * @param device
+ * @param activeOnly if true, mute only if the volume group is active on the output.
+ */
+ void setVolumeSourceMute(VolumeSource volumeSource,
+ bool on,
+ const sp<AudioOutputDescriptor>& outputDesc,
+ int delayMs = 0,
+ audio_devices_t device = AUDIO_DEVICE_NONE,
+ bool activeOnly = false);
audio_mode_t getPhoneState();
diff --git a/services/camera/OWNERS b/services/camera/OWNERS
index 18acfee..f48a95c 100644
--- a/services/camera/OWNERS
+++ b/services/camera/OWNERS
@@ -1,6 +1 @@
-cychen@google.com
-epeev@google.com
-etalvala@google.com
-shuzhenwang@google.com
-yinchiayeh@google.com
-zhijunhe@google.com
+include platform/frameworks/av:/camera/OWNERS
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 62ec955..51d0682 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2180,31 +2180,37 @@
return mp;
}
-void CameraService::loadSound() {
+void CameraService::increaseSoundRef() {
+ Mutex::Autolock lock(mSoundLock);
+ mSoundRef++;
+}
+
+void CameraService::loadSoundLocked(sound_kind kind) {
ATRACE_CALL();
- Mutex::Autolock lock(mSoundLock);
- LOG1("CameraService::loadSound ref=%d", mSoundRef);
- if (mSoundRef++) return;
-
- mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
- if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
- mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
- }
- mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
- if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
- mSoundPlayer[SOUND_RECORDING_START] =
+ LOG1("CameraService::loadSoundLocked ref=%d", mSoundRef);
+ if (SOUND_SHUTTER == kind && mSoundPlayer[SOUND_SHUTTER] == NULL) {
+ mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/product/media/audio/ui/camera_click.ogg");
+ if (mSoundPlayer[SOUND_SHUTTER] == nullptr) {
+ mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
+ }
+ } else if (SOUND_RECORDING_START == kind && mSoundPlayer[SOUND_RECORDING_START] == NULL) {
+ mSoundPlayer[SOUND_RECORDING_START] = newMediaPlayer("/product/media/audio/ui/VideoRecord.ogg");
+ if (mSoundPlayer[SOUND_RECORDING_START] == nullptr) {
+ mSoundPlayer[SOUND_RECORDING_START] =
newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
- }
- mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
- if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
- mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+ }
+ } else if (SOUND_RECORDING_STOP == kind && mSoundPlayer[SOUND_RECORDING_STOP] == NULL) {
+ mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/product/media/audio/ui/VideoStop.ogg");
+ if (mSoundPlayer[SOUND_RECORDING_STOP] == nullptr) {
+ mSoundPlayer[SOUND_RECORDING_STOP] = newMediaPlayer("/system/media/audio/ui/VideoStop.ogg");
+ }
}
}
-void CameraService::releaseSound() {
+void CameraService::decreaseSoundRef() {
Mutex::Autolock lock(mSoundLock);
- LOG1("CameraService::releaseSound ref=%d", mSoundRef);
+ LOG1("CameraService::decreaseSoundRef ref=%d", mSoundRef);
if (--mSoundRef) return;
for (int i = 0; i < NUM_SOUNDS; i++) {
@@ -2220,6 +2226,7 @@
LOG1("playSound(%d)", kind);
Mutex::Autolock lock(mSoundLock);
+ loadSoundLocked(kind);
sp<MediaPlayer> player = mSoundPlayer[kind];
if (player != 0) {
player->seekTo(0);
@@ -2249,7 +2256,7 @@
mRemoteCallback = cameraClient;
- cameraService->loadSound();
+ cameraService->increaseSoundRef();
LOG1("Client::Client X (pid %d, id %d)", callingPid, mCameraId);
}
@@ -2259,7 +2266,7 @@
ALOGV("~Client");
mDestructionStarted = true;
- sCameraService->releaseSound();
+ sCameraService->decreaseSoundRef();
// unconditionally disconnect. function is idempotent
Client::disconnect();
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 65727ec..344dd92 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -192,10 +192,10 @@
NUM_SOUNDS
};
- void loadSound();
void playSound(sound_kind kind);
- void releaseSound();
-
+ void loadSoundLocked(sound_kind kind);
+ void decreaseSoundRef();
+ void increaseSoundRef();
/**
* Update the state of a given camera device (open/close/active/idle) with
* the camera proxy service in the system service