Merge "threadnetwork: Avoid execute command if service does not exist" into main
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index e325001..26f4b3a 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -72,12 +72,7 @@
"name": "audiosystem_tests"
},
{
- "name": "CtsVirtualDevicesTestCases",
- "options" : [
- {
- "include-filter": "android.virtualdevice.cts.VirtualAudioTest"
- }
- ]
+ "name": "CtsVirtualDevicesAudioTestCases"
}
]
}
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index f51f65e..73d7626 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -62,7 +62,6 @@
"ModulePrimary.cpp",
"SoundDose.cpp",
"Stream.cpp",
- "StreamSwitcher.cpp",
"Telephony.cpp",
"XsdcConversion.cpp",
"alsa/Mixer.cpp",
@@ -72,11 +71,13 @@
"bluetooth/DevicePortProxy.cpp",
"bluetooth/ModuleBluetooth.cpp",
"bluetooth/StreamBluetooth.cpp",
+ "deprecated/StreamSwitcher.cpp",
"primary/PrimaryMixer.cpp",
"primary/StreamPrimary.cpp",
"r_submix/ModuleRemoteSubmix.cpp",
"r_submix/SubmixRoute.cpp",
"r_submix/StreamRemoteSubmix.cpp",
+ "stub/DriverStubImpl.cpp",
"stub/ModuleStub.cpp",
"stub/StreamStub.cpp",
"usb/ModuleUsb.cpp",
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 54e2d18..0ff8eb4 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -324,9 +324,9 @@
//
// Mix ports:
// * "r_submix output", maximum 10 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
// * "r_submix input", maximum 10 opened streams, maximum 10 active streams
-// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
+// - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
//
// Routes:
// "r_submix output" -> "Remote Submix Out"
@@ -337,7 +337,7 @@
Configuration c;
const std::vector<AudioProfile> remoteSubmixPcmAudioProfiles{
createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO},
- {8000, 11025, 16000, 32000, 44100, 48000})};
+ {8000, 11025, 16000, 32000, 44100, 48000, 192000})};
// Device ports
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index c14d06e..45ce5ef 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -47,6 +47,7 @@
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::AudioMMapPolicy;
@@ -1200,7 +1201,9 @@
}
if (in_requested.gain.has_value()) {
- // Let's pretend that gain can always be applied.
+ if (!setAudioPortConfigGain(*portIt, in_requested.gain.value())) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
out_suggested->gain = in_requested.gain.value();
}
@@ -1242,6 +1245,52 @@
return ndk::ScopedAStatus::ok();
}
+bool Module::setAudioPortConfigGain(const AudioPort& port, const AudioGainConfig& gainRequested) {
+ auto& ports = getConfig().ports;
+ if (gainRequested.index < 0 || gainRequested.index >= (int)port.gains.size()) {
+ LOG(ERROR) << __func__ << ": gains for port " << port.id << " is undefined";
+ return false;
+ }
+ int stepValue = port.gains[gainRequested.index].stepValue;
+ if (stepValue == 0) {
+ LOG(ERROR) << __func__ << ": port gain step value is 0";
+ return false;
+ }
+ int minValue = port.gains[gainRequested.index].minValue;
+ int maxValue = port.gains[gainRequested.index].maxValue;
+ if (gainRequested.values[0] > maxValue || gainRequested.values[0] < minValue) {
+ LOG(ERROR) << __func__ << ": gain value " << gainRequested.values[0]
+ << " out of range of min and max gain config";
+ return false;
+ }
+ int gainIndex = (gainRequested.values[0] - minValue) / stepValue;
+ int totalSteps = (maxValue - minValue) / stepValue;
+ if (totalSteps == 0) {
+ LOG(ERROR) << __func__ << ": difference between port gain min value " << minValue
+ << " and max value " << maxValue << " is less than step value " << stepValue;
+ return false;
+ }
+ // Root-power quantities are used in curve:
+ // 10^((minMb / 100 + (maxMb / 100 - minMb / 100) * gainIndex / totalSteps) / (10 * 2))
+ // where 100 is the conversion from mB to dB, 10 comes from the log 10 conversion from power
+ // ratios, and 2 means are the square of amplitude.
+ float gain =
+ pow(10, (minValue + (maxValue - minValue) * (gainIndex / (float)totalSteps)) / 2000);
+ if (gain < 0) {
+ LOG(ERROR) << __func__ << ": gain " << gain << " is less than 0";
+ return false;
+ }
+ for (const auto& route : getConfig().routes) {
+ if (route.sinkPortId != port.id) {
+ continue;
+ }
+ for (const auto sourcePortId : route.sourcePortIds) {
+ mStreams.setGain(sourcePortId, gain);
+ }
+ }
+ return true;
+}
+
ndk::ScopedAStatus Module::resetAudioPatch(int32_t in_patchId) {
auto& patches = getConfig().patches;
auto patchIt = findById<AudioPatch>(patches, in_patchId);
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index 3e4650d..de66293 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -855,6 +855,11 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus StreamCommonImpl::setGain(float gain) {
+ LOG(DEBUG) << __func__ << ": gain " << gain;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
ndk::ScopedAStatus StreamCommonImpl::bluetoothParametersUpdated() {
LOG(DEBUG) << __func__;
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp
index f548903..c77bfca 100644
--- a/audio/aidl/default/alsa/StreamAlsa.cpp
+++ b/audio/aidl/default/alsa/StreamAlsa.cpp
@@ -75,6 +75,10 @@
}
decltype(mAlsaDeviceProxies) alsaDeviceProxies;
for (const auto& device : getDeviceProfiles()) {
+ if ((device.direction == PCM_OUT && mIsInput) ||
+ (device.direction == PCM_IN && !mIsInput)) {
+ continue;
+ }
alsa::DeviceProxy proxy;
if (device.isExternal) {
// Always ask alsa configure as required since the configuration should be supported
@@ -92,6 +96,9 @@
}
alsaDeviceProxies.push_back(std::move(proxy));
}
+ if (alsaDeviceProxies.empty()) {
+ return ::android::NO_INIT;
+ }
mAlsaDeviceProxies = std::move(alsaDeviceProxies);
return ::android::OK;
}
@@ -110,6 +117,7 @@
mReadWriteRetries);
maxLatency = proxy_get_latency(mAlsaDeviceProxies[0].get());
} else {
+ alsa::applyGain(buffer, mGain, bytesToTransfer, mConfig.value().format, mConfig->channels);
for (auto& proxy : mAlsaDeviceProxies) {
proxy_write_with_retries(proxy.get(), buffer, bytesToTransfer, mReadWriteRetries);
maxLatency = std::max(maxLatency, proxy_get_latency(proxy.get()));
@@ -159,4 +167,9 @@
mAlsaDeviceProxies.clear();
}
+ndk::ScopedAStatus StreamAlsa::setGain(float gain) {
+ mGain = gain;
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/alsa/Utils.cpp b/audio/aidl/default/alsa/Utils.cpp
index 8eaf162..10374f2 100644
--- a/audio/aidl/default/alsa/Utils.cpp
+++ b/audio/aidl/default/alsa/Utils.cpp
@@ -22,6 +22,8 @@
#include <aidl/android/media/audio/common/AudioFormatType.h>
#include <aidl/android/media/audio/common/PcmType.h>
#include <android-base/logging.h>
+#include <audio_utils/primitives.h>
+#include <cutils/compiler.h>
#include "Utils.h"
#include "core-impl/utils.h"
@@ -343,4 +345,68 @@
return findValueOrDefault(getAudioFormatDescriptorToPcmFormatMap(), aidl, PCM_FORMAT_INVALID);
}
+void applyGain(void* buffer, float gain, size_t bytesToTransfer, enum pcm_format pcmFormat,
+ int channelCount) {
+ if (channelCount != 1 && channelCount != 2) {
+ LOG(WARNING) << __func__ << ": unsupported channel count " << channelCount;
+ return;
+ }
+ if (!getPcmFormatToAudioFormatDescMap().contains(pcmFormat)) {
+ LOG(WARNING) << __func__ << ": unsupported pcm format " << pcmFormat;
+ return;
+ }
+ const float unityGainFloat = 1.0f;
+ if (std::abs(gain - unityGainFloat) < 1e-6) {
+ return;
+ }
+ int numFrames;
+ switch (pcmFormat) {
+ case PCM_FORMAT_S16_LE: {
+ const uint16_t unityGainQ4_12 = u4_12_from_float(unityGainFloat);
+ const uint16_t vl = u4_12_from_float(gain);
+ const uint32_t vrl = (vl << 16) | vl;
+ if (channelCount == 2) {
+ numFrames = bytesToTransfer / sizeof(uint32_t);
+ uint32_t* intBuffer = (uint32_t*)buffer;
+ if (CC_UNLIKELY(vl > unityGainQ4_12)) {
+ // volume is boosted, so we might need to clamp even though
+ // we process only one track.
+ do {
+ int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
+ int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
+ l = clamp16(l);
+ r = clamp16(r);
+ *intBuffer++ = (r << 16) | (l & 0xFFFF);
+ } while (--numFrames);
+ } else {
+ do {
+ int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
+ int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
+ *intBuffer++ = (r << 16) | (l & 0xFFFF);
+ } while (--numFrames);
+ }
+ } else {
+ numFrames = bytesToTransfer / sizeof(uint16_t);
+ int16_t* intBuffer = (int16_t*)buffer;
+ if (CC_UNLIKELY(vl > unityGainQ4_12)) {
+ // volume is boosted, so we might need to clamp even though
+ // we process only one track.
+ do {
+ int32_t mono = mulRL(1, *intBuffer, vrl) >> 12;
+ *intBuffer++ = clamp16(mono);
+ } while (--numFrames);
+ } else {
+ do {
+ int32_t mono = mulRL(1, *intBuffer, vrl) >> 12;
+ *intBuffer++ = static_cast<int16_t>(mono & 0xFFFF);
+ } while (--numFrames);
+ }
+ }
+ } break;
+ default:
+ // TODO(336370745): Implement gain for other supported formats
+ break;
+ }
+}
+
} // namespace aidl::android::hardware::audio::core::alsa
diff --git a/audio/aidl/default/alsa/Utils.h b/audio/aidl/default/alsa/Utils.h
index 980f685..a97ea10 100644
--- a/audio/aidl/default/alsa/Utils.h
+++ b/audio/aidl/default/alsa/Utils.h
@@ -59,6 +59,8 @@
AlsaProxy mProxy;
};
+void applyGain(void* buffer, float gain, size_t bytesToTransfer, enum pcm_format pcmFormat,
+ int channelCount);
::aidl::android::media::audio::common::AudioChannelLayout getChannelLayoutMaskFromChannelCount(
unsigned int channelCount, int isInput);
::aidl::android::media::audio::common::AudioChannelLayout getChannelIndexMaskFromChannelCount(
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
index 3547f54..e57c108 100644
--- a/audio/aidl/default/config/audioPolicy/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -191,6 +191,7 @@
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AAC_XHE;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC3;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC4;
+ enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AC4_L4;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_ALAC;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_NB;
enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_AMR_WB;
diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
index d93f697..108a6a3 100644
--- a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
@@ -389,6 +389,7 @@
<xs:enumeration value="AUDIO_FORMAT_APTX"/>
<xs:enumeration value="AUDIO_FORMAT_APTX_HD"/>
<xs:enumeration value="AUDIO_FORMAT_AC4"/>
+ <xs:enumeration value="AUDIO_FORMAT_AC4_L4"/>
<xs:enumeration value="AUDIO_FORMAT_LDAC"/>
<xs:enumeration value="AUDIO_FORMAT_MAT"/>
<xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/>
diff --git a/audio/aidl/default/StreamSwitcher.cpp b/audio/aidl/default/deprecated/StreamSwitcher.cpp
similarity index 95%
rename from audio/aidl/default/StreamSwitcher.cpp
rename to audio/aidl/default/deprecated/StreamSwitcher.cpp
index 8ba15a8..f1e0f52 100644
--- a/audio/aidl/default/StreamSwitcher.cpp
+++ b/audio/aidl/default/deprecated/StreamSwitcher.cpp
@@ -23,12 +23,12 @@
#include <error/expected_utils.h>
#include "core-impl/StreamStub.h"
-#include "core-impl/StreamSwitcher.h"
+#include "deprecated/StreamSwitcher.h"
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::media::audio::common::AudioDevice;
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::deprecated {
StreamSwitcher::StreamSwitcher(StreamContext* context, const Metadata& metadata)
: mContext(context),
@@ -260,4 +260,12 @@
return mStream->bluetoothParametersUpdated();
}
-} // namespace aidl::android::hardware::audio::core
+ndk::ScopedAStatus StreamSwitcher::setGain(float gain) {
+ if (mStream == nullptr) {
+ LOG(ERROR) << __func__ << ": stream was closed";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ return mStream->setGain(gain);
+}
+
+} // namespace aidl::android::hardware::audio::core::deprecated
diff --git a/audio/aidl/default/include/core-impl/StreamSwitcher.h b/audio/aidl/default/deprecated/StreamSwitcher.h
similarity index 95%
rename from audio/aidl/default/include/core-impl/StreamSwitcher.h
rename to audio/aidl/default/deprecated/StreamSwitcher.h
index 5764ad6..56fdd23 100644
--- a/audio/aidl/default/include/core-impl/StreamSwitcher.h
+++ b/audio/aidl/default/deprecated/StreamSwitcher.h
@@ -14,11 +14,18 @@
* limitations under the License.
*/
+/**
+ ** This class is deprecated because its use causes threading issues
+ ** with the FMQ due to change of threads reading and writing into FMQ.
+ **
+ ** DO NOT USE. These files will be removed.
+ **/
+
#pragma once
-#include "Stream.h"
+#include "core-impl/Stream.h"
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::deprecated {
// 'StreamSwitcher' is an implementation of 'StreamCommonInterface' which allows
// dynamically switching the underlying stream implementation based on currently
@@ -130,6 +137,7 @@
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
override;
ndk::ScopedAStatus bluetoothParametersUpdated() override;
+ ndk::ScopedAStatus setGain(float gain) override;
protected:
// Since switching a stream requires closing down the current stream, StreamSwitcher
@@ -191,4 +199,4 @@
bool mBluetoothParametersUpdated = false;
};
-} // namespace aidl::android::hardware::audio::core
+} // namespace aidl::android::hardware::audio::core::deprecated
diff --git a/audio/aidl/default/include/core-impl/DriverStubImpl.h b/audio/aidl/default/include/core-impl/DriverStubImpl.h
new file mode 100644
index 0000000..40a9fea
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/DriverStubImpl.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "core-impl/Stream.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class DriverStubImpl : virtual public DriverInterface {
+ public:
+ explicit DriverStubImpl(const StreamContext& context);
+
+ ::android::status_t init() override;
+ ::android::status_t drain(StreamDescriptor::DrainMode) override;
+ ::android::status_t flush() override;
+ ::android::status_t pause() override;
+ ::android::status_t standby() override;
+ ::android::status_t start() override;
+ ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+ int32_t* latencyMs) override;
+ void shutdown() override;
+
+ private:
+ const size_t mBufferSizeFrames;
+ const size_t mFrameSizeBytes;
+ const int mSampleRate;
+ const bool mIsAsynchronous;
+ const bool mIsInput;
+ bool mIsInitialized = false; // Used for validating the state machine logic.
+ bool mIsStandby = true; // Used for validating the state machine logic.
+ int64_t mStartTimeNs = 0;
+ long mFramesSinceStart = 0;
+};
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 00eeb4e..8548aff 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -263,6 +263,9 @@
::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied);
ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch,
const AudioPatch& newPatch);
+ bool setAudioPortConfigGain(
+ const ::aidl::android::media::audio::common::AudioPort& port,
+ const ::aidl::android::media::audio::common::AudioGainConfig& gainRequested);
};
std::ostream& operator<<(std::ostream& os, Module::Type t);
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 100b4c8..f7b9269 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -38,6 +38,7 @@
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
#include <aidl/android/media/audio/common/MicrophoneInfo.h>
+#include <android-base/thread_annotations.h>
#include <error/expected_utils.h>
#include <fmq/AidlMessageQueue.h>
#include <system/thread_defs.h>
@@ -132,6 +133,9 @@
ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
int getTransientStateDelayMs() const { return mDebugParameters.transientStateDelayMs; }
int getSampleRate() const { return mSampleRate; }
+ bool isInput() const {
+ return mFlags.getTag() == ::aidl::android::media::audio::common::AudioIoFlags::input;
+ }
bool isValid() const;
// 'reset' is called on a Binder thread when closing the stream. Does not use
// locking because it only cleans MQ pointers which were also set on the Binder thread.
@@ -342,6 +346,7 @@
virtual ndk::ScopedAStatus setConnectedDevices(
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) = 0;
virtual ndk::ScopedAStatus bluetoothParametersUpdated() = 0;
+ virtual ndk::ScopedAStatus setGain(float gain) = 0;
};
// This is equivalent to automatically generated 'IStreamCommonDelegator' but uses
@@ -443,6 +448,7 @@
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
override;
ndk::ScopedAStatus bluetoothParametersUpdated() override;
+ ndk::ScopedAStatus setGain(float gain) override;
protected:
static StreamWorkerInterface::CreateInstance getDefaultInWorkerCreator() {
@@ -609,6 +615,12 @@
return ndk::ScopedAStatus::ok();
}
+ ndk::ScopedAStatus setGain(float gain) {
+ auto s = mStream.lock();
+ if (s) return s->setGain(gain);
+ return ndk::ScopedAStatus::ok();
+ }
+
private:
std::weak_ptr<StreamCommonInterface> mStream;
ndk::SpAIBinder mStreamBinder;
@@ -644,6 +656,12 @@
return isOk ? ndk::ScopedAStatus::ok()
: ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+ ndk::ScopedAStatus setGain(int32_t portId, float gain) {
+ if (auto it = mStreams.find(portId); it != mStreams.end()) {
+ return it->second.setGain(gain);
+ }
+ return ndk::ScopedAStatus::ok();
+ }
private:
// Maps port ids and port config ids to streams. Multimap because a port
diff --git a/audio/aidl/default/include/core-impl/StreamAlsa.h b/audio/aidl/default/include/core-impl/StreamAlsa.h
index 0356946..8bdf208 100644
--- a/audio/aidl/default/include/core-impl/StreamAlsa.h
+++ b/audio/aidl/default/include/core-impl/StreamAlsa.h
@@ -45,6 +45,7 @@
int32_t* latencyMs) override;
::android::status_t refinePosition(StreamDescriptor::Position* position) override;
void shutdown() override;
+ ndk::ScopedAStatus setGain(float gain) override;
protected:
// Called from 'start' to initialize 'mAlsaDeviceProxies', the vector must be non-empty.
@@ -58,6 +59,9 @@
const int mReadWriteRetries;
// All fields below are only used on the worker thread.
std::vector<alsa::DeviceProxy> mAlsaDeviceProxies;
+
+ private:
+ std::atomic<float> mGain = 1.0;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h
index 8d5c57d..4f19a46 100644
--- a/audio/aidl/default/include/core-impl/StreamPrimary.h
+++ b/audio/aidl/default/include/core-impl/StreamPrimary.h
@@ -16,10 +16,14 @@
#pragma once
+#include <mutex>
#include <vector>
+#include <android-base/thread_annotations.h>
+
+#include "DriverStubImpl.h"
#include "StreamAlsa.h"
-#include "StreamSwitcher.h"
+#include "primary/PrimaryMixer.h"
namespace aidl::android::hardware::audio::core {
@@ -27,21 +31,54 @@
public:
StreamPrimary(StreamContext* context, const Metadata& metadata);
+ // Methods of 'DriverInterface'.
+ ::android::status_t init() override;
+ ::android::status_t drain(StreamDescriptor::DrainMode mode) override;
+ ::android::status_t flush() override;
+ ::android::status_t pause() override;
+ ::android::status_t standby() override;
::android::status_t start() override;
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
int32_t* latencyMs) override;
::android::status_t refinePosition(StreamDescriptor::Position* position) override;
+ void shutdown() override;
+
+ // Overridden methods of 'StreamCommonImpl', called on a Binder thread.
+ ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;
protected:
std::vector<alsa::DeviceProfile> getDeviceProfiles() override;
+ bool isStubStream();
const bool mIsAsynchronous;
int64_t mStartTimeNs = 0;
long mFramesSinceStart = 0;
bool mSkipNextTransfer = false;
+
+ private:
+ using AlsaDeviceId = std::pair<int, int>;
+
+ static constexpr StreamPrimary::AlsaDeviceId kDefaultCardAndDeviceId{
+ primary::PrimaryMixer::kAlsaCard, primary::PrimaryMixer::kAlsaDevice};
+ static constexpr StreamPrimary::AlsaDeviceId kStubDeviceId{
+ primary::PrimaryMixer::kInvalidAlsaCard, primary::PrimaryMixer::kInvalidAlsaDevice};
+
+ static AlsaDeviceId getCardAndDeviceId(
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices);
+ static bool useStubStream(bool isInput,
+ const ::aidl::android::media::audio::common::AudioDevice& device);
+
+ bool isStubStreamOnWorker() const { return mCurrAlsaDeviceId == kStubDeviceId; }
+
+ DriverStubImpl mStubDriver;
+ mutable std::mutex mLock;
+ AlsaDeviceId mAlsaDeviceId GUARDED_BY(mLock) = kStubDeviceId;
+
+ // Used by the worker thread only.
+ AlsaDeviceId mCurrAlsaDeviceId = kStubDeviceId;
};
-class StreamInPrimary final : public StreamIn, public StreamSwitcher, public StreamInHwGainHelper {
+class StreamInPrimary final : public StreamIn, public StreamPrimary, public StreamInHwGainHelper {
public:
friend class ndk::SharedRefBase;
StreamInPrimary(
@@ -50,14 +87,6 @@
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
private:
- static bool useStubStream(const ::aidl::android::media::audio::common::AudioDevice& device);
-
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getHwGain(std::vector<float>* _aidl_return) override;
@@ -65,7 +94,7 @@
};
class StreamOutPrimary final : public StreamOut,
- public StreamSwitcher,
+ public StreamPrimary,
public StreamOutHwVolumeHelper {
public:
friend class ndk::SharedRefBase;
@@ -75,22 +104,10 @@
offloadInfo);
private:
- static bool useStubStream(const ::aidl::android::media::audio::common::AudioDevice& device);
-
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getHwVolume(std::vector<float>* _aidl_return) override;
ndk::ScopedAStatus setHwVolume(const std::vector<float>& in_channelVolumes) override;
-
- ndk::ScopedAStatus setConnectedDevices(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 6ea7968..e78e8b7 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -16,19 +16,18 @@
#pragma once
+#include <atomic>
+#include <mutex>
#include <vector>
#include "core-impl/Stream.h"
-#include "core-impl/StreamSwitcher.h"
#include "r_submix/SubmixRoute.h"
namespace aidl::android::hardware::audio::core {
class StreamRemoteSubmix : public StreamCommonImpl {
public:
- StreamRemoteSubmix(
- StreamContext* context, const Metadata& metadata,
- const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
+ StreamRemoteSubmix(StreamContext* context, const Metadata& metadata);
~StreamRemoteSubmix();
// Methods of 'DriverInterface'.
@@ -45,17 +44,18 @@
// Overridden methods of 'StreamCommonImpl', called on a Binder thread.
ndk::ScopedAStatus prepareToClose() override;
+ ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;
private:
long getDelayInUsForFrameCount(size_t frameCount);
+ ::aidl::android::media::audio::common::AudioDeviceAddress getDeviceAddress() const {
+ std::lock_guard guard(mLock);
+ return mDeviceAddress;
+ }
size_t getStreamPipeSizeInFrames();
- ::android::status_t outWrite(void* buffer, size_t frameCount, size_t* actualFrameCount);
::android::status_t inRead(void* buffer, size_t frameCount, size_t* actualFrameCount);
-
- const ::aidl::android::media::audio::common::AudioDeviceAddress mDeviceAddress;
- const bool mIsInput;
- r_submix::AudioConfig mStreamConfig;
- std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
+ ::android::status_t outWrite(void* buffer, size_t frameCount, size_t* actualFrameCount);
+ ::android::status_t setCurrentRoute();
// Limit for the number of error log entries to avoid spamming the logs.
static constexpr int kMaxErrorLogs = 5;
@@ -66,6 +66,15 @@
// 5ms between two read attempts when pipe is empty
static constexpr int kReadAttemptSleepUs = 5000;
+ const bool mIsInput;
+ const r_submix::AudioConfig mStreamConfig;
+
+ mutable std::mutex mLock;
+ ::aidl::android::media::audio::common::AudioDeviceAddress mDeviceAddress GUARDED_BY(mLock);
+ std::atomic<bool> mDeviceAddressUpdated = false;
+
+ // Used by the worker thread only.
+ std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
int64_t mStartTimeNs = 0;
long mFramesSinceStart = 0;
int mReadErrorCount = 0;
@@ -73,7 +82,7 @@
int mWriteShutdownCount = 0;
};
-class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
+class StreamInRemoteSubmix final : public StreamIn, public StreamRemoteSubmix {
public:
friend class ndk::SharedRefBase;
StreamInRemoteSubmix(
@@ -82,19 +91,13 @@
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
private:
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
ndk::ScopedAStatus getActiveMicrophones(
std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
override;
};
-class StreamOutRemoteSubmix final : public StreamOut, public StreamSwitcher {
+class StreamOutRemoteSubmix final : public StreamOut, public StreamRemoteSubmix {
public:
friend class ndk::SharedRefBase;
StreamOutRemoteSubmix(
@@ -104,12 +107,6 @@
offloadInfo);
private:
- DeviceSwitchBehavior switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices)
- override;
- std::unique_ptr<StreamCommonInterfaceEx> createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) override;
void onClose(StreamDescriptor::State) override { defaultOnClose(); }
};
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
index 22b2020..cee44db 100644
--- a/audio/aidl/default/include/core-impl/StreamStub.h
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -16,38 +16,15 @@
#pragma once
+#include "core-impl/DriverStubImpl.h"
#include "core-impl/Stream.h"
namespace aidl::android::hardware::audio::core {
-class StreamStub : public StreamCommonImpl {
+class StreamStub : public StreamCommonImpl, public DriverStubImpl {
public:
StreamStub(StreamContext* context, const Metadata& metadata);
~StreamStub();
-
- // Methods of 'DriverInterface'.
- ::android::status_t init() override;
- ::android::status_t drain(StreamDescriptor::DrainMode) override;
- ::android::status_t flush() override;
- ::android::status_t pause() override;
- ::android::status_t standby() override;
- ::android::status_t start() override;
- ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
- int32_t* latencyMs) override;
- void shutdown() override;
-
- private:
- const size_t mBufferSizeFrames;
- const size_t mFrameSizeBytes;
- const int mSampleRate;
- const bool mIsAsynchronous;
- const bool mIsInput;
- bool mIsInitialized = false; // Used for validating the state machine logic.
- bool mIsStandby = true; // Used for validating the state machine logic.
-
- // Used by the worker thread.
- int64_t mStartTimeNs = 0;
- long mFramesSinceStart = 0;
};
class StreamInStub final : public StreamIn, public StreamStub {
diff --git a/audio/aidl/default/primary/PrimaryMixer.h b/audio/aidl/default/primary/PrimaryMixer.h
index 3806428..760d42f 100644
--- a/audio/aidl/default/primary/PrimaryMixer.h
+++ b/audio/aidl/default/primary/PrimaryMixer.h
@@ -16,20 +16,14 @@
#pragma once
-#include <map>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <android-base/thread_annotations.h>
-#include <android/binder_auto_utils.h>
-
#include "alsa/Mixer.h"
namespace aidl::android::hardware::audio::core::primary {
class PrimaryMixer : public alsa::Mixer {
public:
+ static constexpr int kInvalidAlsaCard = -1;
+ static constexpr int kInvalidAlsaDevice = -1;
static constexpr int kAlsaCard = 0;
static constexpr int kAlsaDevice = 0;
diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index 7325a91..c1c1f03 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -15,19 +15,22 @@
*/
#define LOG_TAG "AHAL_StreamPrimary"
+
+#include <cstdio>
+
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <audio_utils/clock.h>
#include <error/Result.h>
#include <error/expected_utils.h>
-#include "PrimaryMixer.h"
#include "core-impl/StreamPrimary.h"
-#include "core-impl/StreamStub.h"
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioOffloadInfo;
@@ -38,11 +41,49 @@
StreamPrimary::StreamPrimary(StreamContext* context, const Metadata& metadata)
: StreamAlsa(context, metadata, 3 /*readWriteRetries*/),
- mIsAsynchronous(!!getContext().getAsyncCallback()) {
+ mIsAsynchronous(!!getContext().getAsyncCallback()),
+ mStubDriver(getContext()) {
context->startStreamDataProcessor();
}
+::android::status_t StreamPrimary::init() {
+ RETURN_STATUS_IF_ERROR(mStubDriver.init());
+ return StreamAlsa::init();
+}
+
+::android::status_t StreamPrimary::drain(StreamDescriptor::DrainMode mode) {
+ return isStubStreamOnWorker() ? mStubDriver.drain(mode) : StreamAlsa::drain(mode);
+}
+
+::android::status_t StreamPrimary::flush() {
+ RETURN_STATUS_IF_ERROR(isStubStreamOnWorker() ? mStubDriver.flush() : StreamAlsa::flush());
+ // TODO(b/372951987): consider if this needs to be done from 'StreamInWorkerLogic::cycle'.
+ return mIsInput ? standby() : ::android::OK;
+}
+
+::android::status_t StreamPrimary::pause() {
+ return isStubStreamOnWorker() ? mStubDriver.pause() : StreamAlsa::pause();
+}
+
+::android::status_t StreamPrimary::standby() {
+ return isStubStreamOnWorker() ? mStubDriver.standby() : StreamAlsa::standby();
+}
+
::android::status_t StreamPrimary::start() {
+ bool isStub = true, shutdownAlsaStream = false;
+ {
+ std::lock_guard l(mLock);
+ isStub = mAlsaDeviceId == kStubDeviceId;
+ shutdownAlsaStream =
+ mCurrAlsaDeviceId != mAlsaDeviceId && mCurrAlsaDeviceId != kStubDeviceId;
+ mCurrAlsaDeviceId = mAlsaDeviceId;
+ }
+ if (shutdownAlsaStream) {
+ StreamAlsa::shutdown(); // Close currently opened ALSA devices.
+ }
+ if (isStub) {
+ return mStubDriver.start();
+ }
RETURN_STATUS_IF_ERROR(StreamAlsa::start());
mStartTimeNs = ::android::uptimeNanos();
mFramesSinceStart = 0;
@@ -52,6 +93,9 @@
::android::status_t StreamPrimary::transfer(void* buffer, size_t frameCount,
size_t* actualFrameCount, int32_t* latencyMs) {
+ if (isStubStreamOnWorker()) {
+ return mStubDriver.transfer(buffer, frameCount, actualFrameCount, latencyMs);
+ }
// This is a workaround for the emulator implementation which has a host-side buffer
// and is not being able to achieve real-time behavior similar to ADSPs (b/302587331).
if (!mSkipNextTransfer) {
@@ -91,63 +135,85 @@
return ::android::OK;
}
+void StreamPrimary::shutdown() {
+ StreamAlsa::shutdown();
+ mStubDriver.shutdown();
+}
+
+ndk::ScopedAStatus StreamPrimary::setConnectedDevices(const ConnectedDevices& devices) {
+ LOG(DEBUG) << __func__ << ": " << ::android::internal::ToString(devices);
+ if (devices.size() > 1) {
+ LOG(ERROR) << __func__ << ": primary stream can only be connected to one device, got: "
+ << devices.size();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ {
+ const bool useStubDriver = devices.empty() || useStubStream(mIsInput, devices[0]);
+ std::lock_guard l(mLock);
+ mAlsaDeviceId = useStubDriver ? kStubDeviceId : getCardAndDeviceId(devices);
+ }
+ if (!devices.empty()) {
+ auto streamDataProcessor = getContext().getStreamDataProcessor().lock();
+ if (streamDataProcessor != nullptr) {
+ streamDataProcessor->setAudioDevice(devices[0]);
+ }
+ }
+ return StreamAlsa::setConnectedDevices(devices);
+}
+
std::vector<alsa::DeviceProfile> StreamPrimary::getDeviceProfiles() {
- static const std::vector<alsa::DeviceProfile> kBuiltInSource{
- alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard,
- .device = primary::PrimaryMixer::kAlsaDevice,
- .direction = PCM_IN,
+ return {alsa::DeviceProfile{.card = mCurrAlsaDeviceId.first,
+ .device = mCurrAlsaDeviceId.second,
+ .direction = mIsInput ? PCM_IN : PCM_OUT,
.isExternal = false}};
- static const std::vector<alsa::DeviceProfile> kBuiltInSink{
- alsa::DeviceProfile{.card = primary::PrimaryMixer::kAlsaCard,
- .device = primary::PrimaryMixer::kAlsaDevice,
- .direction = PCM_OUT,
- .isExternal = false}};
- return mIsInput ? kBuiltInSource : kBuiltInSink;
+}
+
+bool StreamPrimary::isStubStream() {
+ std::lock_guard l(mLock);
+ return mAlsaDeviceId == kStubDeviceId;
+}
+
+// static
+StreamPrimary::AlsaDeviceId StreamPrimary::getCardAndDeviceId(
+ const std::vector<AudioDevice>& devices) {
+ if (devices.empty() || devices[0].address.getTag() != AudioDeviceAddress::id) {
+ return kDefaultCardAndDeviceId;
+ }
+ std::string deviceAddress = devices[0].address.get<AudioDeviceAddress::id>();
+ AlsaDeviceId cardAndDeviceId;
+ if (const size_t suffixPos = deviceAddress.rfind("CARD_");
+ suffixPos == std::string::npos ||
+ sscanf(deviceAddress.c_str() + suffixPos, "CARD_%d_DEV_%d", &cardAndDeviceId.first,
+ &cardAndDeviceId.second) != 2) {
+ return kDefaultCardAndDeviceId;
+ }
+ LOG(DEBUG) << __func__ << ": parsed with card id " << cardAndDeviceId.first << ", device id "
+ << cardAndDeviceId.second;
+ return cardAndDeviceId;
+}
+
+// static
+bool StreamPrimary::useStubStream(
+ bool isInput, const ::aidl::android::media::audio::common::AudioDevice& device) {
+ static const bool kSimulateInput =
+ GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
+ static const bool kSimulateOutput =
+ GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
+ if (isInput) {
+ return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
+ device.type.type == AudioDeviceType::IN_FM_TUNER ||
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */;
+ }
+ return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/;
}
StreamInPrimary::StreamInPrimary(StreamContext&& context, const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones)
: StreamIn(std::move(context), microphones),
- StreamSwitcher(&mContextInstance, sinkMetadata),
+ StreamPrimary(&mContextInstance, sinkMetadata),
StreamInHwGainHelper(&mContextInstance) {}
-bool StreamInPrimary::useStubStream(const AudioDevice& device) {
- static const bool kSimulateInput =
- GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
- return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
- device.type.type == AudioDeviceType::IN_FM_TUNER ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */ ||
- (device.type.type == AudioDeviceType::IN_BUS && device.type.connection.empty());
-}
-
-StreamSwitcher::DeviceSwitchBehavior StreamInPrimary::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- LOG(DEBUG) << __func__;
- if (devices.size() > 1) {
- LOG(ERROR) << __func__ << ": primary stream can only be connected to one device, got: "
- << devices.size();
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- if (devices.empty() || useStubStream(devices[0]) == isStubStream()) {
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
- }
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamInPrimary::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- if (devices.empty()) {
- LOG(FATAL) << __func__ << ": called with empty devices"; // see 'switchCurrentStream'
- }
- if (useStubStream(devices[0])) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamStub>(context, metadata));
- }
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamPrimary>(context, metadata));
-}
-
ndk::ScopedAStatus StreamInPrimary::getHwGain(std::vector<float>* _aidl_return) {
if (isStubStream()) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -181,45 +247,9 @@
StreamOutPrimary::StreamOutPrimary(StreamContext&& context, const SourceMetadata& sourceMetadata,
const std::optional<AudioOffloadInfo>& offloadInfo)
: StreamOut(std::move(context), offloadInfo),
- StreamSwitcher(&mContextInstance, sourceMetadata),
+ StreamPrimary(&mContextInstance, sourceMetadata),
StreamOutHwVolumeHelper(&mContextInstance) {}
-bool StreamOutPrimary::useStubStream(const AudioDevice& device) {
- static const bool kSimulateOutput =
- GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
- return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/ ||
- (device.type.type == AudioDeviceType::OUT_BUS && device.type.connection.empty());
-}
-
-StreamSwitcher::DeviceSwitchBehavior StreamOutPrimary::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- LOG(DEBUG) << __func__;
- if (devices.size() > 1) {
- LOG(ERROR) << __func__ << ": primary stream can only be connected to one device, got: "
- << devices.size();
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- if (devices.empty() || useStubStream(devices[0]) == isStubStream()) {
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
- }
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamOutPrimary::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- if (devices.empty()) {
- LOG(FATAL) << __func__ << ": called with empty devices"; // see 'switchCurrentStream'
- }
- if (useStubStream(devices[0])) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamStub>(context, metadata));
- }
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamPrimary>(context, metadata));
-}
-
ndk::ScopedAStatus StreamOutPrimary::getHwVolume(std::vector<float>* _aidl_return) {
if (isStubStream()) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -245,15 +275,4 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus StreamOutPrimary::setConnectedDevices(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- if (!devices.empty()) {
- auto streamDataProcessor = mContextInstance.getStreamDataProcessor().lock();
- if (streamDataProcessor != nullptr) {
- streamDataProcessor->setAudioDevice(devices[0]);
- }
- }
- return StreamSwitcher::setConnectedDevices(devices);
-}
-
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index db105b6..93fe028 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -26,128 +26,106 @@
using aidl::android::hardware::audio::common::SourceMetadata;
using aidl::android::hardware::audio::core::r_submix::SubmixRoute;
using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioOffloadInfo;
using aidl::android::media::audio::common::MicrophoneDynamicInfo;
using aidl::android::media::audio::common::MicrophoneInfo;
namespace aidl::android::hardware::audio::core {
-StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata,
- const AudioDeviceAddress& deviceAddress)
+StreamRemoteSubmix::StreamRemoteSubmix(StreamContext* context, const Metadata& metadata)
: StreamCommonImpl(context, metadata),
- mDeviceAddress(deviceAddress),
- mIsInput(isInput(metadata)) {
- mStreamConfig.frameSize = context->getFrameSize();
- mStreamConfig.format = context->getFormat();
- mStreamConfig.channelLayout = context->getChannelLayout();
- mStreamConfig.sampleRate = context->getSampleRate();
-}
+ mIsInput(isInput(metadata)),
+ mStreamConfig{.sampleRate = context->getSampleRate(),
+ .format = context->getFormat(),
+ .channelLayout = context->getChannelLayout(),
+ .frameSize = context->getFrameSize()} {}
StreamRemoteSubmix::~StreamRemoteSubmix() {
cleanupWorker();
}
::android::status_t StreamRemoteSubmix::init() {
- mCurrentRoute = SubmixRoute::findOrCreateRoute(mDeviceAddress, mStreamConfig);
- if (mCurrentRoute == nullptr) {
- return ::android::NO_INIT;
- }
- if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
- LOG(ERROR) << __func__ << ": invalid stream config";
- return ::android::NO_INIT;
- }
- sp<MonoPipe> sink = mCurrentRoute->getSink();
- if (sink == nullptr) {
- LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
- return ::android::NO_INIT;
- }
- if ((!mIsInput || mCurrentRoute->isStreamInOpen()) && sink->isShutdown()) {
- LOG(DEBUG) << __func__ << ": Shut down sink when opening stream";
- if (::android::OK != mCurrentRoute->resetPipe()) {
- LOG(ERROR) << __func__ << ": reset pipe failed";
- return ::android::NO_INIT;
- }
- }
- mCurrentRoute->openStream(mIsInput);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::drain(StreamDescriptor::DrainMode) {
- usleep(1000);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::flush() {
- usleep(1000);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::pause() {
- usleep(1000);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::standby() {
- mCurrentRoute->standby(mIsInput);
+ if (mCurrentRoute) mCurrentRoute->standby(mIsInput);
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::start() {
- mCurrentRoute->exitStandby(mIsInput);
+ if (mDeviceAddressUpdated.load(std::memory_order_acquire)) {
+ LOG(DEBUG) << __func__ << ": device address updated, reset current route";
+ shutdown();
+ mDeviceAddressUpdated.store(false, std::memory_order_release);
+ }
+ if (!mCurrentRoute) {
+ RETURN_STATUS_IF_ERROR(setCurrentRoute());
+ LOG(DEBUG) << __func__ << ": have current route? " << (mCurrentRoute != nullptr);
+ }
+ if (mCurrentRoute) mCurrentRoute->exitStandby(mIsInput);
mStartTimeNs = ::android::uptimeNanos();
mFramesSinceStart = 0;
return ::android::OK;
}
-ndk::ScopedAStatus StreamRemoteSubmix::prepareToClose() {
- if (!mIsInput) {
- std::shared_ptr<SubmixRoute> route = SubmixRoute::findRoute(mDeviceAddress);
- if (route != nullptr) {
- sp<MonoPipe> sink = route->getSink();
- if (sink == nullptr) {
- ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- LOG(DEBUG) << __func__ << ": shutting down MonoPipe sink";
-
- sink->shutdown(true);
- // The client already considers this stream as closed, release the output end.
- route->closeStream(mIsInput);
- } else {
- LOG(DEBUG) << __func__ << ": stream already closed.";
- ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
- }
- return ndk::ScopedAStatus::ok();
-}
-
// Remove references to the specified input and output streams. When the device no longer
// references input and output streams destroy the associated pipe.
void StreamRemoteSubmix::shutdown() {
+ if (!mCurrentRoute) return;
mCurrentRoute->closeStream(mIsInput);
// If all stream instances are closed, we can remove route information for this port.
if (!mCurrentRoute->hasAtleastOneStreamOpen()) {
mCurrentRoute->releasePipe();
LOG(DEBUG) << __func__ << ": pipe destroyed";
- SubmixRoute::removeRoute(mDeviceAddress);
+ SubmixRoute::removeRoute(getDeviceAddress());
}
mCurrentRoute.reset();
}
::android::status_t StreamRemoteSubmix::transfer(void* buffer, size_t frameCount,
size_t* actualFrameCount, int32_t* latencyMs) {
+ if (mDeviceAddressUpdated.load(std::memory_order_acquire)) {
+ // 'setConnectedDevices' was called. I/O will be restarted.
+ return ::android::OK;
+ }
+
*latencyMs = getDelayInUsForFrameCount(getStreamPipeSizeInFrames()) / 1000;
LOG(VERBOSE) << __func__ << ": Latency " << *latencyMs << "ms";
- mCurrentRoute->exitStandby(mIsInput);
- ::android::status_t status = mIsInput ? inRead(buffer, frameCount, actualFrameCount)
- : outWrite(buffer, frameCount, actualFrameCount);
- if ((status != ::android::OK && mIsInput) ||
- ((status != ::android::OK && status != ::android::DEAD_OBJECT) && !mIsInput)) {
- return status;
+ ::android::status_t status = ::android::OK;
+ if (mCurrentRoute) {
+ mCurrentRoute->exitStandby(mIsInput);
+ status = mIsInput ? inRead(buffer, frameCount, actualFrameCount)
+ : outWrite(buffer, frameCount, actualFrameCount);
+ if ((status != ::android::OK && mIsInput) ||
+ ((status != ::android::OK && status != ::android::DEAD_OBJECT) && !mIsInput)) {
+ return status;
+ }
+ } else {
+ LOG(WARNING) << __func__ << ": no current route";
+ if (mIsInput) {
+ memset(buffer, 0, mStreamConfig.frameSize * frameCount);
+ }
+ *actualFrameCount = frameCount;
}
mFramesSinceStart += *actualFrameCount;
- if (!mIsInput && status != ::android::DEAD_OBJECT) return ::android::OK;
- // Input streams always need to block, output streams need to block when there is no sink.
- // When the sink exists, more sophisticated blocking algorithm is implemented by MonoPipe.
+ // If there is no route, always block, otherwise:
+ // - Input streams always need to block, output streams need to block when there is no sink.
+ // - When the sink exists, more sophisticated blocking algorithm is implemented by MonoPipe.
+ if (mCurrentRoute && !mIsInput && status != ::android::DEAD_OBJECT) return ::android::OK;
const long bufferDurationUs =
(*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
const auto totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
@@ -163,6 +141,10 @@
}
::android::status_t StreamRemoteSubmix::refinePosition(StreamDescriptor::Position* position) {
+ if (!mCurrentRoute) {
+ RETURN_STATUS_IF_ERROR(setCurrentRoute());
+ if (!mCurrentRoute) return ::android::OK;
+ }
sp<MonoPipeReader> source = mCurrentRoute->getSource();
if (source == nullptr) {
return ::android::NO_INIT;
@@ -186,6 +168,7 @@
// Calculate the maximum size of the pipe buffer in frames for the specified stream.
size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
+ if (!mCurrentRoute) return r_submix::kDefaultPipeSizeInFrames;
auto pipeConfig = mCurrentRoute->getPipeConfig();
const size_t maxFrameSize = std::max(mStreamConfig.frameSize, pipeConfig.frameSize);
return (pipeConfig.frameCount * pipeConfig.frameSize) / maxFrameSize;
@@ -209,7 +192,7 @@
}
mWriteShutdownCount = 0;
- LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ LOG(VERBOSE) << __func__ << ": " << getDeviceAddress().toString() << ", " << frameCount
<< " frames";
const bool shouldBlockWrite = mCurrentRoute->shouldBlockWrite();
@@ -283,8 +266,9 @@
}
mReadErrorCount = 0;
- LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ LOG(VERBOSE) << __func__ << ": " << getDeviceAddress().toString() << ", " << frameCount
<< " frames";
+
// read the data from the pipe
char* buff = (char*)buffer;
size_t actuallyRead = 0;
@@ -324,10 +308,91 @@
return ::android::OK;
}
+::android::status_t StreamRemoteSubmix::setCurrentRoute() {
+ const auto address = getDeviceAddress();
+ if (address == AudioDeviceAddress{}) {
+ return ::android::OK;
+ }
+ mCurrentRoute = SubmixRoute::findOrCreateRoute(address, mStreamConfig);
+ if (mCurrentRoute == nullptr) {
+ return ::android::NO_INIT;
+ }
+ if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
+ LOG(ERROR) << __func__ << ": invalid stream config";
+ return ::android::NO_INIT;
+ }
+ sp<MonoPipe> sink = mCurrentRoute->getSink();
+ if (sink == nullptr) {
+ LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
+ return ::android::NO_INIT;
+ }
+ if ((!mIsInput || mCurrentRoute->isStreamInOpen()) && sink->isShutdown()) {
+ LOG(DEBUG) << __func__ << ": Shut down sink when opening stream";
+ if (::android::OK != mCurrentRoute->resetPipe()) {
+ LOG(ERROR) << __func__ << ": reset pipe failed";
+ return ::android::NO_INIT;
+ }
+ }
+ mCurrentRoute->openStream(mIsInput);
+ return ::android::OK;
+}
+
+ndk::ScopedAStatus StreamRemoteSubmix::prepareToClose() {
+ if (!mIsInput) {
+ const auto address = getDeviceAddress();
+ if (address == AudioDeviceAddress{}) return ndk::ScopedAStatus::ok();
+ std::shared_ptr<SubmixRoute> route = SubmixRoute::findRoute(address);
+ if (route != nullptr) {
+ sp<MonoPipe> sink = route->getSink();
+ if (sink == nullptr) {
+ ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ LOG(DEBUG) << __func__ << ": shutting down MonoPipe sink";
+
+ sink->shutdown(true);
+ // The client already considers this stream as closed, release the output end.
+ route->closeStream(mIsInput);
+ } else {
+ LOG(DEBUG) << __func__ << ": stream already closed.";
+ ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StreamRemoteSubmix::setConnectedDevices(const ConnectedDevices& devices) {
+ if (devices.size() > 1) {
+ LOG(ERROR) << __func__ << ": Only single device supported, got " << devices.size();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ AudioDeviceAddress newAddress;
+ if (!devices.empty()) {
+ if (auto deviceDesc = devices.front().type;
+ (mIsInput && deviceDesc.type != AudioDeviceType::IN_SUBMIX) ||
+ (!mIsInput && deviceDesc.type != AudioDeviceType::OUT_SUBMIX)) {
+ LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
+ << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ newAddress = devices.front().address;
+ LOG(DEBUG) << __func__ << ": connected to " << newAddress.toString();
+ } else {
+ LOG(DEBUG) << __func__ << ": disconnected";
+ }
+ RETURN_STATUS_IF_ERROR(StreamCommonImpl::setConnectedDevices(devices));
+ std::lock_guard guard(mLock);
+ if (mDeviceAddress != newAddress) {
+ mDeviceAddress = newAddress;
+ mDeviceAddressUpdated.store(true, std::memory_order_release);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
StreamInRemoteSubmix::StreamInRemoteSubmix(StreamContext&& context,
const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones)
- : StreamIn(std::move(context), microphones), StreamSwitcher(&mContextInstance, sinkMetadata) {}
+ : StreamIn(std::move(context), microphones),
+ StreamRemoteSubmix(&mContextInstance, sinkMetadata) {}
ndk::ScopedAStatus StreamInRemoteSubmix::getActiveMicrophones(
std::vector<MicrophoneDynamicInfo>* _aidl_return) {
@@ -336,66 +401,10 @@
return ndk::ScopedAStatus::ok();
}
-StreamSwitcher::DeviceSwitchBehavior StreamInRemoteSubmix::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- // This implementation effectively postpones stream creation until
- // receiving the first call to 'setConnectedDevices' with a non-empty list.
- if (isStubStream()) {
- if (devices.size() == 1) {
- auto deviceDesc = devices.front().type;
- if (deviceDesc.type ==
- ::aidl::android::media::audio::common::AudioDeviceType::IN_SUBMIX) {
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
- }
- LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
- << " not supported";
- } else {
- LOG(ERROR) << __func__ << ": Only single device supported.";
- }
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamInRemoteSubmix::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamRemoteSubmix>(context, metadata, devices.front().address));
-}
-
StreamOutRemoteSubmix::StreamOutRemoteSubmix(StreamContext&& context,
const SourceMetadata& sourceMetadata,
const std::optional<AudioOffloadInfo>& offloadInfo)
: StreamOut(std::move(context), offloadInfo),
- StreamSwitcher(&mContextInstance, sourceMetadata) {}
-
-StreamSwitcher::DeviceSwitchBehavior StreamOutRemoteSubmix::switchCurrentStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
- // This implementation effectively postpones stream creation until
- // receiving the first call to 'setConnectedDevices' with a non-empty list.
- if (isStubStream()) {
- if (devices.size() == 1) {
- auto deviceDesc = devices.front().type;
- if (deviceDesc.type ==
- ::aidl::android::media::audio::common::AudioDeviceType::OUT_SUBMIX) {
- return DeviceSwitchBehavior::CREATE_NEW_STREAM;
- }
- LOG(ERROR) << __func__ << ": Device type " << toString(deviceDesc.type)
- << " not supported";
- } else {
- LOG(ERROR) << __func__ << ": Only single device supported.";
- }
- return DeviceSwitchBehavior::UNSUPPORTED_DEVICES;
- }
- return DeviceSwitchBehavior::USE_CURRENT_STREAM;
-}
-
-std::unique_ptr<StreamCommonInterfaceEx> StreamOutRemoteSubmix::createNewStream(
- const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices,
- StreamContext* context, const Metadata& metadata) {
- return std::unique_ptr<StreamCommonInterfaceEx>(
- new InnerStreamWrapper<StreamRemoteSubmix>(context, metadata, devices.front().address));
-}
+ StreamRemoteSubmix(&mContextInstance, sourceMetadata) {}
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/r_submix/SubmixRoute.h b/audio/aidl/default/r_submix/SubmixRoute.h
index 5425f12..0097f39 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.h
+++ b/audio/aidl/default/r_submix/SubmixRoute.h
@@ -25,10 +25,12 @@
#include <media/nbaio/MonoPipe.h>
#include <media/nbaio/MonoPipeReader.h>
+#include <Utils.h>
#include <aidl/android/media/audio/common/AudioChannelLayout.h>
#include <aidl/android/media/audio/common/AudioDeviceAddress.h>
#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+using aidl::android::hardware::audio::common::getFrameSizeInBytes;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioFormatDescription;
using aidl::android::media::audio::common::AudioFormatType;
@@ -56,8 +58,8 @@
AudioChannelLayout channelLayout =
AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
AudioChannelLayout::LAYOUT_STEREO);
- size_t frameSize;
- size_t frameCount;
+ size_t frameSize = getFrameSizeInBytes(format, channelLayout);
+ size_t frameCount = 0;
};
class SubmixRoute {
diff --git a/audio/aidl/default/stub/DriverStubImpl.cpp b/audio/aidl/default/stub/DriverStubImpl.cpp
new file mode 100644
index 0000000..beb0114
--- /dev/null
+++ b/audio/aidl/default/stub/DriverStubImpl.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+#include <cmath>
+
+#define LOG_TAG "AHAL_Stream"
+#include <android-base/logging.h>
+#include <audio_utils/clock.h>
+
+#include "core-impl/DriverStubImpl.h"
+
+namespace aidl::android::hardware::audio::core {
+
+DriverStubImpl::DriverStubImpl(const StreamContext& context)
+ : mBufferSizeFrames(context.getBufferSizeInFrames()),
+ mFrameSizeBytes(context.getFrameSize()),
+ mSampleRate(context.getSampleRate()),
+ mIsAsynchronous(!!context.getAsyncCallback()),
+ mIsInput(context.isInput()) {}
+
+::android::status_t DriverStubImpl::init() {
+ mIsInitialized = true;
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::drain(StreamDescriptor::DrainMode) {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ if (!mIsInput) {
+ if (!mIsAsynchronous) {
+ static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
+ const size_t delayUs = static_cast<size_t>(
+ std::roundf(mBufferSizeFrames * kMicrosPerSecond / mSampleRate));
+ usleep(delayUs);
+ } else {
+ usleep(500);
+ }
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::flush() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::pause() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::standby() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ mIsStandby = true;
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::start() {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ mIsStandby = false;
+ mStartTimeNs = ::android::uptimeNanos();
+ mFramesSinceStart = 0;
+ return ::android::OK;
+}
+
+::android::status_t DriverStubImpl::transfer(void* buffer, size_t frameCount,
+ size_t* actualFrameCount, int32_t*) {
+ if (!mIsInitialized) {
+ LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
+ }
+ if (mIsStandby) {
+ LOG(FATAL) << __func__ << ": must not happen while in standby";
+ }
+ *actualFrameCount = frameCount;
+ if (mIsAsynchronous) {
+ usleep(500);
+ } else {
+ mFramesSinceStart += *actualFrameCount;
+ const long bufferDurationUs = (*actualFrameCount) * MICROS_PER_SECOND / mSampleRate;
+ const auto totalDurationUs =
+ (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+ const long totalOffsetUs =
+ mFramesSinceStart * MICROS_PER_SECOND / mSampleRate - totalDurationUs;
+ LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+ if (totalOffsetUs > 0) {
+ const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+ LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+ usleep(sleepTimeUs);
+ }
+ }
+ if (mIsInput) {
+ uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
+ for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
+ byteBuffer[i] = std::rand() % 255;
+ }
+ }
+ return ::android::OK;
+}
+
+void DriverStubImpl::shutdown() {
+ mIsInitialized = false;
+}
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/stub/StreamStub.cpp b/audio/aidl/default/stub/StreamStub.cpp
index a3d99a8..f6c87e1 100644
--- a/audio/aidl/default/stub/StreamStub.cpp
+++ b/audio/aidl/default/stub/StreamStub.cpp
@@ -32,110 +32,12 @@
namespace aidl::android::hardware::audio::core {
StreamStub::StreamStub(StreamContext* context, const Metadata& metadata)
- : StreamCommonImpl(context, metadata),
- mBufferSizeFrames(getContext().getBufferSizeInFrames()),
- mFrameSizeBytes(getContext().getFrameSize()),
- mSampleRate(getContext().getSampleRate()),
- mIsAsynchronous(!!getContext().getAsyncCallback()),
- mIsInput(isInput(metadata)) {}
+ : StreamCommonImpl(context, metadata), DriverStubImpl(getContext()) {}
StreamStub::~StreamStub() {
cleanupWorker();
}
-::android::status_t StreamStub::init() {
- mIsInitialized = true;
- return ::android::OK;
-}
-
-::android::status_t StreamStub::drain(StreamDescriptor::DrainMode) {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- if (!mIsInput) {
- if (!mIsAsynchronous) {
- static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
- const size_t delayUs = static_cast<size_t>(
- std::roundf(mBufferSizeFrames * kMicrosPerSecond / mSampleRate));
- usleep(delayUs);
- } else {
- usleep(500);
- }
- }
- return ::android::OK;
-}
-
-::android::status_t StreamStub::flush() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- return ::android::OK;
-}
-
-::android::status_t StreamStub::pause() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- return ::android::OK;
-}
-
-::android::status_t StreamStub::standby() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- mIsStandby = true;
- return ::android::OK;
-}
-
-::android::status_t StreamStub::start() {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- mIsStandby = false;
- mStartTimeNs = ::android::uptimeNanos();
- mFramesSinceStart = 0;
- return ::android::OK;
-}
-
-::android::status_t StreamStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
- int32_t*) {
- if (!mIsInitialized) {
- LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
- }
- if (mIsStandby) {
- LOG(FATAL) << __func__ << ": must not happen while in standby";
- }
- *actualFrameCount = frameCount;
- if (mIsAsynchronous) {
- usleep(500);
- } else {
- mFramesSinceStart += *actualFrameCount;
- const long bufferDurationUs =
- (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
- const auto totalDurationUs =
- (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
- const long totalOffsetUs =
- mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
- LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
- if (totalOffsetUs > 0) {
- const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
- LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
- usleep(sleepTimeUs);
- }
- }
- if (mIsInput) {
- uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
- for (size_t i = 0; i < frameCount * mFrameSizeBytes; ++i) {
- byteBuffer[i] = std::rand() % 255;
- }
- }
- return ::android::OK;
-}
-
-void StreamStub::shutdown() {
- mIsInitialized = false;
-}
-
StreamInStub::StreamInStub(StreamContext&& context, const SinkMetadata& sinkMetadata,
const std::vector<MicrophoneInfo>& microphones)
: StreamIn(std::move(context), microphones), StreamStub(&mContextInstance, sinkMetadata) {}
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 2bf70c7..9fe5801 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -87,6 +87,7 @@
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioDualMonoMode;
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::AudioLatencyMode;
@@ -450,6 +451,7 @@
// This is implemented by the 'StreamFixture' utility class.
static constexpr int kNegativeTestBufferSizeFrames = 256;
static constexpr int kDefaultLargeBufferSizeFrames = 48000;
+ static constexpr int32_t kAidlVersion3 = 3;
void SetUpImpl(const std::string& moduleName, bool setUpDebug = true) {
ASSERT_NO_FATAL_FAILURE(ConnectToService(moduleName, setUpDebug));
@@ -478,6 +480,7 @@
if (setUpDebug) {
ASSERT_NO_FATAL_FAILURE(SetUpDebug());
}
+ ASSERT_TRUE(module->getInterfaceVersion(&aidlVersion).isOk());
}
void RestartService() {
@@ -490,6 +493,7 @@
if (setUpDebug) {
ASSERT_NO_FATAL_FAILURE(SetUpDebug());
}
+ ASSERT_TRUE(module->getInterfaceVersion(&aidlVersion).isOk());
}
void SetUpDebug() {
@@ -577,6 +581,7 @@
std::unique_ptr<WithDebugFlags> debug;
std::vector<AudioPort> initialPorts;
std::vector<AudioRoute> initialRoutes;
+ int32_t aidlVersion;
};
class WithDevicePortConnectedState {
@@ -1821,6 +1826,46 @@
}
}
+TEST_P(AudioCoreModule, SetAudioPortConfigInvalidPortAudioGain) {
+ if (aidlVersion < kAidlVersion3) {
+ GTEST_SKIP() << "Skip for audio HAL version lower than " << kAidlVersion3;
+ }
+ std::vector<AudioPort> ports;
+ ASSERT_IS_OK(module->getAudioPorts(&ports));
+ bool atLeastOnePortWithNonemptyGain = false;
+ for (const auto port : ports) {
+ AudioPortConfig portConfig;
+ portConfig.portId = port.id;
+ if (port.gains.empty()) {
+ continue;
+ }
+ atLeastOnePortWithNonemptyGain = true;
+ int index = 0;
+ ASSERT_NE(0, port.gains[index].stepValue) << "Invalid audio port config gain step 0";
+ portConfig.gain->index = index;
+ AudioGainConfig invalidGainConfig;
+
+ int invalidGain = port.gains[index].maxValue + port.gains[index].stepValue;
+ invalidGainConfig.values.push_back(invalidGain);
+ portConfig.gain.emplace(invalidGainConfig);
+ bool applied = true;
+ AudioPortConfig suggestedConfig;
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
+ << "invalid port gain " << invalidGain << " lower than min gain";
+
+ invalidGain = port.gains[index].minValue - port.gains[index].stepValue;
+ invalidGainConfig.values[0] = invalidGain;
+ portConfig.gain.emplace(invalidGainConfig);
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
+ << "invalid port gain " << invalidGain << "higher than max gain";
+ }
+ if (!atLeastOnePortWithNonemptyGain) {
+ GTEST_SKIP() << "No audio port contains non-empty gain configuration";
+ }
+}
+
TEST_P(AudioCoreModule, TryConnectMissingDevice) {
// Limit checks to connection types that are known to be detectable by HAL implementations.
static const std::set<std::string> kCheckedConnectionTypes{
diff --git a/authsecret/aidl/Android.bp b/authsecret/aidl/Android.bp
index 90e128d..b5e4e3d 100644
--- a/authsecret/aidl/Android.bp
+++ b/authsecret/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.authsecret",
vendor_available: true,
+ frozen: true,
srcs: ["android/hardware/authsecret/*.aidl"],
stability: "vintf",
backend: {
diff --git a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
index 81f18b2..4166fdc 100644
--- a/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
+++ b/automotive/ivn_android_device/impl/default/src/IvnAndroidDeviceService.cpp
@@ -48,7 +48,8 @@
}
bool IvnAndroidDeviceService::init() {
- std::ifstream configStream(mConfigPath);
+ std::string configPathStr(mConfigPath);
+ std::ifstream configStream(configPathStr);
if (!configStream) {
LOG(ERROR) << "couldn't open " << mConfigPath << " for parsing.";
return false;
diff --git a/automotive/occupant_awareness/aidl/Android.bp b/automotive/occupant_awareness/aidl/Android.bp
index 1a8124c..33406ba 100644
--- a/automotive/occupant_awareness/aidl/Android.bp
+++ b/automotive/occupant_awareness/aidl/Android.bp
@@ -14,6 +14,7 @@
"android/hardware/automotive/occupant_awareness/*.aidl",
],
stability: "vintf",
+ frozen: true,
backend: {
java: {
sdk_version: "module_current",
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 6668d16..b301557 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -538,6 +538,9 @@
<< getErrorMsg(writeResult);
}
break;
+ case toInt(VehicleApPowerStateReport::ON):
+ ALOGI("Received VehicleApPowerStateReport::ON, entering normal operating state");
+ break;
default:
ALOGE("Unknown VehicleApPowerStateReport: %d", state);
break;
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index a458c5b..c62784e 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -145,6 +145,13 @@
<< toString(session_type_);
return;
}
+ } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
} else {
LOG(ERROR) << __func__ << " invalid SessionType ="
<< toString(session_type_);
@@ -166,6 +173,13 @@
<< toString(session_type_);
return;
}
+ } else if (session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
} else {
LOG(ERROR) << __func__
<< " invalid SessionType =" << toString(session_type_);
@@ -604,7 +618,9 @@
if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
- session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
return false;
}
@@ -629,7 +645,9 @@
if (session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
- session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH) {
return false;
}
diff --git a/boot/aidl/client/BootControlClient.cpp b/boot/aidl/client/BootControlClient.cpp
index 89258d2..dca98c6 100644
--- a/boot/aidl/client/BootControlClient.cpp
+++ b/boot/aidl/client/BootControlClient.cpp
@@ -18,6 +18,7 @@
#include <aidl/android/hardware/boot/IBootControl.h>
#include <android-base/logging.h>
+#include <android/binder_ibinder.h>
#include <android/binder_manager.h>
#include <android/hardware/boot/1.0/IBootControl.h>
#include <android/hardware/boot/1.1/IBootControl.h>
@@ -65,63 +66,79 @@
using IBootControl = ::aidl::android::hardware::boot::IBootControl;
public:
- BootControlClientAidl(std::shared_ptr<IBootControl> module) : module_(module) {}
+ explicit BootControlClientAidl(std::shared_ptr<IBootControl> module)
+ : module_(module),
+ boot_control_death_recipient(AIBinder_DeathRecipient_new(onBootControlServiceDied)) {
+ binder_status_t status = AIBinder_linkToDeath(module->asBinder().get(),
+ boot_control_death_recipient, nullptr);
+ if (status != STATUS_OK) {
+ LOG(ERROR) << "Could not link to binder death";
+ return;
+ }
+ }
BootControlVersion GetVersion() const override { return BootControlVersion::BOOTCTL_AIDL; }
- ~BootControlClientAidl() = default;
- virtual int32_t GetNumSlots() const {
+ ~BootControlClientAidl() {
+ if (boot_control_death_recipient) {
+ AIBinder_unlinkToDeath(module_->asBinder().get(), boot_control_death_recipient, this);
+ }
+ }
+
+ void onBootControlServiceDied() { LOG(ERROR) << "boot control service AIDL died"; }
+
+ int32_t GetNumSlots() const override {
int32_t ret = -1;
LOG_NDK_STATUS(module_->getNumberSlots(&ret));
return ret;
}
- int32_t GetCurrentSlot() const {
+ int32_t GetCurrentSlot() const override {
int32_t ret = -1;
LOG_NDK_STATUS(module_->getCurrentSlot(&ret));
return ret;
}
- MergeStatus getSnapshotMergeStatus() const {
+ MergeStatus getSnapshotMergeStatus() const override {
MergeStatus status = MergeStatus::UNKNOWN;
LOG_NDK_STATUS(module_->getSnapshotMergeStatus(&status));
return status;
}
- std::string GetSuffix(int32_t slot) const {
+ std::string GetSuffix(int32_t slot) const override {
std::string ret;
const auto status = module_->getSuffix(slot, &ret);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
return {};
}
return ret;
}
- std::optional<bool> IsSlotBootable(int32_t slot) const {
+ std::optional<bool> IsSlotBootable(int32_t slot) const override {
bool ret = false;
const auto status = module_->isSlotBootable(slot, &ret);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
return {};
}
return ret;
}
- CommandResult MarkSlotUnbootable(int32_t slot) {
+ CommandResult MarkSlotUnbootable(int32_t slot) override {
const auto status = module_->setSlotAsUnbootable(slot);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
}
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
- CommandResult SetActiveBootSlot(int slot) {
+ CommandResult SetActiveBootSlot(int slot) override {
const auto status = module_->setActiveBootSlot(slot);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
}
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
@@ -132,18 +149,18 @@
}
// Check if |slot| is marked boot successfully.
- std::optional<bool> IsSlotMarkedSuccessful(int slot) const {
+ std::optional<bool> IsSlotMarkedSuccessful(int slot) const override {
bool ret = false;
const auto status = module_->isSlotMarkedSuccessful(slot, &ret);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed "
+ << status.getDescription();
return {};
}
return ret;
}
- CommandResult MarkBootSuccessful() {
+ CommandResult MarkBootSuccessful() override {
const auto status = module_->markBootSuccessful();
if (!status.isOk()) {
LOG(ERROR) << __FUNCTION__ << " failed " << status.getDescription();
@@ -151,17 +168,23 @@
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
- CommandResult SetSnapshotMergeStatus(aidl::android::hardware::boot::MergeStatus merge_status) {
+ CommandResult SetSnapshotMergeStatus(
+ aidl::android::hardware::boot::MergeStatus merge_status) override {
const auto status = module_->setSnapshotMergeStatus(merge_status);
if (!status.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
- << " failed " << status.getDescription();
+ LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")" << " failed "
+ << status.getDescription();
}
return {.success = status.isOk(), .errMsg = status.getDescription()};
}
private:
const std::shared_ptr<IBootControl> module_;
+ AIBinder_DeathRecipient* boot_control_death_recipient;
+ static void onBootControlServiceDied(void* client) {
+ BootControlClientAidl* self = static_cast<BootControlClientAidl*>(client);
+ self->onBootControlServiceDied();
+ }
};
using namespace android::hardware::boot;
@@ -183,7 +206,7 @@
return BootControlVersion::BOOTCTL_V1_0;
}
}
- int32_t GetNumSlots() const {
+ int32_t GetNumSlots() const override {
const auto ret = module_v1_->getNumberSlots();
if (!ret.isOk()) {
LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
@@ -191,7 +214,7 @@
return ret.withDefault(-1);
}
- int32_t GetCurrentSlot() const {
+ int32_t GetCurrentSlot() const override {
const auto ret = module_v1_->getCurrentSlot();
if (!ret.isOk()) {
LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
@@ -199,23 +222,21 @@
return ret.withDefault(-1);
}
- std::string GetSuffix(int32_t slot) const {
+ std::string GetSuffix(int32_t slot) const override {
std::string suffix;
const auto ret = module_v1_->getSuffix(
slot,
[&](const ::android::hardware::hidl_string& slotSuffix) { suffix = slotSuffix; });
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
}
return suffix;
}
- std::optional<bool> IsSlotBootable(int32_t slot) const {
+ std::optional<bool> IsSlotBootable(int32_t slot) const override {
const auto ret = module_v1_->isSlotBootable(slot);
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
return {};
}
const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
@@ -225,7 +246,7 @@
return bool_result == V1_0::BoolResult::TRUE;
}
- CommandResult MarkSlotUnbootable(int32_t slot) {
+ CommandResult MarkSlotUnbootable(int32_t slot) override {
CommandResult result;
const auto ret =
module_v1_->setSlotAsUnbootable(slot, [&](const V1_0::CommandResult& error) {
@@ -233,26 +254,24 @@
result.errMsg = error.errMsg;
});
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
}
return result;
}
- CommandResult SetActiveBootSlot(int32_t slot) {
+ CommandResult SetActiveBootSlot(int32_t slot) override {
CommandResult result;
const auto ret = module_v1_->setActiveBootSlot(slot, [&](const V1_0::CommandResult& error) {
result.success = error.success;
result.errMsg = error.errMsg;
});
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
}
return result;
}
- CommandResult MarkBootSuccessful() {
+ CommandResult MarkBootSuccessful() override {
CommandResult result;
const auto ret = module_v1_->markBootSuccessful([&](const V1_0::CommandResult& error) {
result.success = error.success;
@@ -264,11 +283,10 @@
return result;
}
- std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const {
+ std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const override {
const auto ret = module_v1_->isSlotMarkedSuccessful(slot);
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << slot << ")" << " failed " << ret.description();
return {};
}
const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
@@ -278,7 +296,7 @@
return bool_result == V1_0::BoolResult::TRUE;
}
- MergeStatus getSnapshotMergeStatus() const {
+ MergeStatus getSnapshotMergeStatus() const override {
if (module_v1_1_ == nullptr) {
LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.1";
return MergeStatus::UNKNOWN;
@@ -291,7 +309,7 @@
ret.withDefault(static_cast<V1_1::MergeStatus>(MergeStatus::UNKNOWN)));
}
- CommandResult SetSnapshotMergeStatus(MergeStatus merge_status) {
+ CommandResult SetSnapshotMergeStatus(MergeStatus merge_status) override {
if (module_v1_1_ == nullptr) {
return {.success = false,
.errMsg = "setSnapshotMergeStatus is unsupported, requires at least boot v1.1"};
@@ -299,13 +317,13 @@
const auto ret =
module_v1_1_->setSnapshotMergeStatus(static_cast<V1_1::MergeStatus>(merge_status));
if (!ret.isOk()) {
- LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
- << " failed " << ret.description();
+ LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")" << " failed "
+ << ret.description();
}
return {.success = ret.isOk(), .errMsg = ret.description()};
}
- int32_t GetActiveBootSlot() const {
+ int32_t GetActiveBootSlot() const override {
if (module_v1_2_ == nullptr) {
LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.2";
return -1;
@@ -326,7 +344,6 @@
std::unique_ptr<BootControlClient> BootControlClient::WaitForService() {
const auto instance_name =
std::string(::aidl::android::hardware::boot::IBootControl::descriptor) + "/default";
-
if (AServiceManager_isDeclared(instance_name.c_str())) {
auto module = ::aidl::android::hardware::boot::IBootControl::fromBinder(
ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str())));
diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp
index 91196d4..abd5d7e 100644
--- a/camera/device/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/default/ExternalCameraDeviceSession.cpp
@@ -1136,6 +1136,11 @@
uint32_t v4lBufferCount = (fps >= kDefaultFps) ? mCfg.numVideoBuffers : mCfg.numStillBuffers;
+ // Double the max lag in theory.
+ mMaxLagNs = v4lBufferCount * 1000000000LL * 2 / fps;
+ ALOGI("%s: set mMaxLagNs to %" PRIu64 " ns, v4lBufferCount %u", __FUNCTION__, mMaxLagNs,
+ v4lBufferCount);
+
// VIDIOC_REQBUFS: create buffers
v4l2_requestbuffers req_buffers{};
req_buffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1232,40 +1237,67 @@
}
}
- ATRACE_BEGIN("VIDIOC_DQBUF");
+ uint64_t lagNs = 0;
v4l2_buffer buffer{};
- buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buffer.memory = V4L2_MEMORY_MMAP;
- if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
- ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
- return ret;
- }
- ATRACE_END();
+ do {
+ ATRACE_BEGIN("VIDIOC_DQBUF");
+ buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buffer.memory = V4L2_MEMORY_MMAP;
+ if (TEMP_FAILURE_RETRY(ioctl(mV4l2Fd.get(), VIDIOC_DQBUF, &buffer)) < 0) {
+ ALOGE("%s: DQBUF fails: %s", __FUNCTION__, strerror(errno));
+ return ret;
+ }
+ ATRACE_END();
- if (buffer.index >= mV4L2BufferCount) {
- ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index);
- return ret;
- }
+ if (buffer.index >= mV4L2BufferCount) {
+ ALOGE("%s: Invalid buffer id: %d", __FUNCTION__, buffer.index);
+ return ret;
+ }
- if (buffer.flags & V4L2_BUF_FLAG_ERROR) {
- ALOGE("%s: v4l2 buf error! buf flag 0x%x", __FUNCTION__, buffer.flags);
- // TODO: try to dequeue again
- }
+ if (buffer.flags & V4L2_BUF_FLAG_ERROR) {
+ ALOGE("%s: v4l2 buf error! buf flag 0x%x", __FUNCTION__, buffer.flags);
+ // TODO: try to dequeue again
+ }
- if (buffer.bytesused > mMaxV4L2BufferSize) {
- ALOGE("%s: v4l2 buffer bytes used: %u maximum %u", __FUNCTION__, buffer.bytesused,
- mMaxV4L2BufferSize);
- return ret;
- }
+ if (buffer.bytesused > mMaxV4L2BufferSize) {
+ ALOGE("%s: v4l2 buffer bytes used: %u maximum %u", __FUNCTION__, buffer.bytesused,
+ mMaxV4L2BufferSize);
+ return ret;
+ }
- if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
- // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
- // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
- *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec) * 1000000000LL +
- buffer.timestamp.tv_usec * 1000LL;
- } else {
- *shutterTs = systemTime(SYSTEM_TIME_MONOTONIC);
- }
+ nsecs_t curTimeNs = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ if (buffer.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC) {
+ // Ideally we should also check for V4L2_BUF_FLAG_TSTAMP_SRC_SOE, but
+ // even V4L2_BUF_FLAG_TSTAMP_SRC_EOF is better than capture a timestamp now
+ *shutterTs = static_cast<nsecs_t>(buffer.timestamp.tv_sec) * 1000000000LL +
+ buffer.timestamp.tv_usec * 1000LL;
+ } else {
+ *shutterTs = curTimeNs;
+ }
+
+ // The tactic only takes effect on v4l2 buffers with flag V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC.
+ // Most USB cameras should have the feature.
+ if (curTimeNs < *shutterTs) {
+ lagNs = 0;
+ ALOGW("%s: should not happen, the monotonic clock has issue, shutterTs is in the "
+ "future, curTimeNs %" PRId64 " < "
+ "shutterTs %" PRId64 "",
+ __func__, curTimeNs, *shutterTs);
+ } else {
+ lagNs = curTimeNs - *shutterTs;
+ }
+
+ if (lagNs > mMaxLagNs) {
+ ALOGI("%s: drop too old buffer, index %d, lag %" PRIu64 " ns > max %" PRIu64 " ns", __FUNCTION__,
+ buffer.index, lagNs, mMaxLagNs);
+ int retVal = ioctl(mV4l2Fd.get(), VIDIOC_QBUF, &buffer);
+ if (retVal) {
+ ALOGE("%s: unexpected VIDIOC_QBUF failed, retVal %d", __FUNCTION__, retVal);
+ return ret;
+ }
+ }
+ } while (lagNs > mMaxLagNs);
{
std::lock_guard<std::mutex> lk(mV4l2BufferLock);
diff --git a/camera/device/default/ExternalCameraDeviceSession.h b/camera/device/default/ExternalCameraDeviceSession.h
index 795b589..1c6ed06 100644
--- a/camera/device/default/ExternalCameraDeviceSession.h
+++ b/camera/device/default/ExternalCameraDeviceSession.h
@@ -382,6 +382,9 @@
std::string mExifMake;
std::string mExifModel;
/* End of members not changed after initialize() */
+
+ // The max tolerant lag between the dequeued v4l2 buffer and current capture request.
+ uint64_t mMaxLagNs;
};
} // namespace implementation
diff --git a/cas/1.2/default/Android.bp b/cas/1.2/default/Android.bp
index 38561fd..5bc8bad 100644
--- a/cas/1.2/default/Android.bp
+++ b/cas/1.2/default/Android.bp
@@ -46,6 +46,7 @@
vintf_fragments: ["android.hardware.cas@1.2-service.xml"],
defaults: ["cas_service_defaults@1.2"],
init_rc: ["android.hardware.cas@1.2-service.rc"],
+ overrides: ["com.android.hardware.cas"],
}
cc_binary {
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 6a3fa32..df5e5b1 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -21,6 +21,65 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+// Device framework compatibility matrix (common to all FCM versions)
+// Reference: https://source.android.com/docs/core/architecture/vintf/comp-matrices
+vintf_compatibility_matrix {
+ name: "framework_compatibility_matrix.device.xml",
+ stem: "compatibility_matrix.device.xml",
+ type: "device_fcm",
+}
+
+// Phony target that installs all system compatibility matrix files
+SYSTEM_MATRIX_DEPS = [
+ "framework_compatibility_matrix.5.xml",
+ "framework_compatibility_matrix.6.xml",
+ "framework_compatibility_matrix.7.xml",
+ "framework_compatibility_matrix.8.xml",
+ "framework_compatibility_matrix.202404.xml",
+ "framework_compatibility_matrix.device.xml",
+]
+
+phony {
+ name: "system_compatibility_matrix.xml",
+ required: SYSTEM_MATRIX_DEPS,
+ product_variables: {
+ release_aidl_use_unfrozen: {
+ required: [
+ "framework_compatibility_matrix.202504.xml",
+ ],
+ },
+ },
+}
+
+// Product Compatibility Matrix
+vintf_compatibility_matrix {
+ name: "product_compatibility_matrix.xml",
+ stem: "compatibility_matrix.xml",
+ product_specific: true,
+ type: "product_fcm",
+}
+
+// Phony target that installs all framework compatibility matrix files (system + product)
+FRAMEWORK_MATRIX_DEPS = SYSTEM_MATRIX_DEPS + ["product_compatibility_matrix.xml"]
+
+phony {
+ name: "framework_compatibility_matrix.xml",
+ required: FRAMEWORK_MATRIX_DEPS,
+ product_variables: {
+ release_aidl_use_unfrozen: {
+ required: [
+ "framework_compatibility_matrix.202504.xml",
+ ],
+ },
+ },
+}
+
+////////////////////////////////////////////
+// AUTO GENERATED MODULES
+// DO NOT ADD MORE MODULES BELOW THIS LINE
+////////////////////////////////////////////
+
+// System compatibility matrices
vintf_compatibility_matrix {
name: "framework_compatibility_matrix.5.xml",
stem: "compatibility_matrix.5.xml",
@@ -90,58 +149,4 @@
kernel_configs: [
"kernel_config_w_6.next",
],
-
-}
-
-// Device framework compatibility matrix (common to all FCM versions)
-// Reference: https://source.android.com/docs/core/architecture/vintf/comp-matrices
-vintf_compatibility_matrix {
- name: "framework_compatibility_matrix.device.xml",
- stem: "compatibility_matrix.device.xml",
- type: "device_fcm",
-}
-
-// Phony target that installs all system compatibility matrix files
-SYSTEM_MATRIX_DEPS = [
- "framework_compatibility_matrix.5.xml",
- "framework_compatibility_matrix.6.xml",
- "framework_compatibility_matrix.7.xml",
- "framework_compatibility_matrix.8.xml",
- "framework_compatibility_matrix.202404.xml",
- "framework_compatibility_matrix.device.xml",
-]
-
-phony {
- name: "system_compatibility_matrix.xml",
- required: SYSTEM_MATRIX_DEPS,
- product_variables: {
- release_aidl_use_unfrozen: {
- required: [
- "framework_compatibility_matrix.202504.xml",
- ],
- },
- },
-}
-
-// Product Compatibility Matrix
-vintf_compatibility_matrix {
- name: "product_compatibility_matrix.xml",
- stem: "compatibility_matrix.xml",
- product_specific: true,
- type: "product_fcm",
-}
-
-// Phony target that installs all framework compatibility matrix files (system + product)
-FRAMEWORK_MATRIX_DEPS = SYSTEM_MATRIX_DEPS + ["product_compatibility_matrix.xml"]
-
-phony {
- name: "framework_compatibility_matrix.xml",
- required: FRAMEWORK_MATRIX_DEPS,
- product_variables: {
- release_aidl_use_unfrozen: {
- required: [
- "framework_compatibility_matrix.202504.xml",
- ],
- },
- },
}
diff --git a/compatibility_matrices/bump.py b/compatibility_matrices/bump.py
index 4e3ceaa..ee2fa88 100755
--- a/compatibility_matrices/bump.py
+++ b/compatibility_matrices/bump.py
@@ -58,7 +58,6 @@
self.bump_kernel_configs()
self.copy_matrix()
self.edit_android_bp()
- self.edit_android_mk()
self.bump_libvintf()
def bump_kernel_configs(self):
@@ -127,28 +126,6 @@
with open(android_bp, "w") as f:
f.write("".join(lines))
-
- # This Android.mk file may be deprecated soon and the functionality is
- # replaced by the soong phony module system_compatibility_matrix.xml.
- def edit_android_mk(self):
- android_mk = self.interfaces_dir / "compatibility_matrices/Android.mk"
- lines = []
- with open(android_mk) as f:
- if self.next_module_name in f.read():
- return
- f.seek(0)
- for line in f:
- if f" {self.device_module_name} \\\n" in line:
- lines.append(f" {self.current_module_name} \\\n")
-
- if self.current_module_name in line:
- lines.append(f" {self.next_module_name} \\\n")
- else:
- lines.append(line)
-
- with open(android_mk, "w") as f:
- f.write("".join(lines))
-
def bump_libvintf(self):
if not self.current_version:
print("Skip libvintf update...")
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index afcb603..c42e723 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -12,6 +12,7 @@
vendor_available: true,
srcs: ["android/hardware/drm/*.aidl"],
stability: "vintf",
+ frozen: true,
imports: [
"android.hardware.common-V2",
],
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
index 1eb8b32..45c992a 100644
--- a/dumpstate/aidl/Android.bp
+++ b/dumpstate/aidl/Android.bp
@@ -26,6 +26,7 @@
vendor_available: true,
srcs: ["android/hardware/dumpstate/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 5e2cbe3..31e6536 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -462,6 +462,10 @@
GnssData lastGnssData;
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, timeoutSeconds));
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ if (i <= 2 && lastGnssData.measurements.size() == 0) {
+ // Allow 3 seconds tolerance for empty measurement
+ continue;
+ }
ASSERT_TRUE(lastGnssData.measurements.size() > 0);
// Validity check GnssData fields
@@ -507,6 +511,10 @@
GnssData lastGnssData;
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, timeoutSeconds));
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ if (i <= 2 && lastGnssData.measurements.size() == 0) {
+ // Allow 3 seconds tolerance to report empty measurement
+ continue;
+ }
ASSERT_TRUE(lastGnssData.measurements.size() > 0);
// Validity check GnssData fields
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index f7408d8..8abf7ab 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -419,6 +419,10 @@
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
kFirstGnssMeasurementTimeoutSeconds));
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ if (i <= 2 && lastMeasurement.measurements.size() == 0) {
+ // Allow 3 seconds tolerance for empty measurement
+ continue;
+ }
ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
// Validity check GnssData fields
@@ -479,6 +483,10 @@
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
kFirstGnssMeasurementTimeoutSeconds));
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ if (i <= 2 && lastMeasurement.measurements.size() == 0) {
+ // Allow 3 seconds tolerance for empty measurement
+ continue;
+ }
ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
// Validity check GnssData fields
@@ -1335,7 +1343,10 @@
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
kFirstGnssMeasurementTimeoutSeconds));
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
- ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
+ if (i > 2) {
+ // Allow 3 seconds tolerance for empty measurement
+ ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
+ }
// Validity check GnssData fields
checkGnssMeasurementClockFields(lastMeasurement);
@@ -1790,6 +1801,10 @@
GnssData lastGnssData;
ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastGnssData, 10));
EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+ if (i <= 2 && lastGnssData.measurements.size() == 0) {
+ // Allow 3 seconds tolerance to report empty measurement
+ continue;
+ }
ASSERT_TRUE(lastGnssData.measurements.size() > 0);
// Validity check GnssData fields
diff --git a/graphics/composer/2.2/default/Android.bp b/graphics/composer/2.2/default/Android.bp
new file mode 100644
index 0000000..5753bb0
--- /dev/null
+++ b/graphics/composer/2.2/default/Android.bp
@@ -0,0 +1,51 @@
+// 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 {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "hardware_interfaces_license",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.graphics.composer@2.2-service",
+ vendor: true,
+ relative_install_path: "hw",
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-DLOG_TAG=\"ComposerHal\"",
+ ],
+ srcs: ["service.cpp"],
+ init_rc: ["android.hardware.graphics.composer@2.2-service.rc"],
+ header_libs: ["android.hardware.graphics.composer@2.2-passthrough"],
+ shared_libs: [
+ "android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.2",
+ "android.hardware.graphics.composer@2.1-resources",
+ "android.hardware.graphics.composer@2.2-resources",
+ "libbase",
+ "libbinder",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "libhwc2on1adapter",
+ "libhwc2onfbadapter",
+ "liblog",
+ "libsync",
+ "libutils",
+ ],
+}
diff --git a/graphics/composer/2.2/default/Android.mk b/graphics/composer/2.2/default/Android.mk
deleted file mode 100644
index 6f7ef85..0000000
--- a/graphics/composer/2.2/default/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.graphics.composer@2.2-service
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../../NOTICE
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_CFLAGS := -Wall -Werror -DLOG_TAG=\"ComposerHal\"
-LOCAL_SRC_FILES := service.cpp
-LOCAL_INIT_RC := android.hardware.graphics.composer@2.2-service.rc
-LOCAL_HEADER_LIBRARIES := android.hardware.graphics.composer@2.2-passthrough
-LOCAL_SHARED_LIBRARIES := \
- android.hardware.graphics.composer@2.1 \
- android.hardware.graphics.composer@2.2 \
- android.hardware.graphics.composer@2.1-resources \
- android.hardware.graphics.composer@2.2-resources \
- libbase \
- libbinder \
- libcutils \
- libfmq \
- libhardware \
- libhidlbase \
- libhwc2on1adapter \
- libhwc2onfbadapter \
- liblog \
- libsync \
- libutils
-
-ifdef TARGET_USES_DISPLAY_RENDER_INTENTS
-LOCAL_CFLAGS += -DUSES_DISPLAY_RENDER_INTENTS
-endif
-
-include $(BUILD_EXECUTABLE)
diff --git a/graphics/composer/aidl/vts/RenderEngineVts.cpp b/graphics/composer/aidl/vts/RenderEngineVts.cpp
index 4e7f773..bc5eb6f 100644
--- a/graphics/composer/aidl/vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/vts/RenderEngineVts.cpp
@@ -28,9 +28,7 @@
mRenderEngine = ::android::renderengine::RenderEngine::create(args);
}
-TestRenderEngine::~TestRenderEngine() {
- mRenderEngine.release();
-}
+TestRenderEngine::~TestRenderEngine() {}
void TestRenderEngine::setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers) {
sort(layers.begin(), layers.end(),
diff --git a/health/storage/OWNERS b/health/storage/OWNERS
index 7af8d99..ec1fd8f 100644
--- a/health/storage/OWNERS
+++ b/health/storage/OWNERS
@@ -1,6 +1,9 @@
# Bug component: 30545
+# Don't inherit owners from hardware/interfaces/health/
set noparent
+# But inherit from hardware/interfaces
+include platform/hardware/interfaces:/OWNERS
jaegeuk@google.com
elsk@google.com
diff --git a/health/storage/aidl/Android.bp b/health/storage/aidl/Android.bp
index c614efb..44484d6 100644
--- a/health/storage/aidl/Android.bp
+++ b/health/storage/aidl/Android.bp
@@ -26,6 +26,7 @@
vendor_available: true,
srcs: ["android/hardware/health/storage/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/input/common/aidl/Android.bp b/input/common/aidl/Android.bp
index 0759d2e..8721e5d 100644
--- a/input/common/aidl/Android.bp
+++ b/input/common/aidl/Android.bp
@@ -14,6 +14,7 @@
vendor_available: true,
srcs: ["android/hardware/input/common/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/input/processor/aidl/Android.bp b/input/processor/aidl/Android.bp
index 68adf32..6855b08 100644
--- a/input/processor/aidl/Android.bp
+++ b/input/processor/aidl/Android.bp
@@ -12,6 +12,7 @@
name: "android.hardware.input.processor",
host_supported: true,
vendor_available: true,
+ frozen: true,
srcs: ["android/hardware/input/processor/*.aidl"],
imports: [
"android.hardware.input.common-V1",
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
index 25f6c8f..c561c52 100644
--- a/ir/aidl/Android.bp
+++ b/ir/aidl/Android.bp
@@ -26,6 +26,7 @@
vendor_available: true,
srcs: ["android/hardware/ir/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
cpp: {
enabled: false,
diff --git a/keymaster/4.0/vts/performance/Android.bp b/keymaster/4.0/vts/performance/Android.bp
index d7342ad..8f26871 100644
--- a/keymaster/4.0/vts/performance/Android.bp
+++ b/keymaster/4.0/vts/performance/Android.bp
@@ -33,6 +33,5 @@
"android.hardware.keymaster@4.0",
"libkeymaster4support",
"libsoftkeymasterdevice",
- "libchrome"
],
}
diff --git a/keymaster/4.0/vts/performance/Benchmark.cpp b/keymaster/4.0/vts/performance/Benchmark.cpp
index e5fdff2..723b543 100644
--- a/keymaster/4.0/vts/performance/Benchmark.cpp
+++ b/keymaster/4.0/vts/performance/Benchmark.cpp
@@ -16,6 +16,8 @@
#define LOG_TAG "keymaster_benchmark"
+#include <getopt.h>
+
#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
#include <android/hardware/keymaster/4.0/types.h>
#include <keymaster/keymaster_configuration.h>
@@ -36,8 +38,6 @@
#include <benchmark/benchmark.h>
#include <hidl/Status.h>
-#include <base/command_line.h>
-
namespace android {
namespace hardware {
namespace keymaster {
@@ -700,14 +700,26 @@
} // namespace hardware
} // namespace android
+namespace {
+
+std::string ParseCommandLineFlags(int argc, char** argv) {
+ std::string service_name = "default";
+ static struct option long_options[] = {{"service_name", required_argument, 0, 's'},
+ {0, 0, 0, 0}};
+ int opt;
+ while ((opt = getopt_long(argc, argv, "s:", long_options, nullptr)) != -1) {
+ if (opt == 's') {
+ service_name = optarg;
+ }
+ }
+ return service_name;
+}
+
+} // namespace
+
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
- base::CommandLine::Init(argc, argv);
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- auto service_name = command_line->GetSwitchValueASCII("service_name");
- if (service_name.empty()) {
- service_name = "default";
- }
+ std::string service_name = ParseCommandLineFlags(argc, argv);
android::hardware::keymaster::V4_0::test::keymaster =
android::hardware::keymaster::V4_0::test::KeymasterWrapper::newInstance(service_name);
if (!android::hardware::keymaster::V4_0::test::keymaster) {
diff --git a/light/aidl/Android.bp b/light/aidl/Android.bp
index c9fba95..142be6d 100644
--- a/light/aidl/Android.bp
+++ b/light/aidl/Android.bp
@@ -14,6 +14,7 @@
"android/hardware/light/*.aidl",
],
stability: "vintf",
+ frozen: true,
backend: {
java: {
sdk_version: "module_current",
diff --git a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
index d80e651..2d34afe 100644
--- a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
+++ b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
@@ -93,9 +93,9 @@
void validateAttributes(
const std::map<const std::string, const testing::internal::RE>& knownPatterns,
- const std::vector<const struct AttributePattern>& unknownPatterns,
+ const std::vector<struct AttributePattern>& unknownPatterns,
hidl_vec<IOmxStore::Attribute> attributes) {
- std::set<const std::string> attributeKeys;
+ std::set<std::string> attributeKeys;
for (const auto& attr : attributes) {
// Make sure there are no duplicates
const auto [nodeIter, inserted] = attributeKeys.insert(attr.key);
@@ -179,7 +179,7 @@
* tried for a match with the second element of the pair. If this second
* match fails, the test will fail.
*/
- const std::vector<const struct AttributePattern> unknownPatterns = {
+ const std::vector<struct AttributePattern> unknownPatterns = {
{"supports-[a-z0-9-]*", "0|1"}};
validateAttributes(knownPatterns, unknownPatterns, attributes);
@@ -248,7 +248,7 @@
};
// Strings for matching rules for node attributes with key patterns
- const std::vector<const struct AttributePattern> unknownPatterns = {
+ const std::vector<struct AttributePattern> unknownPatterns = {
{"measured-frame-rate-" + size + "-range", range_num},
{"feature-[a-zA-Z0-9_-]+", string},
};
@@ -257,9 +257,9 @@
const testing::internal::RE nodeNamePattern = "[a-zA-Z0-9._-]+";
const testing::internal::RE nodeOwnerPattern = "[a-zA-Z0-9._-]+";
- std::set<const std::string> roleKeys;
- std::map<const std::string, std::set<const std::string>> nodeToRoles;
- std::map<const std::string, std::set<const std::string>> ownerToNodes;
+ std::set<std::string> roleKeys;
+ std::map<const std::string, std::set<std::string>> nodeToRoles;
+ std::map<const std::string, std::set<std::string>> ownerToNodes;
for (const IOmxStore::RoleInfo& role : roleList) {
// Make sure there are no duplicates
const auto [roleIter, inserted] = roleKeys.insert(role.role);
@@ -276,7 +276,7 @@
}
// Check the nodes for this role
- std::set<const std::string> nodeKeys;
+ std::set<std::string> nodeKeys;
for (const IOmxStore::NodeInfo& node : role.nodes) {
// Make sure there are no duplicates
const auto [nodeIter, inserted] = nodeKeys.insert(node.name);
@@ -317,7 +317,7 @@
// Verify that roles for each node match with the information from
// IOmxStore::listRoles().
- std::set<const std::string> nodeKeys;
+ std::set<std::string> nodeKeys;
for (IOmx::ComponentInfo node : nodeList) {
// Make sure there are no duplicates
const auto [nodeIter, inserted] = nodeKeys.insert(node.mName);
@@ -334,7 +334,7 @@
// All the roles advertised by IOmxStore::listRoles() for this
// node must be included in roleKeys.
- std::set<const std::string> difference;
+ std::set<std::string> difference;
std::set_difference(nodeToRoles[node.mName].begin(), nodeToRoles[node.mName].end(),
roleKeys.begin(), roleKeys.end(),
std::inserter(difference, difference.begin()));
@@ -347,7 +347,7 @@
}
// Check that all nodes obtained from IOmxStore::listRoles() are
// supported by the their corresponding IOmx instances.
- std::set<const std::string> difference;
+ std::set<std::string> difference;
std::set_difference(nodes.begin(), nodes.end(), nodeKeys.begin(), nodeKeys.end(),
std::inserter(difference, difference.begin()));
EXPECT_EQ(difference.empty(), true) << "IOmx::listNodes() for IOmx "
diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp
index 145604c..c9242ca 100644
--- a/neuralnetworks/aidl/Android.bp
+++ b/neuralnetworks/aidl/Android.bp
@@ -11,6 +11,7 @@
name: "android.hardware.neuralnetworks",
host_supported: true,
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/neuralnetworks/*.aidl",
],
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
index ae68f17..b34e4f2 100644
--- a/nfc/aidl/Android.bp
+++ b/nfc/aidl/Android.bp
@@ -27,6 +27,7 @@
vendor_available: true,
srcs: ["android/hardware/nfc/*.aidl"],
stability: "vintf",
+ frozen: false,
backend: {
cpp: {
enabled: false,
diff --git a/oemlock/aidl/Android.bp b/oemlock/aidl/Android.bp
index 1c19bb1..f4533ed 100644
--- a/oemlock/aidl/Android.bp
+++ b/oemlock/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.oemlock",
vendor_available: true,
+ frozen: true,
srcs: ["android/hardware/oemlock/*.aidl"],
stability: "vintf",
backend: {
diff --git a/rebootescrow/aidl/Android.bp b/rebootescrow/aidl/Android.bp
index 39aaa07..3d5b827 100644
--- a/rebootescrow/aidl/Android.bp
+++ b/rebootescrow/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.rebootescrow",
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/rebootescrow/IRebootEscrow.aidl",
],
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index f669110..9e3e159 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -253,39 +253,14 @@
// Collection of valid attestation ID tags.
auto attestation_id_tags = AuthorizationSetBuilder();
- // Use ro.product.brand_for_attestation property for attestation if it is present else fallback
- // to ro.product.brand
- std::string prop_value =
- ::android::base::GetProperty("ro.product.brand_for_attestation", /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND,
- "ro.product.brand_for_attestation");
- } else {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "ro.product.brand");
- }
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "ro.product.device");
- // Use ro.product.name_for_attestation property for attestation if it is present else fallback
- // to ro.product.name
- prop_value = ::android::base::GetProperty("ro.product.name_for_attestation", /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT,
- "ro.product.name_for_attestation");
- } else {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "ro.product.name");
- }
+
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_BRAND, "brand");
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_DEVICE, "device");
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_PRODUCT, "name");
add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_SERIAL, "ro.serialno");
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER,
- "ro.product.manufacturer");
- // Use ro.product.model_for_attestation property for attestation if it is present else fallback
- // to ro.product.model
- prop_value =
- ::android::base::GetProperty("ro.product.model_for_attestation", /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL,
- "ro.product.model_for_attestation");
- } else {
- add_tag_from_prop(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "ro.product.model");
- }
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_MANUFACTURER, "manufacturer");
+ add_attestation_id(&attestation_id_tags, TAG_ATTESTATION_ID_MODEL, "model");
+
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index c19ab11..cfe9fa7 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -2400,6 +2400,43 @@
return imei;
}
+std::optional<std::string> get_attestation_id(const char* prop) {
+ // The frameworks code (in AndroidKeyStoreKeyPairGeneratorSpi.java) populates device ID
+ // values from one of 3 places, so the same logic needs to be reproduced here so the tests
+ // check what's expected correctly.
+ //
+ // In order of preference, the properties checked are:
+ //
+ // 1) `ro.product.<device-id>_for_attestation`: This should only be set in special cases; in
+ // particular, AOSP builds for reference devices use a different value than the normal
+ // builds for the same device (e.g. model of "aosp_raven" instead of "raven").
+ ::android::String8 prop_name =
+ ::android::String8::format("ro.product.%s_for_attestation", prop);
+ std::string prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
+ if (!prop_value.empty()) {
+ return prop_value;
+ }
+
+ // 2) `ro.product.vendor.<device-id>`: This property refers to the vendor code, and so is
+ // retained even in a GSI environment.
+ prop_name = ::android::String8::format("ro.product.vendor.%s", prop);
+ prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
+ if (!prop_value.empty()) {
+ return prop_value;
+ }
+
+ // 3) `ro.product.<device-id>`: Note that this property is replaced by a default value when
+ // running a GSI environment, and so will *not* match the value expected/used by the
+ // vendor code on the device.
+ prop_name = ::android::String8::format("ro.product.%s", prop);
+ prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
+ if (!prop_value.empty()) {
+ return prop_value;
+ }
+
+ return std::nullopt;
+}
+
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 0368bba..85ae93d 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -17,6 +17,7 @@
#pragma once
#include <functional>
+#include <optional>
#include <string_view>
#include <aidl/Gtest.h>
@@ -384,14 +385,20 @@
const string& plaintext, const string& exp_cipher_text);
};
+// If the given string is non-empty, add it to the tag set under the given tag ID.
+template <Tag tag>
+void add_tag(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
+ const std::string& prop_value) {
+ if (!prop_value.empty()) {
+ tags->Authorization(ttag, prop_value.data(), prop_value.size());
+ }
+}
+
// If the given property is available, add it to the tag set under the given tag ID.
template <Tag tag>
void add_tag_from_prop(AuthorizationSetBuilder* tags, TypedTag<TagType::BYTES, tag> ttag,
const char* prop) {
- std::string prop_value = ::android::base::GetProperty(prop, /* default= */ "");
- if (!prop_value.empty()) {
- tags->Authorization(ttag, prop_value.data(), prop_value.size());
- }
+ add_tag(tags, ttag, ::android::base::GetProperty(prop, /* default= */ ""));
}
// Return the VSR API level for this device.
@@ -431,6 +438,20 @@
std::optional<int32_t> keymint_feature_value(bool strongbox);
std::string get_imei(int slot);
+// Retrieve a device ID property value, to match what is expected in attestations.
+std::optional<std::string> get_attestation_id(const char* prop);
+
+// Add the appropriate attestation device ID tag value to the provided `AuthorizationSetBuilder`,
+// if found.
+template <Tag tag>
+void add_attestation_id(AuthorizationSetBuilder* attestation_id_tags,
+ TypedTag<TagType::BYTES, tag> tag_type, const char* prop) {
+ auto prop_value = get_attestation_id(prop);
+ if (prop_value.has_value()) {
+ add_tag(attestation_id_tags, tag_type, prop_value.value());
+ }
+}
+
AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
@@ -444,29 +465,6 @@
::android::PrintInstanceNameToString); \
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);
-// Use `ro.product.<property>_for_attestation` property for attestation if it is present else
-// fallback to use `ro.product.vendor.<property>` if it is present else fallback to
-// `ro.product.<property>`. Similar logic can be seen in Java method `getVendorDeviceIdProperty`
-// in frameworks/base/core/java/android/os/Build.java.
-template <Tag tag>
-void add_attestation_id(AuthorizationSetBuilder* attestation_id_tags,
- TypedTag<TagType::BYTES, tag> tag_type, const char* prop) {
- ::android::String8 prop_name =
- ::android::String8::format("ro.product.%s_for_attestation", prop);
- std::string prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
- } else {
- prop_name = ::android::String8::format("ro.product.vendor.%s", prop);
- prop_value = ::android::base::GetProperty(prop_name.c_str(), /* default= */ "");
- if (!prop_value.empty()) {
- add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
- } else {
- prop_name = ::android::String8::format("ro.product.%s", prop);
- add_tag_from_prop(attestation_id_tags, tag_type, prop_name.c_str());
- }
- }
-}
} // namespace test
} // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 5c9efef..608d328 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -40,6 +40,9 @@
export_include_dirs: [
"include",
],
+ header_libs: [
+ "libhardware_headers",
+ ],
defaults: [
"keymint_use_latest_hal_aidl_ndk_shared",
],
diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp
index 853ad89..d7e7b43 100644
--- a/security/secureclock/aidl/Android.bp
+++ b/security/secureclock/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.security.secureclock",
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/security/secureclock/*.aidl",
],
diff --git a/security/sharedsecret/aidl/Android.bp b/security/sharedsecret/aidl/Android.bp
index fe77c10..adf33d3 100644
--- a/security/sharedsecret/aidl/Android.bp
+++ b/security/sharedsecret/aidl/Android.bp
@@ -10,6 +10,7 @@
aidl_interface {
name: "android.hardware.security.sharedsecret",
vendor_available: true,
+ frozen: true,
srcs: [
"android/hardware/security/sharedsecret/*.aidl",
],
diff --git a/soundtrigger/2.0/default/Android.bp b/soundtrigger/2.0/default/Android.bp
index 2cbf041..2e61f9b 100644
--- a/soundtrigger/2.0/default/Android.bp
+++ b/soundtrigger/2.0/default/Android.bp
@@ -46,3 +46,36 @@
"libhardware_headers",
],
}
+
+soong_config_module_type {
+ name: "soundtrigger_cc_library_shared",
+ module_type: "cc_library_shared",
+ config_namespace: "soundtrigger",
+ value_variables: [
+ "audioserver_multilib",
+ ],
+ properties: ["compile_multilib"],
+}
+
+soundtrigger_cc_library_shared {
+ name: "android.hardware.soundtrigger@2.0-impl",
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: ["FetchISoundTriggerHw.cpp"],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libhardware",
+ "libutils",
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.0-core",
+ ],
+ compile_multilib: "32",
+ soong_config_variables: {
+ audioserver_multilib: {
+ compile_multilib: "%s",
+ },
+ },
+}
diff --git a/soundtrigger/2.0/default/Android.mk b/soundtrigger/2.0/default/Android.mk
deleted file mode 100644
index 17e4440..0000000
--- a/soundtrigger/2.0/default/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Copyright (C) 2016 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.
-
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.soundtrigger@2.0-impl
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
- FetchISoundTriggerHw.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
- libhardware \
- libutils \
- android.hardware.soundtrigger@2.0 \
- android.hardware.soundtrigger@2.0-core
-
-LOCAL_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
-LOCAL_MULTILIB := 32
-else
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/soundtrigger/2.1/default/Android.bp b/soundtrigger/2.1/default/Android.bp
new file mode 100644
index 0000000..a246680
--- /dev/null
+++ b/soundtrigger/2.1/default/Android.bp
@@ -0,0 +1,57 @@
+//
+// 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.
+
+package {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: [
+ "hardware_interfaces_license",
+ ],
+}
+
+soong_config_module_type_import {
+ from: "hardware/interfaces/soundtrigger/2.0/default/Android.bp",
+ module_types: ["soundtrigger_cc_library_shared"],
+}
+
+soundtrigger_cc_library_shared {
+ name: "android.hardware.soundtrigger@2.1-impl",
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: ["SoundTriggerHw.cpp"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "libhardware",
+ "libhidlbase",
+ "libhidlmemory",
+ "liblog",
+ "libutils",
+ "android.hardware.soundtrigger@2.1",
+ "android.hardware.soundtrigger@2.0",
+ "android.hardware.soundtrigger@2.0-core",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ ],
+ compile_multilib: "32",
+ soong_config_variables: {
+ audioserver_multilib: {
+ compile_multilib: "%s",
+ },
+ },
+}
diff --git a/soundtrigger/2.1/default/Android.mk b/soundtrigger/2.1/default/Android.mk
deleted file mode 100644
index 602f5a7..0000000
--- a/soundtrigger/2.1/default/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# 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.
-
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.soundtrigger@2.1-impl
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../../NOTICE
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
- SoundTriggerHw.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
- libhardware \
- libhidlbase \
- libhidlmemory \
- liblog \
- libutils \
- android.hardware.soundtrigger@2.1 \
- android.hardware.soundtrigger@2.0 \
- android.hardware.soundtrigger@2.0-core \
- android.hidl.allocator@1.0 \
- android.hidl.memory@1.0
-
-LOCAL_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
-LOCAL_MULTILIB := 32
-else
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/threadnetwork/aidl/default/socket_interface.cpp b/threadnetwork/aidl/default/socket_interface.cpp
index a5aa2b4..71c6b4f 100644
--- a/threadnetwork/aidl/default/socket_interface.cpp
+++ b/threadnetwork/aidl/default/socket_interface.cpp
@@ -36,6 +36,7 @@
#include <vector>
#include "common/code_utils.hpp"
+#include "openthread/error.h"
#include "openthread/openthread-system.h"
#include "platform-posix.h"
@@ -56,14 +57,9 @@
otError SocketInterface::Init(ReceiveFrameCallback aCallback, void* aCallbackContext,
RxFrameBuffer& aFrameBuffer) {
- otError error = OT_ERROR_NONE;
+ otError error = InitSocket();
- VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
-
- WaitForSocketFileCreated(mRadioUrl.GetPath());
-
- mSockFd = OpenFile(mRadioUrl);
- VerifyOrExit(mSockFd != -1, error = OT_ERROR_FAILED);
+ VerifyOrExit(error == OT_ERROR_NONE);
mReceiveFrameCallback = aCallback;
mReceiveFrameContext = aCallbackContext;
@@ -155,9 +151,22 @@
VerifyOrExit(!mIsHardwareResetting, error = OT_ERROR_FAILED);
- WaitForSocketFileCreated(mRadioUrl.GetPath());
- mSockFd = OpenFile(mRadioUrl);
- VerifyOrExit(mSockFd != -1, error = OT_ERROR_FAILED);
+exit:
+ return error;
+}
+
+otError SocketInterface::InitSocket() {
+ otError error = OT_ERROR_NONE;
+ int retries = 0;
+
+ VerifyOrExit(mSockFd == -1, error = OT_ERROR_ALREADY);
+
+ while (retries++ < kMaxRetriesForSocketInit) {
+ WaitForSocketFileCreated(mRadioUrl.GetPath());
+ mSockFd = OpenFile(mRadioUrl);
+ VerifyOrExit(mSockFd == -1);
+ }
+ error = OT_ERROR_FAILED;
exit:
return error;
@@ -168,11 +177,16 @@
assert(context != nullptr);
+ VerifyOrExit(mSockFd != -1);
+
FD_SET(mSockFd, &context->mReadFdSet);
if (context->mMaxFd < mSockFd) {
context->mMaxFd = mSockFd;
}
+
+exit:
+ return;
}
void SocketInterface::Process(const void* aMainloopContext) {
@@ -181,9 +195,14 @@
assert(context != nullptr);
+ VerifyOrExit(mSockFd != -1);
+
if (FD_ISSET(mSockFd, &context->mReadFdSet)) {
Read();
}
+
+exit:
+ return;
}
otError SocketInterface::HardwareReset(void) {
@@ -198,22 +217,24 @@
void SocketInterface::Read(void) {
uint8_t buffer[kMaxFrameSize];
+ ssize_t rval;
- ssize_t rval = TEMP_FAILURE_RETRY(read(mSockFd, buffer, sizeof(buffer)));
+ VerifyOrExit(mSockFd != -1);
+
+ rval = TEMP_FAILURE_RETRY(read(mSockFd, buffer, sizeof(buffer)));
if (rval > 0) {
ProcessReceivedData(buffer, static_cast<uint16_t>(rval));
} else if (rval < 0) {
DieNow(OT_EXIT_ERROR_ERRNO);
} else {
- if (mIsHardwareResetting) {
- LogInfo("Socket connection is closed due to hardware reset.");
- ResetStates();
- } else {
- LogCrit("Socket connection is closed by remote.");
- exit(OT_EXIT_FAILURE);
- }
+ LogWarn("Socket connection is closed by remote, isHardwareReset: %d", mIsHardwareResetting);
+ ResetStates();
+ InitSocket();
}
+
+exit:
+ return;
}
void SocketInterface::Write(const uint8_t* aFrame, uint16_t aLength) {
diff --git a/threadnetwork/aidl/default/socket_interface.hpp b/threadnetwork/aidl/default/socket_interface.hpp
index 494d76a..83c86e8 100644
--- a/threadnetwork/aidl/default/socket_interface.hpp
+++ b/threadnetwork/aidl/default/socket_interface.hpp
@@ -247,6 +247,15 @@
otError WaitForHardwareResetCompletion(uint32_t aTimeoutMs);
/**
+ * Initialize socket
+ *
+ * @retval TRUE Socket initialization is successful.
+ * @retval FALSE Socket initialization is failed.
+ *
+ */
+ otError InitSocket();
+
+ /**
* Reset socket interface to intitial state.
*
*/
@@ -257,6 +266,7 @@
///< descriptor to become available.
kMaxRetriesForSocketCloseCheck = 3, ///< Maximum retry times for checking
///< if socket is closed.
+ kMaxRetriesForSocketInit = 3, ///< Maximum retry times for socket initialization.
};
ReceiveFrameCallback mReceiveFrameCallback;
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index abd6a23..655d8a2 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -16,6 +16,7 @@
srcs: ["android/hardware/uwb/*.aidl"],
stability: "vintf",
host_supported: true,
+ frozen: true,
backend: {
java: {
sdk_version: "module_Tiramisu",
@@ -56,6 +57,7 @@
vendor_available: true,
srcs: ["android/hardware/uwb/fira_android/*.aidl"],
stability: "vintf",
+ frozen: false,
backend: {
java: {
sdk_version: "module_Tiramisu",
diff --git a/weaver/vts/VtsHalWeaverTargetTest.cpp b/weaver/vts/VtsHalWeaverTargetTest.cpp
index 8952dfc..faa8416 100644
--- a/weaver/vts/VtsHalWeaverTargetTest.cpp
+++ b/weaver/vts/VtsHalWeaverTargetTest.cpp
@@ -220,13 +220,10 @@
used_slots.insert(slot);
}
}
- // Starting in Android 14, the system will always use at least one Weaver slot if Weaver is
- // supported at all. This is true even if an LSKF hasn't been set yet, since Weaver is used to
- // protect the initial binding of each user's synthetic password to ensure that binding can be
- // securely deleted if an LSKF is set later. Make sure we saw at least one slot, as otherwise
- // the Weaver implementation must have a bug that makes it not fully usable by Android.
- ASSERT_FALSE(used_slots.empty())
- << "Could not determine which Weaver slots are in use by the system";
+
+ // We should assert !used_slots.empty() here, but that can't be done yet due to
+ // config_disableWeaverOnUnsecuredUsers being supported. The value of that option is not
+ // accessible from here, so we have to assume it might be set to true.
// Find the first free slot.
int found = 0;
diff --git a/wifi/netlinkinterceptor/aidl/Android.bp b/wifi/netlinkinterceptor/aidl/Android.bp
index 8c04e31..bc02125 100644
--- a/wifi/netlinkinterceptor/aidl/Android.bp
+++ b/wifi/netlinkinterceptor/aidl/Android.bp
@@ -29,6 +29,7 @@
vendor_available: true,
srcs: ["android/hardware/net/nlinterceptor/*.aidl"],
stability: "vintf",
+ frozen: true,
backend: {
java: {
enabled: false,