Skip to content

Commit

Permalink
Merge AP3A.240614.001
Browse files Browse the repository at this point in the history
Change-Id: Ib251394a914e94ff160f0a346cd6518c5674a2e4
  • Loading branch information
Scott Lobdell committed Jun 25, 2024
2 parents 9bdc8c1 + 43b3318 commit 4c76c47
Show file tree
Hide file tree
Showing 27 changed files with 511 additions and 81 deletions.
1 change: 1 addition & 0 deletions camera/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ filegroup {
name: "libcamera_client_aidl",
srcs: [
"aidl/android/hardware/CameraExtensionSessionStats.aidl",
"aidl/android/hardware/CameraFeatureCombinationStats.aidl",
"aidl/android/hardware/ICameraService.aidl",
"aidl/android/hardware/ICameraServiceListener.aidl",
"aidl/android/hardware/ICameraServiceProxy.aidl",
Expand Down
47 changes: 47 additions & 0 deletions camera/aidl/android/hardware/CameraFeatureCombinationStats.aidl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2024 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;

/**
* {@hide}
*/
parcelable CameraFeatureCombinationStats {
/**
* Values for feature combination queries
*/
const long CAMERA_FEATURE_UNKNOWN = 0;
const long CAMERA_FEATURE_60_FPS = 1 << 0;
const long CAMERA_FEATURE_STABILIZATION = 1 << 1;
const long CAMERA_FEATURE_HLG10 = 1 << 2;
const long CAMERA_FEATURE_JPEG = 1 << 3;
const long CAMERA_FEATURE_JPEG_R = 1 << 4;
const long CAMERA_FEATURE_4K = 1 << 5;

/**
* Values for notifyFeatureCombinationStats type
*/
enum QueryType {
QUERY_FEATURE_COMBINATION = 0,
QUERY_SESSION_CHARACTERISTICS = 1,
}

@utf8InCpp String mCameraId;
int mUid;
long mFeatureCombination;
int mQueryType;
int mStatus;
}
7 changes: 7 additions & 0 deletions camera/aidl/android/hardware/ICameraServiceProxy.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package android.hardware;

import android.hardware.CameraFeatureCombinationStats;
import android.hardware.CameraSessionStats;
import android.hardware.CameraExtensionSessionStats;

Expand All @@ -37,6 +38,12 @@ interface ICameraServiceProxy
*/
oneway void notifyCameraState(in CameraSessionStats cameraSessionStats);

/**
* Notify feature combination query for a camera device.
*/
oneway void notifyFeatureCombinationStats(
in CameraFeatureCombinationStats cameraFeatureCombinationStats);

/**
* Returns the necessary rotate and crop override for the top activity which
* will be one of ({@link android.hardware.camera2.CameraMetadata#SCALER_ROTATE_AND_CROP_NONE},
Expand Down
16 changes: 12 additions & 4 deletions media/audio/aconfig/audioserver.aconfig
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ flag {
bug: "339515899"
}

flag {
name: "fix_input_sharing_logic"
namespace: "media_audio"
description:
"Fix the audio policy logic that decides to reuse or close "
"input streams when resources are exhausted"
bug: "338446410"
}

flag {
name: "mutex_priority_inheritance"
namespace: "media_audio"
Expand All @@ -48,10 +57,9 @@ flag {
}

flag {
name: "fix_input_sharing_logic"
name: "use_bt_sco_for_media"
namespace: "media_audio"
description:
"Fix the audio policy logic that decides to reuse or close "
"input streams when resources are exhausted"
bug: "338446410"
"Play media strategy over Bluetooth SCO when active"
bug: "292037886"
}
4 changes: 3 additions & 1 deletion media/libaaudio/src/client/AudioStreamInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,17 +620,19 @@ aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& cli
audio_port_handle_t *portHandle) {
ALOGV("%s() called", __func__);
if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGE("%s() getServiceHandle() is invalid", __func__);
return AAUDIO_ERROR_INVALID_STATE;
}
aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandleInfo,
client, attr, portHandle);
ALOGV("%s(%d) returning %d", __func__, *portHandle, result);
ALOGV("%s(), got %d, returning %d", __func__, *portHandle, result);
return result;
}

aaudio_result_t AudioStreamInternal::stopClient(audio_port_handle_t portHandle) {
ALOGV("%s(%d) called", __func__, portHandle);
if (getServiceHandle() == AAUDIO_HANDLE_INVALID) {
ALOGE("%s(%d) getServiceHandle() is invalid", __func__, portHandle);
return AAUDIO_ERROR_INVALID_STATE;
}
aaudio_result_t result = mServiceInterface.stopClient(mServiceStreamHandleInfo, portHandle);
Expand Down
6 changes: 5 additions & 1 deletion media/libaudiohal/impl/DeviceHalAidl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,17 @@ status_t DeviceHalAidl::openOutputStream(
args.portConfigId = mixPortConfig.id;
const bool isOffload = isBitPositionFlagSet(
aidlOutputFlags, AudioOutputFlags::COMPRESS_OFFLOAD);
const bool isHwAvSync = isBitPositionFlagSet(
aidlOutputFlags, AudioOutputFlags::HW_AV_SYNC);
std::shared_ptr<OutputStreamCallbackAidl> streamCb;
if (isOffload) {
streamCb = ndk::SharedRefBase::make<OutputStreamCallbackAidl>(this);
}
auto eventCb = ndk::SharedRefBase::make<OutputStreamEventCallbackAidl>(this);
if (isOffload) {
if (isOffload || isHwAvSync) {
args.offloadInfo = aidlConfig.offloadInfo;
}
if (isOffload) {
args.callback = streamCb;
}
args.bufferSizeFrames = aidlConfig.frameCount;
Expand Down
35 changes: 25 additions & 10 deletions media/libaudiohal/impl/Hal2AidlMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
using aidl::android::media::audio::common::AudioGainConfig;
using aidl::android::media::audio::common::AudioInputFlags;
using aidl::android::media::audio::common::AudioIoFlags;
using aidl::android::media::audio::common::AudioOutputFlags;
Expand Down Expand Up @@ -325,8 +326,8 @@ status_t Hal2AidlMapper::findOrCreatePatch(
}

status_t Hal2AidlMapper::findOrCreateDevicePortConfig(
const AudioDevice& device, const AudioConfig* config, AudioPortConfig* portConfig,
bool* created) {
const AudioDevice& device, const AudioConfig* config, const AudioGainConfig* gainConfig,
AudioPortConfig* portConfig, bool* created) {
if (auto portConfigIt = findPortConfig(device); portConfigIt == mPortConfigs.end()) {
auto portsIt = findPort(device);
if (portsIt == mPorts.end()) {
Expand All @@ -339,12 +340,18 @@ status_t Hal2AidlMapper::findOrCreateDevicePortConfig(
if (config != nullptr) {
setPortConfigFromConfig(&requestedPortConfig, *config);
}
if (gainConfig != nullptr) {
requestedPortConfig.gain = *gainConfig;
}
return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created);
} else {
AudioPortConfig requestedPortConfig = portConfigIt->second;
if (config != nullptr) {
setPortConfigFromConfig(&requestedPortConfig, *config);
}
if (gainConfig != nullptr) {
requestedPortConfig.gain = *gainConfig;
}

if (requestedPortConfig != portConfigIt->second) {
return createOrUpdatePortConfigRetry(requestedPortConfig, portConfig, created);
Expand Down Expand Up @@ -447,18 +454,26 @@ status_t Hal2AidlMapper::findOrCreatePortConfig(
requestedPortConfig.ext.get<Tag::mix>().handle, source, destinationPortIds,
portConfig, created);
} else if (requestedPortConfig.ext.getTag() == Tag::device) {
if (const auto& p = requestedPortConfig;
p.sampleRate.has_value() && p.channelMask.has_value() &&
p.format.has_value()) {
AudioConfig config;
setConfigFromPortConfig(&config, requestedPortConfig);
const auto& p = requestedPortConfig;
const bool hasAudioConfig =
p.sampleRate.has_value() && p.channelMask.has_value() && p.format.has_value();
const bool hasGainConfig = p.gain.has_value();
if (hasAudioConfig || hasGainConfig) {
AudioConfig config, *configPtr = nullptr;
if (hasAudioConfig) {
setConfigFromPortConfig(&config, requestedPortConfig);
configPtr = &config;
}
const AudioGainConfig* gainConfigPtr = nullptr;
if (hasGainConfig) gainConfigPtr = &(*(p.gain));
return findOrCreateDevicePortConfig(
requestedPortConfig.ext.get<Tag::device>().device, &config,
requestedPortConfig.ext.get<Tag::device>().device, configPtr, gainConfigPtr,
portConfig, created);
} else {
ALOGD("%s: device port config does not have audio or gain config specified", __func__);
return findOrCreateDevicePortConfig(
requestedPortConfig.ext.get<Tag::device>().device, nullptr /*config*/,
portConfig, created);
nullptr /*gainConfig*/, portConfig, created);
}
}
ALOGW("%s: unsupported audio port config: %s",
Expand Down Expand Up @@ -769,7 +784,7 @@ status_t Hal2AidlMapper::prepareToOpenStream(
// then find / create a patch between them, and open a stream on the mix port.
AudioPortConfig devicePortConfig;
bool created = false;
RETURN_STATUS_IF_ERROR(findOrCreateDevicePortConfig(device, config,
RETURN_STATUS_IF_ERROR(findOrCreateDevicePortConfig(device, config, nullptr /*gainConfig*/,
&devicePortConfig, &created));
LOG_ALWAYS_FATAL_IF(devicePortConfig.id == 0);
if (created) {
Expand Down
1 change: 1 addition & 0 deletions media/libaudiohal/impl/Hal2AidlMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class Hal2AidlMapper {
status_t findOrCreateDevicePortConfig(
const ::aidl::android::media::audio::common::AudioDevice& device,
const ::aidl::android::media::audio::common::AudioConfig* config,
const ::aidl::android::media::audio::common::AudioGainConfig* gainConfig,
::aidl::android::media::audio::common::AudioPortConfig* portConfig,
bool* created);
// If the resulting 'portConfig->id' is 0, that means the config was not created,
Expand Down
80 changes: 80 additions & 0 deletions media/libaudiohal/tests/CoreAudioHalAidl_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <aidl/android/hardware/audio/core/BnModule.h>
#include <aidl/android/hardware/audio/core/BnStreamCommon.h>
#include <aidl/android/media/audio/BnHalAdapterVendorExtension.h>
#include <aidl/android/media/audio/common/AudioGainMode.h>
#include <aidl/android/media/audio/common/Int.h>
#include <utils/Log.h>

Expand All @@ -44,6 +45,8 @@ using ::aidl::android::media::audio::common::AudioDeviceDescription;
using ::aidl::android::media::audio::common::AudioDeviceType;
using ::aidl::android::media::audio::common::AudioFormatDescription;
using ::aidl::android::media::audio::common::AudioFormatType;
using ::aidl::android::media::audio::common::AudioGainConfig;
using ::aidl::android::media::audio::common::AudioGainMode;
using ::aidl::android::media::audio::common::AudioIoFlags;
using ::aidl::android::media::audio::common::AudioPort;
using ::aidl::android::media::audio::common::AudioPortConfig;
Expand Down Expand Up @@ -179,6 +182,11 @@ Configuration getTestConfiguration() {
primaryInMix.profiles = standardPcmAudioProfiles;
c.ports.push_back(primaryInMix);

AudioPort speakerOutDevice = createPort(c.nextPortId++, "Speaker", 0, false,
createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0));
speakerOutDevice.profiles = standardPcmAudioProfiles;
c.ports.push_back(speakerOutDevice);

AudioPort btOutDevice =
createPort(c.nextPortId++, "BT A2DP Out", 0, false,
createPortDeviceExt(AudioDeviceType::OUT_DEVICE, 0,
Expand Down Expand Up @@ -209,6 +217,13 @@ class ModuleMock : public ::aidl::android::hardware::audio::core::BnModule,
getAudioPatches(&result);
return result;
}
std::optional<AudioPortConfig> getPortConfig(int32_t id) {
auto iter = findById<AudioPortConfig>(mConfig.portConfigs, id);
if (iter != mConfig.portConfigs.end()) {
return *iter;
}
return std::nullopt;
}

private:
ndk::ScopedAStatus setModuleDebug(
Expand Down Expand Up @@ -646,6 +661,19 @@ std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os,
}
} // namespace aidl::android::hardware::audio::core

namespace aidl::android::media::audio::common {
template <typename P>
std::enable_if_t<std::is_function_v<typename mf_traits<decltype(&P::toString)>::member_type>,
std::ostream&>
operator<<(std::ostream& os, const P& p) {
return os << p.toString();
}
template <typename E>
std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) {
return os << toString(e);
}
} // namespace aidl::android::media::audio::common

using namespace android;

namespace {
Expand Down Expand Up @@ -1214,3 +1242,55 @@ TEST_F(Hal2AidlMapperTest, ChangeTransientPatchDevice) {
EXPECT_EQ(std::vector<int32_t>{backMicPortConfig.id}, patchIt->sourcePortConfigIds);
EXPECT_EQ(std::vector<int32_t>{mixPortConfig.id}, patchIt->sinkPortConfigIds);
}

TEST_F(Hal2AidlMapperTest, SetAudioPortConfigGainChangeExistingPortConfig) {
// First set config, then update gain.
AudioPortConfig speakerPortConfig;
speakerPortConfig.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0);
speakerPortConfig.channelMask = AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
AudioChannelLayout::LAYOUT_STEREO);
speakerPortConfig.format =
AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = PcmType::INT_16_BIT};
speakerPortConfig.sampleRate = ::aidl::android::media::audio::common::Int(48000);
AudioPortConfig resultingPortConfig;
ASSERT_EQ(OK,
mMapper->setPortConfig(speakerPortConfig, std::set<int32_t>(), &resultingPortConfig));
EXPECT_NE(0, resultingPortConfig.id);
EXPECT_NE(0, resultingPortConfig.portId);

AudioPortConfig gainUpdate;
gainUpdate.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0);
AudioGainConfig gainConfig{.index = -1,
.mode = 1 << static_cast<int>(AudioGainMode::JOINT),
.channelMask = AudioChannelLayout{},
.values = std::vector<int32_t>{-3200},
.rampDurationMs = 0};
gainUpdate.gain = gainConfig;
AudioPortConfig resultingGainUpdate;
ASSERT_EQ(OK, mMapper->setPortConfig(gainUpdate, std::set<int32_t>(), &resultingGainUpdate));
EXPECT_EQ(resultingPortConfig.id, resultingGainUpdate.id);
auto updatedPortConfig = mModule->getPortConfig(resultingGainUpdate.id);
ASSERT_TRUE(updatedPortConfig.has_value());
ASSERT_TRUE(updatedPortConfig->gain.has_value());
EXPECT_EQ(gainConfig, updatedPortConfig->gain);
}

TEST_F(Hal2AidlMapperTest, SetAudioPortConfigGainChangeFromScratch) {
// Set gain as the first operation, the HAL should suggest the rest of the configuration.
AudioPortConfig gainSet;
gainSet.ext = createPortDeviceExt(AudioDeviceType::OUT_SPEAKER, 0);
AudioGainConfig gainConfig{.index = -1,
.mode = 1 << static_cast<int>(AudioGainMode::JOINT),
.channelMask = AudioChannelLayout{},
.values = std::vector<int32_t>{-3200},
.rampDurationMs = 0};
gainSet.gain = gainConfig;
AudioPortConfig resultingPortConfig;
ASSERT_EQ(OK, mMapper->setPortConfig(gainSet, std::set<int32_t>(), &resultingPortConfig));
EXPECT_NE(0, resultingPortConfig.id);
EXPECT_NE(0, resultingPortConfig.portId);
auto portConfig = mModule->getPortConfig(resultingPortConfig.id);
ASSERT_TRUE(portConfig.has_value());
ASSERT_TRUE(portConfig->gain.has_value());
EXPECT_EQ(gainConfig, portConfig->gain);
}
3 changes: 2 additions & 1 deletion services/audioflinger/AudioFlinger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3951,7 +3951,8 @@ void AudioFlinger::updateSecondaryOutputsForTrack_l(
patchRecord->bufferSize(),
outputFlags,
0ns /* timeout */,
frameCountToBeReady);
frameCountToBeReady,
track->getSpeed());
status = patchTrack->initCheck();
if (status != NO_ERROR) {
ALOGE("Secondary output patchTrack init failed: %d", status);
Expand Down
5 changes: 3 additions & 2 deletions services/audioflinger/IAfTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,10 +579,11 @@ class IAfPatchTrack : public virtual IAfTrack, public virtual IAfPatchTrackBase
size_t bufferSize,
audio_output_flags_t flags,
const Timeout& timeout = {},
size_t frameCountToBeReady = 1 /** Default behaviour is to start
size_t frameCountToBeReady = 1, /** Default behaviour is to start
* as soon as possible to have
* the lowest possible latency
* even if it might glitch. */);
* even if it might glitch. */
float speed = 1.0f);
};

class IAfPatchRecord : public virtual IAfRecordTrack, public virtual IAfPatchTrackBase {
Expand Down
3 changes: 2 additions & 1 deletion services/audioflinger/PatchPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,8 @@ status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel)
tempRecordTrack->bufferSize(),
outputFlags,
{} /*timeout*/,
frameCountToBeReady);
frameCountToBeReady,
1.0f);
status = mPlayback.checkTrack(tempPatchTrack.get());
if (status != NO_ERROR) {
return status;
Expand Down
Loading

0 comments on commit 4c76c47

Please sign in to comment.