mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-03 12:07:58 +00:00
Merge "audio: Add volume/mute, audio mode, and screen state to IModule"
This commit is contained in:
@@ -91,12 +91,14 @@ aidl_interface {
|
||||
name: "android.hardware.audio.core",
|
||||
vendor_available: true,
|
||||
srcs: [
|
||||
"android/hardware/audio/core/AudioMode.aidl",
|
||||
"android/hardware/audio/core/AudioPatch.aidl",
|
||||
"android/hardware/audio/core/AudioRoute.aidl",
|
||||
"android/hardware/audio/core/IConfig.aidl",
|
||||
"android/hardware/audio/core/IModule.aidl",
|
||||
"android/hardware/audio/core/IStreamIn.aidl",
|
||||
"android/hardware/audio/core/IStreamOut.aidl",
|
||||
"android/hardware/audio/core/ITelephony.aidl",
|
||||
"android/hardware/audio/core/MmapBufferDescriptor.aidl",
|
||||
"android/hardware/audio/core/ModuleDebug.aidl",
|
||||
"android/hardware/audio/core/StreamDescriptor.aidl",
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.audio.core;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum AudioMode {
|
||||
NORMAL = 0,
|
||||
RINGTONE = 1,
|
||||
IN_CALL = 2,
|
||||
IN_COMMUNICATION = 3,
|
||||
CALL_SCREEN = 4,
|
||||
}
|
||||
@@ -35,6 +35,7 @@ package android.hardware.audio.core;
|
||||
@VintfStability
|
||||
interface IModule {
|
||||
void setModuleDebug(in android.hardware.audio.core.ModuleDebug debug);
|
||||
@nullable android.hardware.audio.core.ITelephony getTelephony();
|
||||
android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
|
||||
void disconnectExternalDevice(int portId);
|
||||
android.hardware.audio.core.AudioPatch[] getAudioPatches();
|
||||
@@ -49,6 +50,15 @@ interface IModule {
|
||||
boolean setAudioPortConfig(in android.media.audio.common.AudioPortConfig requested, out android.media.audio.common.AudioPortConfig suggested);
|
||||
void resetAudioPatch(int patchId);
|
||||
void resetAudioPortConfig(int portConfigId);
|
||||
boolean getMasterMute();
|
||||
void setMasterMute(boolean mute);
|
||||
float getMasterVolume();
|
||||
void setMasterVolume(float volume);
|
||||
boolean getMicMute();
|
||||
void setMicMute(boolean mute);
|
||||
void updateAudioMode(android.hardware.audio.core.AudioMode mode);
|
||||
void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
|
||||
void updateScreenState(boolean isTurnedOn);
|
||||
@VintfStability
|
||||
parcelable OpenInputStreamArguments {
|
||||
int portConfigId;
|
||||
@@ -72,4 +82,11 @@ interface IModule {
|
||||
android.hardware.audio.core.IStreamOut stream;
|
||||
android.hardware.audio.core.StreamDescriptor desc;
|
||||
}
|
||||
@Backing(type="int") @VintfStability
|
||||
enum ScreenRotation {
|
||||
DEG_0 = 0,
|
||||
DEG_90 = 1,
|
||||
DEG_180 = 2,
|
||||
DEG_270 = 3,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.audio.core;
|
||||
@VintfStability
|
||||
interface ITelephony {
|
||||
android.hardware.audio.core.AudioMode[] getSupportedAudioModes();
|
||||
void switchAudioMode(android.hardware.audio.core.AudioMode mode);
|
||||
}
|
||||
38
audio/aidl/android/hardware/audio/core/AudioMode.aidl
Normal file
38
audio/aidl/android/hardware/audio/core/AudioMode.aidl
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
package android.hardware.audio.core;
|
||||
|
||||
/**
|
||||
* The audio mode describes states of the audio system of the device that
|
||||
* can significantly affect the rules of audio routing, volume control, etc.
|
||||
* The audio mode is controlled by the framework, however the HAL has some
|
||||
* flexibility in the choice of modes to support, see 'IModule.updateAudioMode'.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum AudioMode {
|
||||
/** No active calls. */
|
||||
NORMAL = 0,
|
||||
/** The device is playing the ringtone. */
|
||||
RINGTONE = 1,
|
||||
/** The call is handled by the telephony stack ("voice call"). */
|
||||
IN_CALL = 2,
|
||||
/** The call is handled by an application ("VoIP call"). */
|
||||
IN_COMMUNICATION = 3,
|
||||
/** Call screening is in progress. */
|
||||
CALL_SCREEN = 4,
|
||||
}
|
||||
@@ -18,10 +18,12 @@ package android.hardware.audio.core;
|
||||
|
||||
import android.hardware.audio.common.SinkMetadata;
|
||||
import android.hardware.audio.common.SourceMetadata;
|
||||
import android.hardware.audio.core.AudioMode;
|
||||
import android.hardware.audio.core.AudioPatch;
|
||||
import android.hardware.audio.core.AudioRoute;
|
||||
import android.hardware.audio.core.IStreamIn;
|
||||
import android.hardware.audio.core.IStreamOut;
|
||||
import android.hardware.audio.core.ITelephony;
|
||||
import android.hardware.audio.core.ModuleDebug;
|
||||
import android.hardware.audio.core.StreamDescriptor;
|
||||
import android.media.audio.common.AudioOffloadInfo;
|
||||
@@ -59,6 +61,19 @@ interface IModule {
|
||||
*/
|
||||
void setModuleDebug(in ModuleDebug debug);
|
||||
|
||||
/**
|
||||
* Retrieve the interface to control telephony audio.
|
||||
*
|
||||
* If the HAL module supports telephony functions, it must return an
|
||||
* instance of the ITelephony interface. The same instance must be returned
|
||||
* during the lifetime of the HAL module. If the HAL module does not support
|
||||
* telephony, a null must be returned, without throwing any errors.
|
||||
*
|
||||
* @return An instance of the ITelephony interface implementation.
|
||||
* @throws EX_ILLEGAL_STATE If there was an error creating an instance.
|
||||
*/
|
||||
@nullable ITelephony getTelephony();
|
||||
|
||||
/**
|
||||
* Set a device port of an external device into connected state.
|
||||
*
|
||||
@@ -487,4 +502,140 @@ interface IModule {
|
||||
* - If the port config is used by a patch.
|
||||
*/
|
||||
void resetAudioPortConfig(int portConfigId);
|
||||
|
||||
/**
|
||||
* Get the current state of audio output muting.
|
||||
*
|
||||
* If the HAL module supports muting its combined output completely,
|
||||
* this method returns whether muting is currently enabled.
|
||||
*
|
||||
* Note that muting operates independently from the master volume.
|
||||
*
|
||||
* @return Whether the output from the module is muted.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If muting of combined output
|
||||
* is not supported by the module.
|
||||
*/
|
||||
boolean getMasterMute();
|
||||
|
||||
/**
|
||||
* Set the current value of the audio output muting.
|
||||
*
|
||||
* If the HAL module supports muting its combined output completely, this
|
||||
* method controls the mute. Note that for modules supporting telephony,
|
||||
* muting does not affect the voice call.
|
||||
*
|
||||
* For HAL modules not supporting this operation, it's functionality is
|
||||
* typically emulated by the client, in the digital domain.
|
||||
*
|
||||
* @param mute Whether the output from the module is muted.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If muting of combined output
|
||||
* is not supported by the module.
|
||||
*/
|
||||
void setMasterMute(boolean mute);
|
||||
|
||||
/**
|
||||
* Get the current value of the audio output attenuation.
|
||||
*
|
||||
* If the HAL module supports attenuating the level its combined output,
|
||||
* this method returns the current attenuation value.
|
||||
*
|
||||
* @return Volume 1.0f means no attenuation (unity), 0.0f is mute.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If attenuation of combined output
|
||||
* is not supported by the module.
|
||||
*/
|
||||
float getMasterVolume();
|
||||
|
||||
/**
|
||||
* Set the current value of the audio output attenuation.
|
||||
*
|
||||
* If the HAL module supports attenuating the level its combined output,
|
||||
* this method sets the attenuation value. Note that for modules supporting
|
||||
* telephony, the attenuation of the voice call volume is set separately
|
||||
* via ITelephony interface.
|
||||
*
|
||||
* For HAL modules not supporting this operation, it's functionality is
|
||||
* typically emulated by the client, in the digital domain.
|
||||
*
|
||||
* @param volume The new value, 1.0f means no attenuation (unity), 0.0f is mute.
|
||||
* @throws EX_ILLEGAL_ARGUMENT If the value of the volume is outside of
|
||||
* accepted range.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If attenuation of combined output
|
||||
* is not supported by the module.
|
||||
*/
|
||||
void setMasterVolume(float volume);
|
||||
|
||||
/**
|
||||
* Get the current state of audio input muting.
|
||||
*
|
||||
* If the HAL module supports muting its external input, this method returns
|
||||
* whether muting is currently enabled.
|
||||
*
|
||||
* @return Whether the input is muted.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If muting of input is not supported by
|
||||
* the module.
|
||||
*/
|
||||
boolean getMicMute();
|
||||
|
||||
/**
|
||||
* Set the current value of the audio input muting.
|
||||
*
|
||||
* If the HAL module supports muting its external input, this method
|
||||
* controls the mute.
|
||||
*
|
||||
* For HAL modules not supporting this operation, it's functionality is
|
||||
* emulated by the client.
|
||||
*
|
||||
* @param mute Whether input is muted.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If muting of input is not supported by
|
||||
* the module.
|
||||
*/
|
||||
void setMicMute(boolean mute);
|
||||
|
||||
/**
|
||||
* Notify the HAL module on the change of the current audio mode.
|
||||
*
|
||||
* The current audio mode is always controlled by the client. This is an
|
||||
* informative notification sent to all modules, no reply is needed. The HAL
|
||||
* module should silently ignore this notification if it does not need to
|
||||
* be aware of the current audio mode.
|
||||
*
|
||||
* The client sends this notification to all HAL modules after successfully
|
||||
* switching the telephony module by calling the 'ITelephony.switchAudioMode'
|
||||
* method.
|
||||
*
|
||||
* @param mode The current mode.
|
||||
*/
|
||||
void updateAudioMode(AudioMode mode);
|
||||
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum ScreenRotation {
|
||||
/** Natural orientation. */
|
||||
DEG_0 = 0,
|
||||
DEG_90 = 1,
|
||||
/** Upside down. */
|
||||
DEG_180 = 2,
|
||||
DEG_270 = 3,
|
||||
}
|
||||
/**
|
||||
* Notify the HAL module on the change of the screen rotation.
|
||||
*
|
||||
* Informs the HAL of the current orientation of the device screen. This
|
||||
* information can be used to optimize the output of built-in speakers.
|
||||
* This is an informative notification sent to all modules, no reply is
|
||||
* needed.
|
||||
*
|
||||
* @param rotation The current rotation.
|
||||
*/
|
||||
void updateScreenRotation(ScreenRotation rotation);
|
||||
|
||||
/**
|
||||
* Notify the HAL module on the change of the screen state.
|
||||
*
|
||||
* Informs the HAL whether the screen of the device is turned on. This is an
|
||||
* informative notification sent to all modules, no reply is needed.
|
||||
*
|
||||
* @param isTurnedOn True if the screen is turned on.
|
||||
*/
|
||||
void updateScreenState(boolean isTurnedOn);
|
||||
}
|
||||
|
||||
56
audio/aidl/android/hardware/audio/core/ITelephony.aidl
Normal file
56
audio/aidl/android/hardware/audio/core/ITelephony.aidl
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
package android.hardware.audio.core;
|
||||
|
||||
import android.hardware.audio.core.AudioMode;
|
||||
|
||||
/**
|
||||
* An instance of ITelephony manages settings which are specific to voice calls
|
||||
* and SMS messaging functionality. This interface is optional to implement and
|
||||
* provide by the vendor. It needs to be provided only if the device actually
|
||||
* supports telephony.
|
||||
*/
|
||||
@VintfStability
|
||||
interface ITelephony {
|
||||
/**
|
||||
* Return the list of supported audio modes.
|
||||
*
|
||||
* The first 4 AudioModes: NORMAL, RINGTONE, IN_CALL, IN_COMMUNICATION must
|
||||
* be supported by all implementations.
|
||||
*
|
||||
* This method is only called once, during the audio system initialization,
|
||||
* and must return the same result all the time.
|
||||
*
|
||||
* @return The list of supported audio modes.
|
||||
*/
|
||||
AudioMode[] getSupportedAudioModes();
|
||||
|
||||
/**
|
||||
* Switch the HAL into a new audio mode.
|
||||
*
|
||||
* The current audio mode is always controlled by the client. The HAL must
|
||||
* accept all modes returned by 'getSupportedAudioModes' and reject the
|
||||
* rest. The HAL must return from this method only after switching itself
|
||||
* to the specified mode, or throw an error if there was a problem during
|
||||
* switching.
|
||||
*
|
||||
* @param mode The mode to switch to.
|
||||
* @throws EX_UNSUPPORTED_OPERATION If the HAL does not support the specified mode.
|
||||
* @throws EX_ILLEGAL_STATE If there was an error during switching.
|
||||
*/
|
||||
void switchAudioMode(AudioMode mode);
|
||||
}
|
||||
@@ -39,6 +39,7 @@ cc_library_static {
|
||||
"Configuration.cpp",
|
||||
"Module.cpp",
|
||||
"Stream.cpp",
|
||||
"Telephony.cpp",
|
||||
],
|
||||
visibility: [
|
||||
":__subpackages__",
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
|
||||
|
||||
#include "core-impl/Module.h"
|
||||
#include "core-impl/Telephony.h"
|
||||
#include "core-impl/utils.h"
|
||||
|
||||
using aidl::android::hardware::audio::common::SinkMetadata;
|
||||
@@ -245,6 +246,15 @@ ndk::ScopedAStatus Module::setModuleDebug(
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::getTelephony(std::shared_ptr<ITelephony>* _aidl_return) {
|
||||
if (mTelephony == nullptr) {
|
||||
mTelephony = ndk::SharedRefBase::make<Telephony>();
|
||||
}
|
||||
*_aidl_return = mTelephony;
|
||||
LOG(DEBUG) << __func__ << ": returning instance of ITelephony: " << _aidl_return->get();
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdAndAdditionalData,
|
||||
AudioPort* _aidl_return) {
|
||||
const int32_t templateId = in_templateIdAndAdditionalData.id;
|
||||
@@ -779,4 +789,60 @@ ndk::ScopedAStatus Module::resetAudioPortConfig(int32_t in_portConfigId) {
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::getMasterMute(bool* _aidl_return) {
|
||||
*_aidl_return = mMasterMute;
|
||||
LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::setMasterMute(bool in_mute) {
|
||||
LOG(DEBUG) << __func__ << ": " << in_mute;
|
||||
mMasterMute = in_mute;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::getMasterVolume(float* _aidl_return) {
|
||||
*_aidl_return = mMasterVolume;
|
||||
LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::setMasterVolume(float in_volume) {
|
||||
LOG(DEBUG) << __func__ << ": " << in_volume;
|
||||
if (in_volume >= 0.0f && in_volume <= 1.0f) {
|
||||
mMasterVolume = in_volume;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
LOG(ERROR) << __func__ << ": invalid master volume value: " << in_volume;
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::getMicMute(bool* _aidl_return) {
|
||||
*_aidl_return = mMicMute;
|
||||
LOG(DEBUG) << __func__ << ": returning " << *_aidl_return;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::setMicMute(bool in_mute) {
|
||||
LOG(DEBUG) << __func__ << ": " << in_mute;
|
||||
mMicMute = in_mute;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::updateAudioMode(AudioMode in_mode) {
|
||||
// No checks for supported audio modes here, it's an informative notification.
|
||||
LOG(DEBUG) << __func__ << ": " << toString(in_mode);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::updateScreenRotation(ScreenRotation in_rotation) {
|
||||
LOG(DEBUG) << __func__ << ": " << toString(in_rotation);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Module::updateScreenState(bool in_isTurnedOn) {
|
||||
LOG(DEBUG) << __func__ << ": " << in_isTurnedOn;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::audio::core
|
||||
|
||||
41
audio/aidl/default/Telephony.cpp
Normal file
41
audio/aidl/default/Telephony.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include <android/binder_to_string.h>
|
||||
#define LOG_TAG "AHAL_Telephony"
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "core-impl/Telephony.h"
|
||||
|
||||
namespace aidl::android::hardware::audio::core {
|
||||
|
||||
ndk::ScopedAStatus Telephony::getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) {
|
||||
*_aidl_return = mSupportedAudioModes;
|
||||
LOG(DEBUG) << __func__ << ": returning " << ::android::internal::ToString(*_aidl_return);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus Telephony::switchAudioMode(AudioMode in_mode) {
|
||||
if (std::find(mSupportedAudioModes.begin(), mSupportedAudioModes.end(), in_mode) !=
|
||||
mSupportedAudioModes.end()) {
|
||||
LOG(DEBUG) << __func__ << ": " << toString(in_mode);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
LOG(ERROR) << __func__ << ": unsupported mode " << toString(in_mode);
|
||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::audio::core
|
||||
@@ -35,6 +35,7 @@ class Module : public BnModule {
|
||||
private:
|
||||
ndk::ScopedAStatus setModuleDebug(
|
||||
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
|
||||
ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
|
||||
ndk::ScopedAStatus connectExternalDevice(
|
||||
const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
|
||||
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
|
||||
@@ -70,6 +71,17 @@ class Module : public BnModule {
|
||||
bool* _aidl_return) override;
|
||||
ndk::ScopedAStatus resetAudioPatch(int32_t in_patchId) override;
|
||||
ndk::ScopedAStatus resetAudioPortConfig(int32_t in_portConfigId) override;
|
||||
ndk::ScopedAStatus getMasterMute(bool* _aidl_return) override;
|
||||
ndk::ScopedAStatus setMasterMute(bool in_mute) override;
|
||||
ndk::ScopedAStatus getMasterVolume(float* _aidl_return) override;
|
||||
ndk::ScopedAStatus setMasterVolume(float in_volume) override;
|
||||
ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
|
||||
ndk::ScopedAStatus setMicMute(bool in_mute) override;
|
||||
ndk::ScopedAStatus updateAudioMode(
|
||||
::aidl::android::hardware::audio::core::AudioMode in_mode) override;
|
||||
ndk::ScopedAStatus updateScreenRotation(
|
||||
::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override;
|
||||
ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override;
|
||||
|
||||
void cleanUpPatch(int32_t patchId);
|
||||
ndk::ScopedAStatus createStreamContext(
|
||||
@@ -88,12 +100,18 @@ class Module : public BnModule {
|
||||
|
||||
std::unique_ptr<internal::Configuration> mConfig;
|
||||
ModuleDebug mDebug;
|
||||
// Since it is required to return the same instance of the ITelephony, even
|
||||
// if the client has released it on its side, we need to hold it via a strong pointer.
|
||||
std::shared_ptr<ITelephony> mTelephony;
|
||||
// ids of ports created at runtime via 'connectExternalDevice'.
|
||||
std::set<int32_t> mConnectedDevicePorts;
|
||||
Streams mStreams;
|
||||
// Maps port ids and port config ids to patch ids.
|
||||
// Multimap because both ports and configs can be used by multiple patches.
|
||||
std::multimap<int32_t, int32_t> mPatches;
|
||||
bool mMasterMute = false;
|
||||
float mMasterVolume = 1.0f;
|
||||
bool mMicMute = false;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::audio::core
|
||||
|
||||
34
audio/aidl/default/include/core-impl/Telephony.h
Normal file
34
audio/aidl/default/include/core-impl/Telephony.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <android/binder_enums.h>
|
||||
|
||||
#include <aidl/android/hardware/audio/core/BnTelephony.h>
|
||||
|
||||
namespace aidl::android::hardware::audio::core {
|
||||
|
||||
class Telephony : public BnTelephony {
|
||||
private:
|
||||
ndk::ScopedAStatus getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) override;
|
||||
ndk::ScopedAStatus switchAudioMode(AudioMode in_mode) override;
|
||||
|
||||
const std::vector<AudioMode> mSupportedAudioModes = {::ndk::enum_range<AudioMode>().begin(),
|
||||
::ndk::enum_range<AudioMode>().end()};
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::audio::core
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <mutex>
|
||||
|
||||
#include <android-base/properties.h>
|
||||
#include <android/binder_auto_utils.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
@@ -34,7 +35,7 @@ class AudioHalBinderServiceUtil {
|
||||
if (mBinder == nullptr) {
|
||||
LOG(ERROR) << "Failed to get service " << serviceName;
|
||||
} else {
|
||||
LOG(DEBUG) << "succeed to get service " << serviceName;
|
||||
LOG(DEBUG) << "Succeeded to get service " << serviceName;
|
||||
}
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -29,8 +30,8 @@
|
||||
#include <Utils.h>
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <aidl/android/hardware/audio/core/IConfig.h>
|
||||
#include <aidl/android/hardware/audio/core/IModule.h>
|
||||
#include <aidl/android/hardware/audio/core/ITelephony.h>
|
||||
#include <aidl/android/media/audio/common/AudioIoFlags.h>
|
||||
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
|
||||
#include <android-base/chrono_utils.h>
|
||||
@@ -46,11 +47,13 @@ using aidl::android::hardware::audio::common::PlaybackTrackMetadata;
|
||||
using aidl::android::hardware::audio::common::RecordTrackMetadata;
|
||||
using aidl::android::hardware::audio::common::SinkMetadata;
|
||||
using aidl::android::hardware::audio::common::SourceMetadata;
|
||||
using aidl::android::hardware::audio::core::AudioMode;
|
||||
using aidl::android::hardware::audio::core::AudioPatch;
|
||||
using aidl::android::hardware::audio::core::AudioRoute;
|
||||
using aidl::android::hardware::audio::core::IModule;
|
||||
using aidl::android::hardware::audio::core::IStreamIn;
|
||||
using aidl::android::hardware::audio::core::IStreamOut;
|
||||
using aidl::android::hardware::audio::core::ITelephony;
|
||||
using aidl::android::hardware::audio::core::ModuleDebug;
|
||||
using aidl::android::hardware::audio::core::StreamDescriptor;
|
||||
using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
|
||||
@@ -173,6 +176,29 @@ class WithAudioPortConfig {
|
||||
AudioPortConfig mConfig;
|
||||
};
|
||||
|
||||
template <typename PropType, class Instance, typename Getter, typename Setter>
|
||||
void TestAccessors(Instance* inst, Getter getter, Setter setter,
|
||||
const std::vector<PropType>& validValues,
|
||||
const std::vector<PropType>& invalidValues, bool* isSupported) {
|
||||
PropType initialValue{};
|
||||
ScopedAStatus status = (inst->*getter)(&initialValue);
|
||||
if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
|
||||
*isSupported = false;
|
||||
return;
|
||||
}
|
||||
*isSupported = true;
|
||||
for (const auto v : validValues) {
|
||||
EXPECT_IS_OK((inst->*setter)(v)) << "for valid value: " << v;
|
||||
PropType currentValue{};
|
||||
EXPECT_IS_OK((inst->*getter)(¤tValue));
|
||||
EXPECT_EQ(v, currentValue);
|
||||
}
|
||||
for (const auto v : invalidValues) {
|
||||
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, (inst->*setter)(v)) << "for invalid value: " << v;
|
||||
}
|
||||
EXPECT_IS_OK((inst->*setter)(initialValue)) << "Failed to restore the initial value";
|
||||
}
|
||||
|
||||
// Can be used as a base for any test here, does not depend on the fixture GTest parameters.
|
||||
class AudioCoreModuleBase {
|
||||
public:
|
||||
@@ -1242,6 +1268,112 @@ TEST_P(AudioCoreModule, ExternalDevicePortRoutes) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreModule, MasterMute) {
|
||||
bool isSupported = false;
|
||||
EXPECT_NO_FATAL_FAILURE(TestAccessors<bool>(module.get(), &IModule::getMasterMute,
|
||||
&IModule::setMasterMute, {false, true}, {},
|
||||
&isSupported));
|
||||
if (!isSupported) {
|
||||
GTEST_SKIP() << "Master mute is not supported";
|
||||
}
|
||||
// TODO: Test that master mute actually mutes output.
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreModule, MasterVolume) {
|
||||
bool isSupported = false;
|
||||
EXPECT_NO_FATAL_FAILURE(TestAccessors<float>(
|
||||
module.get(), &IModule::getMasterVolume, &IModule::setMasterVolume, {0.0f, 0.5f, 1.0f},
|
||||
{-0.1, 1.1, NAN, INFINITY, -INFINITY, 1 + std::numeric_limits<float>::epsilon()},
|
||||
&isSupported));
|
||||
if (!isSupported) {
|
||||
GTEST_SKIP() << "Master volume is not supported";
|
||||
}
|
||||
// TODO: Test that master volume actually attenuates output.
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreModule, MicMute) {
|
||||
bool isSupported = false;
|
||||
EXPECT_NO_FATAL_FAILURE(TestAccessors<bool>(module.get(), &IModule::getMicMute,
|
||||
&IModule::setMicMute, {false, true}, {},
|
||||
&isSupported));
|
||||
if (!isSupported) {
|
||||
GTEST_SKIP() << "Mic mute is not supported";
|
||||
}
|
||||
// TODO: Test that mic mute actually mutes input.
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreModule, UpdateAudioMode) {
|
||||
for (const auto mode : ::ndk::enum_range<AudioMode>()) {
|
||||
EXPECT_IS_OK(module->updateAudioMode(mode)) << toString(mode);
|
||||
}
|
||||
EXPECT_IS_OK(module->updateAudioMode(AudioMode::NORMAL));
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreModule, UpdateScreenRotation) {
|
||||
for (const auto rotation : ::ndk::enum_range<IModule::ScreenRotation>()) {
|
||||
EXPECT_IS_OK(module->updateScreenRotation(rotation)) << toString(rotation);
|
||||
}
|
||||
EXPECT_IS_OK(module->updateScreenRotation(IModule::ScreenRotation::DEG_0));
|
||||
}
|
||||
|
||||
TEST_P(AudioCoreModule, UpdateScreenState) {
|
||||
EXPECT_IS_OK(module->updateScreenState(false));
|
||||
EXPECT_IS_OK(module->updateScreenState(true));
|
||||
}
|
||||
|
||||
class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
|
||||
ASSERT_IS_OK(module->getTelephony(&telephony));
|
||||
}
|
||||
|
||||
void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
|
||||
|
||||
std::shared_ptr<ITelephony> telephony;
|
||||
};
|
||||
|
||||
TEST_P(AudioCoreTelephony, GetSupportedAudioModes) {
|
||||
if (telephony == nullptr) {
|
||||
GTEST_SKIP() << "Telephony is not supported";
|
||||
}
|
||||
std::vector<AudioMode> modes1;
|
||||
ASSERT_IS_OK(telephony->getSupportedAudioModes(&modes1));
|
||||
const std::vector<AudioMode> kMandatoryModes = {AudioMode::NORMAL, AudioMode::RINGTONE,
|
||||
AudioMode::IN_CALL,
|
||||
AudioMode::IN_COMMUNICATION};
|
||||
for (const auto mode : kMandatoryModes) {
|
||||
EXPECT_NE(modes1.end(), std::find(modes1.begin(), modes1.end(), mode))
|
||||
<< "Mandatory mode not supported: " << toString(mode);
|
||||
}
|
||||
std::vector<AudioMode> modes2;
|
||||
ASSERT_IS_OK(telephony->getSupportedAudioModes(&modes2));
|
||||
ASSERT_EQ(modes1.size(), modes2.size())
|
||||
<< "Sizes of audio mode arrays do not match across consequent calls to "
|
||||
<< "getSupportedAudioModes";
|
||||
std::sort(modes1.begin(), modes1.end());
|
||||
std::sort(modes2.begin(), modes2.end());
|
||||
EXPECT_EQ(modes1, modes2);
|
||||
};
|
||||
|
||||
TEST_P(AudioCoreTelephony, SwitchAudioMode) {
|
||||
if (telephony == nullptr) {
|
||||
GTEST_SKIP() << "Telephony is not supported";
|
||||
}
|
||||
std::vector<AudioMode> supportedModes;
|
||||
ASSERT_IS_OK(telephony->getSupportedAudioModes(&supportedModes));
|
||||
std::set<AudioMode> unsupportedModes = {
|
||||
// Start with all, remove supported ones
|
||||
::ndk::enum_range<AudioMode>().begin(), ::ndk::enum_range<AudioMode>().end()};
|
||||
for (const auto mode : supportedModes) {
|
||||
EXPECT_IS_OK(telephony->switchAudioMode(mode)) << toString(mode);
|
||||
unsupportedModes.erase(mode);
|
||||
}
|
||||
for (const auto mode : unsupportedModes) {
|
||||
EXPECT_STATUS(EX_UNSUPPORTED_OPERATION, telephony->switchAudioMode(mode)) << toString(mode);
|
||||
}
|
||||
}
|
||||
|
||||
class StreamLogicDriverInvalidCommand : public StreamLogicDriver {
|
||||
public:
|
||||
StreamLogicDriverInvalidCommand(const std::vector<StreamDescriptor::Command>& commands)
|
||||
@@ -1825,6 +1957,9 @@ TEST_P(AudioModulePatch, ResetInvalidPatchId) {
|
||||
INSTANTIATE_TEST_SUITE_P(AudioCoreModuleTest, AudioCoreModule,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
|
||||
android::PrintInstanceNameToString);
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreModule);
|
||||
INSTANTIATE_TEST_SUITE_P(AudioStreamInTest, AudioStreamIn,
|
||||
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
|
||||
|
||||
Reference in New Issue
Block a user