diff options
26 files changed, 254 insertions, 318 deletions
diff --git a/audio/4.0/config/audio_policy_configuration.xsd b/audio/4.0/config/audio_policy_configuration.xsd index f26e41b42..58bab227f 100644 --- a/audio/4.0/config/audio_policy_configuration.xsd +++ b/audio/4.0/config/audio_policy_configuration.xsd @@ -357,10 +357,6 @@ <xs:enumeration value="AUDIO_FORMAT_APTX_HD"/> <xs:enumeration value="AUDIO_FORMAT_AC4"/> <xs:enumeration value="AUDIO_FORMAT_LDAC"/> - <xs:enumeration value="AUDIO_FORMAT_E_AC3_JOC"/> - <xs:enumeration value="AUDIO_FORMAT_MAT_1_0"/> - <xs:enumeration value="AUDIO_FORMAT_MAT_2_0"/> - <xs:enumeration value="AUDIO_FORMAT_MAT_2_1"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="extendableAudioFormat"> diff --git a/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc b/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc index 8217b946d..6e91bccb3 100644 --- a/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc +++ b/audio/common/all-versions/default/service/android.hardware.audio@2.0-service.rc @@ -2,7 +2,8 @@ service vendor.audio-hal-2-0 /vendor/bin/hw/android.hardware.audio@2.0-service class hal user audioserver # media gid needed for /dev/fm (radio) and for /data/misc/media (tee) - group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct + group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock + capabilities BLOCK_SUSPEND ioprio rt 4 writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks # audioflinger restarts itself when it loses connection with the hal diff --git a/audio/common/all-versions/test/utility/include/utility/ValidateXml.h b/audio/common/all-versions/test/utility/include/utility/ValidateXml.h index 4abd3fa8e..91adfc12c 100644 --- a/audio/common/all-versions/test/utility/include/utility/ValidateXml.h +++ b/audio/common/all-versions/test/utility/include/utility/ValidateXml.h @@ -34,10 +34,6 @@ namespace utility { ::testing::AssertionResult validateXml(const char* xmlFilePathExpr, const char* xsdFilePathExpr, const char* xmlFilePath, const char* xsdFilePath); -std::vector<std::string> findValidXmlFiles(const char* xsdFilePathExpr, - const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath, - std::vector<std::string>* errors = nullptr); - /** Helper gtest ASSERT to test XML validity against an XSD. */ #define ASSERT_VALID_XML(xmlFilePath, xsdFilePath) \ ASSERT_PRED_FORMAT2(::android::hardware::audio::common::test::utility::validateXml, \ @@ -82,9 +78,6 @@ template <bool atLeastOneRequired = true> ::android::hardware::audio::common::test::utility::validateXmlMultipleLocations<true>, \ xmlFileName, xmlFileLocations, xsdFilePath) -::testing::AssertionResult isNonEmptyXpath( - const char* xmlFilePath, const char* xpathQuery, bool* result); - } // namespace utility } // namespace test } // namespace common diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp index 126873d6f..1a906d668 100644 --- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp +++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp @@ -23,8 +23,6 @@ #include <libxml/xmlschemastypes.h> #define LIBXML_XINCLUDE_ENABLED #include <libxml/xinclude.h> -#define LIBXML_XPATH_ENABLED -#include <libxml/xpath.h> #include <memory> #include <string> @@ -49,10 +47,6 @@ template <> constexpr auto xmlDeleter<xmlSchemaParserCtxt> = xmlSchemaFreeParserCtxt; template <> constexpr auto xmlDeleter<xmlSchemaValidCtxt> = xmlSchemaFreeValidCtxt; -template <> -constexpr auto xmlDeleter<xmlXPathContext> = xmlXPathFreeContext; -template <> -constexpr auto xmlDeleter<xmlXPathObject> = xmlXPathFreeObject; /** @return a unique_ptr with the correct deleter for the libxml2 object. */ template <class T> @@ -135,37 +129,27 @@ struct Libxml2Global { return ::testing::AssertionSuccess(); } -std::vector<std::string> findValidXmlFiles( - const char* xsdFilePathExpr, - const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath, - std::vector<std::string>* errors) { +template <bool atLeastOneRequired> +::testing::AssertionResult validateXmlMultipleLocations( + const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr, + const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath) { using namespace std::string_literals; + + std::vector<std::string> errors; std::vector<std::string> foundFiles; + for (const char* location : xmlFileLocations) { std::string xmlFilePath = location + "/"s + xmlFileName; if (access(xmlFilePath.c_str(), F_OK) != 0) { // If the file does not exist ignore this location and fallback on the next one continue; } + foundFiles.push_back(" " + xmlFilePath + '\n'); auto result = validateXml("xmlFilePath", xsdFilePathExpr, xmlFilePath.c_str(), xsdFilePath); if (!result) { - if (errors != nullptr) errors->push_back(result.message()); - } else { - foundFiles.push_back(xmlFilePath); + errors.push_back(result.message()); } } - return foundFiles; -} - -template <bool atLeastOneRequired> -::testing::AssertionResult validateXmlMultipleLocations( - const char* xmlFileNameExpr, const char* xmlFileLocationsExpr, const char* xsdFilePathExpr, - const char* xmlFileName, std::vector<const char*> xmlFileLocations, const char* xsdFilePath) { - using namespace std::string_literals; - - std::vector<std::string> errors; - std::vector<std::string> foundFiles = findValidXmlFiles( - xsdFilePathExpr, xmlFileName, xmlFileLocations, xsdFilePath, &errors); if (atLeastOneRequired && foundFiles.empty()) { errors.push_back("No xml file found in provided locations.\n"); @@ -191,35 +175,6 @@ template ::testing::AssertionResult validateXmlMultipleLocations<false>(const ch std::vector<const char*>, const char*); -::testing::AssertionResult isNonEmptyXpath( - const char* xmlFilePath, const char* xpathQuery, bool* result) { - Libxml2Global libxml2; - - auto context = [&]() { - return std::string() + " In: " + xmlFilePath + "\nLibxml2 errors:\n" + libxml2.getErrors(); - }; - - auto doc = make_xmlUnique(xmlReadFile(xmlFilePath, nullptr, 0)); - if (doc == nullptr) { - return ::testing::AssertionFailure() << "Failed to parse xml\n" << context(); - } - if (xmlXIncludeProcess(doc.get()) == -1) { - return ::testing::AssertionFailure() << "Failed to resolve xincludes in xml\n" << context(); - } - auto xpathCtxt = make_xmlUnique(xmlXPathNewContext(doc.get())); - if (xpathCtxt == nullptr) { - return ::testing::AssertionFailure() << "Failed to create xpath context\n" << context(); - } - auto xpathObj = make_xmlUnique(xmlXPathEvalExpression(BAD_CAST xpathQuery, xpathCtxt.get())); - if (xpathObj == nullptr) { - return ::testing::AssertionFailure() << - "Failed to evaluate xpath: \'" << xpathQuery << "\'\n" << context(); - } - auto nodeSet = xpathObj.get()->nodesetval; - *result = nodeSet ? nodeSet->nodeNr != 0 : false; - return ::testing::AssertionSuccess(); -} - } // namespace utility } // namespace test } // namespace common diff --git a/audio/core/4.0/vts/functional/Android.bp b/audio/core/4.0/vts/functional/Android.bp index 48a98b1fe..e3b376ca8 100644 --- a/audio/core/4.0/vts/functional/Android.bp +++ b/audio/core/4.0/vts/functional/Android.bp @@ -18,7 +18,6 @@ cc_test { name: "VtsHalAudioV4_0TargetTest", defaults: ["VtsHalTargetTestDefaults"], srcs: [ - "AudioPolicyConfiguration.cpp", "AudioPrimaryHidlHalTest.cpp", "ValidateAudioConfiguration.cpp" ], diff --git a/audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp b/audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp deleted file mode 100644 index 254c018e3..000000000 --- a/audio/core/4.0/vts/functional/AudioPolicyConfiguration.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AudioPolicyConfiguration.h" - -const char* kAudioPolicyConfigurationXml = "audio_policy_configuration.xml"; -const char* kAudioPolicyConfigurationXsd = - "/data/local/tmp/audio_policy_configuration_V4_0.xsd"; - -const std::vector<const char*>& getApmConfigLocations() { - static const std::vector<const char*> locations = {"/odm/etc", "/vendor/etc", "/system/etc"}; - return locations; -} diff --git a/audio/core/4.0/vts/functional/AudioPolicyConfiguration.h b/audio/core/4.0/vts/functional/AudioPolicyConfiguration.h deleted file mode 100644 index 13a62ed73..000000000 --- a/audio/core/4.0/vts/functional/AudioPolicyConfiguration.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vector> - -extern const char* kAudioPolicyConfigurationXml; -extern const char* kAudioPolicyConfigurationXsd; - -const std::vector<const char*>& getApmConfigLocations(); diff --git a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp index 8e05beb1d..46c228a19 100644 --- a/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/4.0/vts/functional/AudioPrimaryHidlHalTest.cpp @@ -45,14 +45,12 @@ #include <common/all-versions/VersionUtils.h> -#include "AudioPolicyConfiguration.h" #include "utility/AssertOk.h" #include "utility/Documentation.h" #include "utility/EnvironmentTearDown.h" #define AUDIO_HAL_VERSION V4_0 #include "utility/PrettyPrintAudioTypes.h" #include "utility/ReturnIn.h" -#include "utility/ValidateXml.h" using std::initializer_list; using std::string; @@ -157,11 +155,6 @@ class AudioHidlTest : public HidlTest { protected: // Cache the devicesFactory retrieval to speed up each test by ~0.5s static sp<IDevicesFactory> devicesFactory; - - static bool isPrimaryDeviceOptional() { - // It's OK not to have "primary" device on non-default audio HAL service. - return environment->getServiceName<IDevicesFactory>() != kDefaultServiceName; - } }; sp<IDevicesFactory> AudioHidlTest::devicesFactory; @@ -178,7 +171,19 @@ TEST_F(AudioHidlTest, OpenDeviceInvalidParameter) { ASSERT_TRUE(device == nullptr); } -static void waitForDeviceDestruction() { +TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) { + doc::test("Calling openDevice(\"primary\") should return the primary device."); + { + Result result; + sp<IDevice> baseDevice; + ASSERT_OK(devicesFactory->openDevice("primary", returnIn(result, baseDevice))); + ASSERT_OK(result); + ASSERT_TRUE(baseDevice != nullptr); + + Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice); + ASSERT_TRUE(primaryDevice.isOk()); + ASSERT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr); + } // Destroy local IDevice proxy // FIXME: there is no way to know when the remote IDevice is being destroyed // Binder does not support testing if an object is alive, thus // wait for 100ms to let the binder destruction propagates and @@ -186,26 +191,7 @@ static void waitForDeviceDestruction() { // flushCommand makes sure all local command are sent, thus should reduce // the latency between local and remote destruction. IPCThreadState::self()->flushCommands(); - usleep(100*1000); -} - -TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) { - doc::test("Calling openDevice(\"primary\") should return the primary device."); - struct WaitExecutor { - ~WaitExecutor() { waitForDeviceDestruction(); } - } waitExecutor; // Make sure we wait for the device destruction on exiting from the test. - Result result; - sp<IDevice> baseDevice; - ASSERT_OK(devicesFactory->openDevice("primary", returnIn(result, baseDevice))); - if (result != Result::OK && isPrimaryDeviceOptional()) { - return SUCCEED() << "No primary device on this factory"; - } - ASSERT_OK(result); - ASSERT_TRUE(baseDevice != nullptr); - - Return<sp<IPrimaryDevice>> primaryDevice = IPrimaryDevice::castFrom(baseDevice); - ASSERT_TRUE(primaryDevice.isOk()); - ASSERT_TRUE(sp<IPrimaryDevice>(primaryDevice) != nullptr); + usleep(100); } ////////////////////////////////////////////////////////////////////////////// @@ -218,44 +204,29 @@ class AudioPrimaryHidlTest : public AudioHidlTest { /** Primary HAL test are NOT thread safe. */ void SetUp() override { ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base + if (device == nullptr) { - initPrimaryDevice(); - if (device == nullptr && isPrimaryDeviceOptional()) { - return SUCCEED() << "No primary device on this factory"; - } + Result result; + ASSERT_OK(devicesFactory->openPrimaryDevice(returnIn(result, device))); + ASSERT_OK(result); + ASSERT_TRUE(device != nullptr); + + environment->registerTearDown([] { device.clear(); }); } - ASSERT_TRUE(device != nullptr); } protected: // Cache the device opening to speed up each test by ~0.5s static sp<IPrimaryDevice> device; - - static void initPrimaryDevice() { - ASSERT_TRUE(devicesFactory != nullptr); - Result result; - ASSERT_OK(devicesFactory->openPrimaryDevice(returnIn(result, device))); - ASSERT_OK(result); - if (device != nullptr) { - environment->registerTearDown([] { device.clear(); }); - } - } }; sp<IPrimaryDevice> AudioPrimaryHidlTest::device; -#define SKIP_IF_NO_DEVICE \ - if (!device) { \ - doc::partialTest("No primary device on this factory"); \ - return; \ - } \ - TEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) { doc::test("Test the openDevice (called in SetUp)"); } TEST_F(AudioPrimaryHidlTest, Init) { doc::test("Test that the audio primary hal initialized correctly"); - SKIP_IF_NO_DEVICE; ASSERT_OK(device->initCheck()); } @@ -279,7 +250,6 @@ class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest { void testAccessors(const string& propertyName, const Initial expectedInitial, list<Property> valuesToTest, Setter setter, Getter getter, const vector<Property>& invalidValues = {}) { - SKIP_IF_NO_DEVICE; const auto expectedResults = {Result::OK, optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK}; @@ -362,7 +332,6 @@ class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest { TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) { doc::test("Test if audio patches are supported"); - SKIP_IF_NO_DEVICE; if (!areAudioPatchesSupported()) { doc::partialTest("Audio patches are not supported"); return; @@ -379,29 +348,8 @@ TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) { /////////// TODO: move to the beginning of the file for easier update //////// ////////////////////////////////////////////////////////////////////////////// -static void hasDeviceTypeInModule( - const std::string& module, const std::string& device, bool* result) { - const std::vector<std::string> configs = findValidXmlFiles( - "", kAudioPolicyConfigurationXml, getApmConfigLocations(), - kAudioPolicyConfigurationXsd); - *result = true; // If could not get the information, run all tests - ASSERT_EQ(1U, configs.size()); - std::string query = "/audioPolicyConfiguration/modules/module[@name=\"" + module + "\"]" + - "/devicePorts/devicePort[@type=\"" + device + "\"]"; - ASSERT_NO_FATAL_FAILURE(isNonEmptyXpath(configs[0].c_str(), query.c_str(), result)); -} - class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest { public: - static bool primaryHasMic() { - static const bool hasMic = []() { - bool result; - hasDeviceTypeInModule("primary", "AUDIO_DEVICE_IN_BUILTIN_MIC", &result); - return result; - }(); - return hasMic; - } - // Cache result ? static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() { return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO}, @@ -421,12 +369,10 @@ class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest { } static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() { - if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100}, {AudioFormat::PCM_16_BIT}); } static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() { - if (!primaryHasMic()) return {}; return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000}, {AudioFormat::PCM_16_BIT}); } @@ -485,7 +431,6 @@ class AudioCaptureConfigPrimaryTest : public AudioConfigPrimaryTest, public ::testing::WithParamInterface<AudioConfig> { protected: void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) { - SKIP_IF_NO_DEVICE; uint64_t bufferSize; ASSERT_OK(device->getInputBufferSize(audioConfig, returnIn(res, bufferSize))); @@ -542,7 +487,6 @@ INSTANTIATE_TEST_CASE_P( TEST_F(AudioPrimaryHidlTest, setScreenState) { doc::test("Check that the hal can receive the screen state"); - SKIP_IF_NO_DEVICE; for (bool turnedOn : {false, true, true, false, false}) { ASSERT_RESULT(okOrNotSupported, device->setScreenState(turnedOn)); } @@ -554,7 +498,6 @@ TEST_F(AudioPrimaryHidlTest, setScreenState) { TEST_F(AudioPrimaryHidlTest, getParameters) { doc::test("Check that the hal can set and get parameters"); - SKIP_IF_NO_DEVICE; hidl_vec<ParameterValue> context; hidl_vec<hidl_string> keys; hidl_vec<ParameterValue> values; @@ -570,13 +513,8 @@ TEST_F(AudioPrimaryHidlTest, getParameters) { TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) { doc::test("Make sure getMicrophones always succeeds"); - SKIP_IF_NO_DEVICE; hidl_vec<MicrophoneInfo> microphones; ASSERT_OK(device->getMicrophones(returnIn(res, microphones))); - if (res == Result::NOT_SUPPORTED) { - doc::partialTest("getMicrophones is not supported"); - return; - } ASSERT_OK(res); if (microphones.size() > 0) { // When there is microphone on the phone, try to open an input stream @@ -690,19 +628,16 @@ static void testDebugDump(DebugDump debugDump) { TEST_F(AudioPrimaryHidlTest, DebugDump) { doc::test("Check that the hal can dump its state without error"); - SKIP_IF_NO_DEVICE; testDebugDump([](const auto& handle) { return device->debug(handle, {/* options */}); }); } TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) { doc::test("Check that the hal dump doesn't crash on invalid arguments"); - SKIP_IF_NO_DEVICE; ASSERT_OK(device->debug(hidl_handle(), {/* options */})); } TEST_F(AudioPrimaryHidlTest, SetConnectedState) { doc::test("Check that the HAL can be notified of device connection and deconnection"); - SKIP_IF_NO_DEVICE; using AD = AudioDevice; for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) { SCOPED_TRACE("device=" + ::testing::PrintToString(deviceType)); @@ -719,13 +654,6 @@ TEST_F(AudioPrimaryHidlTest, SetConnectedState) { ASSERT_OK(ret); } } - - // Because there is no way of knowing if the devices were connected before - // calling setConnectedState, there is no way to restore the HAL to its - // initial state. To workaround this, destroy the HAL at the end of this test. - device.clear(); - waitForDeviceDestruction(); - ASSERT_NO_FATAL_FAILURE(initPrimaryDevice()); } ////////////////////////////////////////////////////////////////////////////// @@ -738,7 +666,6 @@ class OpenStreamTest : public AudioConfigPrimaryTest, protected: template <class Open> void testOpen(Open openStream, const AudioConfig& config) { - SKIP_IF_NO_DEVICE; // FIXME: Open a stream without an IOHandle // This is not required to be accepted by hal implementations AudioIoHandle ioHandle = (AudioIoHandle)AudioHandleConsts::AUDIO_IO_HANDLE_NONE; @@ -771,29 +698,14 @@ class OpenStreamTest : public AudioConfigPrimaryTest, Return<Result> closeStream() { open = false; - auto res = stream->close(); - stream.clear(); - waitForStreamDestruction(); - return res; - } - - void waitForStreamDestruction() { - // FIXME: there is no way to know when the remote IStream is being destroyed - // Binder does not support testing if an object is alive, thus - // wait for 100ms to let the binder destruction propagates and - // the remote device has the time to be destroyed. - // flushCommand makes sure all local command are sent, thus should reduce - // the latency between local and remote destruction. - IPCThreadState::self()->flushCommands(); - usleep(100*1000); + return stream->close(); } private: void TearDown() override { if (open) { - ASSERT_OK(closeStream()); + ASSERT_OK(stream->close()); } - AudioConfigPrimaryTest::TearDown(); } protected: @@ -806,9 +718,8 @@ class OpenStreamTest : public AudioConfigPrimaryTest, ////////////////////////////// openOutputStream ////////////////////////////// class OutputStreamTest : public OpenStreamTest<IStreamOut> { - void SetUp() override { + virtual void SetUp() override { ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base - if (!device && !HasFailure()) return; // do not attempt to use 'device' address.device = AudioDevice::OUT_DEFAULT; const AudioConfig& config = GetParam(); // TODO: test all flag combination @@ -848,9 +759,8 @@ INSTANTIATE_TEST_CASE_P( ////////////////////////////// openInputStream ////////////////////////////// class InputStreamTest : public OpenStreamTest<IStreamIn> { - void SetUp() override { + virtual void SetUp() override { ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base - if (!device && !HasFailure()) return; // do not attempt to use 'device' address.device = AudioDevice::IN_DEFAULT; const AudioConfig& config = GetParam(); // TODO: test all supported flags and source @@ -901,23 +811,15 @@ static R extract(Return<R> ret) { return ret; } -#define SKIP_IF_NO_STREAM \ - if (!stream) { \ - doc::partialTest("No primary device on this factory"); \ - return; \ - } - /* Could not find a way to write a test for two parametrized class fixure * thus use this macro do duplicate tests for Input and Output stream */ #define TEST_IO_STREAM(test_name, documentation, code) \ TEST_P(InputStreamTest, test_name) { \ doc::test(documentation); \ - SKIP_IF_NO_STREAM; \ code; \ } \ TEST_P(OutputStreamTest, test_name) { \ doc::test(documentation); \ - SKIP_IF_NO_STREAM; \ code; \ } @@ -946,7 +848,6 @@ static void testCapabilityGetter(const string& name, IStream* stream, Return<Property> (IStream::*getter)(), Return<Result> (IStream::*setter)(Property), bool currentMustBeSupported = true) { - SKIP_IF_NO_STREAM; hidl_vec<Property> capabilities; auto ret = capablityGetter(stream, capabilities); if (ret == Result::NOT_SUPPORTED) { @@ -1016,7 +917,6 @@ TEST_IO_STREAM(SupportedFormat, "Check that the stream format is declared as sup &IStream::getFormat, &IStream::setFormat)) static void testGetDevices(IStream* stream, AudioDevice expectedDevice) { - SKIP_IF_NO_STREAM; hidl_vec<DeviceAddress> devices; Result res; ASSERT_OK(stream->getDevices(returnIn(res, devices))); @@ -1036,7 +936,6 @@ TEST_IO_STREAM(GetDevices, "Check that the stream device == the one it was opene : testGetDevices(stream.get(), address.device)) static void testSetDevices(IStream* stream, const DeviceAddress& address) { - SKIP_IF_NO_STREAM; DeviceAddress otherAddress = address; otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER : AudioDevice::IN_BUILTIN_MIC; @@ -1050,7 +949,6 @@ TEST_IO_STREAM(SetDevices, "Check that the stream can be rerouted to SPEAKER or : testSetDevices(stream.get(), address)) static void testGetAudioProperties(IStream* stream, AudioConfig expectedConfig) { - SKIP_IF_NO_STREAM; uint32_t sampleRateHz; hidl_bitfield<AudioChannelMask> mask; AudioFormat format; @@ -1072,7 +970,6 @@ TEST_IO_STREAM(SetHwAvSync, "Try to set hardware sync to an invalid value", ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, stream->setHwAvSync(666))) static void checkGetHwAVSync(IDevice* device) { - SKIP_IF_NO_DEVICE; Result res; AudioHwSync sync; ASSERT_OK(device->getHwAvSync(returnIn(res, sync))); @@ -1085,7 +982,6 @@ TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(d static void checkGetNoParameter(IStream* stream, hidl_vec<hidl_string> keys, initializer_list<Result> expectedResults) { - SKIP_IF_NO_STREAM; hidl_vec<ParameterValue> context; hidl_vec<ParameterValue> parameters; Result res; @@ -1155,15 +1051,10 @@ TEST_IO_STREAM(getMmapPositionNoMmap, "Get a stream Mmap position before mapping ASSERT_RESULT(invalidStateOrNotSupported, stream->stop())) TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream())) -TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", - auto streamCopy = stream; - ASSERT_OK(closeStream()); - ASSERT_RESULT(Result::INVALID_STATE, streamCopy->close()); - streamCopy.clear(); - waitForStreamDestruction()) +TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", ASSERT_OK(closeStream()); + ASSERT_RESULT(Result::INVALID_STATE, closeStream())) static void testCreateTooBigMmapBuffer(IStream* stream) { - SKIP_IF_NO_STREAM; MmapBufferInfo info; Result res; // Assume that int max is a value too big to be allocated @@ -1178,7 +1069,6 @@ TEST_IO_STREAM(CreateTooBigMmapBuffer, "Create mmap buffer too big should fail", testCreateTooBigMmapBuffer(stream.get())) static void testGetMmapPositionOfNonMmapedStream(IStream* stream) { - SKIP_IF_NO_STREAM; Result res; MmapPosition position; ASSERT_OK(stream->getMmapPosition(returnIn(res, position))); @@ -1195,7 +1085,6 @@ TEST_IO_STREAM(GetMmapPositionOfNonMmapedStream, TEST_P(InputStreamTest, GetAudioSource) { doc::test("Retrieving the audio source of an input stream should always succeed"); - SKIP_IF_NO_STREAM; AudioSource source; ASSERT_OK(stream->getAudioSource(returnIn(res, source))); if (res == Result::NOT_SUPPORTED) { @@ -1230,14 +1119,12 @@ static void testOptionalUnitaryGain(std::function<Return<Result>(float)> setGain TEST_P(InputStreamTest, SetGain) { doc::test("The gain of an input stream should only be set between [0,1]"); - SKIP_IF_NO_STREAM; testOptionalUnitaryGain([this](float volume) { return stream->setGain(volume); }, "InputStream::setGain"); } static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_t framesCount) { Result res; - SKIP_IF_NO_STREAM; // Ignore output parameters as the call should fail ASSERT_OK(stream->prepareForReading(frameSize, framesCount, [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); @@ -1246,13 +1133,11 @@ static void testPrepareForReading(IStreamIn* stream, uint32_t frameSize, uint32_ TEST_P(InputStreamTest, PrepareForReadingWithZeroBuffer) { doc::test("Preparing a stream for reading with a 0 sized buffer should fail"); - SKIP_IF_NO_STREAM; testPrepareForReading(stream.get(), 0, 0); } TEST_P(InputStreamTest, PrepareForReadingWithHugeBuffer) { doc::test("Preparing a stream for reading with a 2^32 sized buffer should fail"); - SKIP_IF_NO_STREAM; testPrepareForReading(stream.get(), 1, std::numeric_limits<uint32_t>::max()); } @@ -1260,14 +1145,12 @@ TEST_P(InputStreamTest, PrepareForReadingCheckOverflow) { doc::test( "Preparing a stream for reading with a overflowing sized buffer should " "fail"); - SKIP_IF_NO_STREAM; auto uintMax = std::numeric_limits<uint32_t>::max(); testPrepareForReading(stream.get(), uintMax, uintMax); } TEST_P(InputStreamTest, GetInputFramesLost) { doc::test("The number of frames lost on a never started stream should be 0"); - SKIP_IF_NO_STREAM; auto ret = stream->getInputFramesLost(); ASSERT_IS_OK(ret); uint32_t framesLost{ret}; @@ -1278,7 +1161,6 @@ TEST_P(InputStreamTest, getCapturePosition) { doc::test( "The capture position of a non prepared stream should not be " "retrievable or 0"); - SKIP_IF_NO_STREAM; uint64_t frames; uint64_t time; ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time))); @@ -1291,7 +1173,6 @@ TEST_P(InputStreamTest, getCapturePosition) { TEST_P(InputStreamTest, updateSinkMetadata) { doc::test("The HAL should not crash on metadata change"); - SKIP_IF_NO_STREAM; hidl_enum_iterator<AudioSource> range; // Test all possible track configuration @@ -1318,7 +1199,6 @@ TEST_P(InputStreamTest, updateSinkMetadata) { TEST_P(OutputStreamTest, getLatency) { doc::test("Make sure latency is over 0"); - SKIP_IF_NO_STREAM; auto result = stream->getLatency(); ASSERT_IS_OK(result); ASSERT_GT(result, 0U); @@ -1326,14 +1206,12 @@ TEST_P(OutputStreamTest, getLatency) { TEST_P(OutputStreamTest, setVolume) { doc::test("Try to set the output volume"); - SKIP_IF_NO_STREAM; testOptionalUnitaryGain([this](float volume) { return stream->setVolume(volume, volume); }, "setVolume"); } static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32_t framesCount) { Result res; - SKIP_IF_NO_STREAM; // Ignore output parameters as the call should fail ASSERT_OK(stream->prepareForWriting(frameSize, framesCount, [&res](auto r, auto&, auto&, auto&, auto&) { res = r; })); @@ -1342,13 +1220,11 @@ static void testPrepareForWriting(IStreamOut* stream, uint32_t frameSize, uint32 TEST_P(OutputStreamTest, PrepareForWriteWithZeroBuffer) { doc::test("Preparing a stream for writing with a 0 sized buffer should fail"); - SKIP_IF_NO_STREAM; testPrepareForWriting(stream.get(), 0, 0); } TEST_P(OutputStreamTest, PrepareForWriteWithHugeBuffer) { doc::test("Preparing a stream for writing with a 2^32 sized buffer should fail"); - SKIP_IF_NO_STREAM; testPrepareForWriting(stream.get(), 1, std::numeric_limits<uint32_t>::max()); } @@ -1356,7 +1232,6 @@ TEST_P(OutputStreamTest, PrepareForWritingCheckOverflow) { doc::test( "Preparing a stream for writing with a overflowing sized buffer should " "fail"); - SKIP_IF_NO_STREAM; auto uintMax = std::numeric_limits<uint32_t>::max(); testPrepareForWriting(stream.get(), uintMax, uintMax); } @@ -1377,7 +1252,6 @@ struct Capability { TEST_P(OutputStreamTest, SupportsPauseAndResumeAndDrain) { doc::test("Implementation must expose pause, resume and drain capabilities"); - SKIP_IF_NO_STREAM; Capability(stream.get()); } @@ -1396,7 +1270,6 @@ static void checkInvalidStateOr0(Result res, Value value) { TEST_P(OutputStreamTest, GetRenderPosition) { doc::test("A new stream render position should be 0 or INVALID_STATE"); - SKIP_IF_NO_STREAM; uint32_t dspFrames; ASSERT_OK(stream->getRenderPosition(returnIn(res, dspFrames))); if (res == Result::NOT_SUPPORTED) { @@ -1408,7 +1281,6 @@ TEST_P(OutputStreamTest, GetRenderPosition) { TEST_P(OutputStreamTest, GetNextWriteTimestamp) { doc::test("A new stream next write timestamp should be 0 or INVALID_STATE"); - SKIP_IF_NO_STREAM; uint64_t timestampUs; ASSERT_OK(stream->getNextWriteTimestamp(returnIn(res, timestampUs))); if (res == Result::NOT_SUPPORTED) { @@ -1426,7 +1298,6 @@ class MockOutCallbacks : public IStreamOutCallback { }; static bool isAsyncModeSupported(IStreamOut* stream) { - if (!stream) return false; auto res = stream->setCallback(new MockOutCallbacks); stream->clearCallback(); // try to restore the no callback state, ignore // any error @@ -1463,7 +1334,6 @@ TEST_P(OutputStreamTest, Resume) { doc::test( "If supported, a stream should fail to resume if not previously " "paused"); - SKIP_IF_NO_STREAM; if (!Capability(stream.get()).resume) { doc::partialTest("The output stream does not support resume"); return; @@ -1475,7 +1345,6 @@ TEST_P(OutputStreamTest, Pause) { doc::test( "If supported, a stream should fail to pause if not previously " "started"); - SKIP_IF_NO_STREAM; if (!Capability(stream.get()).pause) { doc::partialTest("The output stream does not support pause"); return; @@ -1493,19 +1362,16 @@ static void testDrain(IStreamOut* stream, AudioDrain type) { TEST_P(OutputStreamTest, DrainAll) { doc::test("If supported, a stream should always succeed to drain"); - SKIP_IF_NO_STREAM; testDrain(stream.get(), AudioDrain::ALL); } TEST_P(OutputStreamTest, DrainEarlyNotify) { doc::test("If supported, a stream should always succeed to drain"); - SKIP_IF_NO_STREAM; testDrain(stream.get(), AudioDrain::EARLY_NOTIFY); } TEST_P(OutputStreamTest, FlushStop) { doc::test("If supported, a stream should always succeed to flush"); - SKIP_IF_NO_STREAM; auto ret = stream->flush(); ASSERT_IS_OK(ret); if (ret == Result::NOT_SUPPORTED) { @@ -1519,7 +1385,6 @@ TEST_P(OutputStreamTest, GetPresentationPositionStop) { doc::test( "If supported, a stream should always succeed to retrieve the " "presentation position"); - SKIP_IF_NO_STREAM; uint64_t frames; TimeSpec mesureTS; ASSERT_OK(stream->getPresentationPosition(returnIn(res, frames, mesureTS))); @@ -1547,13 +1412,11 @@ TEST_P(OutputStreamTest, GetPresentationPositionStop) { TEST_P(OutputStreamTest, SelectPresentation) { doc::test("Verify that presentation selection does not crash"); - SKIP_IF_NO_STREAM; ASSERT_RESULT(okOrNotSupported, stream->selectPresentation(0, 0)); } TEST_P(OutputStreamTest, updateSourceMetadata) { doc::test("The HAL should not crash on metadata change"); - SKIP_IF_NO_STREAM; hidl_enum_iterator<AudioUsage> usageRange; hidl_enum_iterator<AudioContentType> contentRange; @@ -1589,13 +1452,11 @@ TEST_P(OutputStreamTest, updateSourceMetadata) { TEST_F(AudioPrimaryHidlTest, setVoiceVolume) { doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]"); - SKIP_IF_NO_DEVICE; testUnitaryGain([](float volume) { return device->setVoiceVolume(volume); }); } TEST_F(AudioPrimaryHidlTest, setMode) { doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise"); - SKIP_IF_NO_DEVICE; // Test Invalid values for (int mode : {-2, -1, int(AudioMode::IN_COMMUNICATION) + 1}) { ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(AudioMode(mode))) @@ -1612,7 +1473,6 @@ TEST_F(AudioPrimaryHidlTest, setBtHfpSampleRate) { doc::test( "Make sure setBtHfpSampleRate either succeeds or " "indicates that it is not supported at all, or that the provided value is invalid"); - SKIP_IF_NO_DEVICE; for (auto samplingRate : {8000, 16000, 22050, 24000}) { ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, device->setBtHfpSampleRate(samplingRate)); } @@ -1622,7 +1482,6 @@ TEST_F(AudioPrimaryHidlTest, setBtHfpVolume) { doc::test( "Make sure setBtHfpVolume is either not supported or " "only succeed if volume is in [0,1]"); - SKIP_IF_NO_DEVICE; auto ret = device->setBtHfpVolume(0.0); ASSERT_TRUE(ret.isOk()); if (ret == Result::NOT_SUPPORTED) { @@ -1636,13 +1495,11 @@ TEST_F(AudioPrimaryHidlTest, setBtScoHeadsetDebugName) { doc::test( "Make sure setBtScoHeadsetDebugName either succeeds or " "indicates that it is not supported"); - SKIP_IF_NO_DEVICE; ASSERT_RESULT(okOrNotSupported, device->setBtScoHeadsetDebugName("test")); } TEST_F(AudioPrimaryHidlTest, updateRotation) { doc::test("Check that the hal can receive the current rotation"); - SKIP_IF_NO_DEVICE; for (Rotation rotation : {Rotation::DEG_0, Rotation::DEG_90, Rotation::DEG_180, Rotation::DEG_270, Rotation::DEG_0}) { ASSERT_RESULT(okOrNotSupported, device->updateRotation(rotation)); diff --git a/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp b/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp index 7d929ce56..a64513fc8 100644 --- a/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp +++ b/audio/core/4.0/vts/functional/ValidateAudioConfiguration.cpp @@ -18,14 +18,13 @@ #include <string> #include "utility/ValidateXml.h" -#include "AudioPolicyConfiguration.h" TEST(CheckConfig, audioPolicyConfigurationValidation) { RecordProperty("description", "Verify that the audio policy configuration file " "is valid according to the schema"); - EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS( - kAudioPolicyConfigurationXml, getApmConfigLocations(), - kAudioPolicyConfigurationXsd); + std::vector<const char*> locations = {"/odm/etc", "/vendor/etc", "/system/etc"}; + EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("audio_policy_configuration.xml", locations, + "/data/local/tmp/audio_policy_configuration_V4_0.xsd"); } diff --git a/camera/common/1.0/default/Exif.cpp b/camera/common/1.0/default/Exif.cpp index 6054999a0..b04c8084f 100644 --- a/camera/common/1.0/default/Exif.cpp +++ b/camera/common/1.0/default/Exif.cpp @@ -632,13 +632,13 @@ bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) { } bool ExifUtilsImpl::setImageHeight(uint32_t length) { - SET_LONG(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length); + SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length); SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length); return true; } bool ExifUtilsImpl::setImageWidth(uint32_t width) { - SET_LONG(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width); + SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width); SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width); return true; } diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp index 69f853562..fd785df1a 100644 --- a/camera/device/3.2/default/CameraDeviceSession.cpp +++ b/camera/device/3.2/default/CameraDeviceSession.cpp @@ -53,6 +53,7 @@ CameraDeviceSession::CameraDeviceSession( camera3_callback_ops({&sProcessCaptureResult, &sNotify}), mDevice(device), mDeviceVersion(device->common.version), + mFreeBufEarly(shouldFreeBufEarly()), mIsAELockAvailable(false), mDerivePostRawSensKey(false), mNumPartialResults(1), @@ -129,6 +130,10 @@ bool CameraDeviceSession::initialize() { return false; } +bool CameraDeviceSession::shouldFreeBufEarly() { + return property_get_bool("ro.vendor.camera.free_buf_early", 0) == 1; +} + CameraDeviceSession::~CameraDeviceSession() { if (!isClosed()) { ALOGE("CameraDeviceSession deleted before close!"); @@ -887,6 +892,24 @@ bool CameraDeviceSession::preProcessConfigurationLocked( (*streams)[i] = &mStreamMap[id]; } + if (mFreeBufEarly) { + // Remove buffers of deleted streams + for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) { + int id = it->first; + bool found = false; + for (const auto& stream : requestedConfiguration.streams) { + if (id == stream.id) { + found = true; + break; + } + } + if (!found) { + // Unmap all buffers of deleted stream + cleanupBuffersLocked(id); + } + } + } + return true; } @@ -908,7 +931,9 @@ void CameraDeviceSession::postProcessConfigurationLocked( // Unmap all buffers of deleted stream // in case the configuration call succeeds and HAL // is able to release the corresponding resources too. - cleanupBuffersLocked(id); + if (!mFreeBufEarly) { + cleanupBuffersLocked(id); + } it = mStreamMap.erase(it); } else { ++it; @@ -927,6 +952,27 @@ void CameraDeviceSession::postProcessConfigurationLocked( mResultBatcher.setBatchedStreams(mVideoStreamIds); } + +void CameraDeviceSession::postProcessConfigurationFailureLocked( + const StreamConfiguration& requestedConfiguration) { + if (mFreeBufEarly) { + // Re-build the buf cache entry for deleted streams + for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) { + int id = it->first; + bool found = false; + for (const auto& stream : requestedConfiguration.streams) { + if (id == stream.id) { + found = true; + break; + } + } + if (!found) { + mCirculatingBuffers.emplace(id, CirculatingBuffers{}); + } + } + } +} + Return<void> CameraDeviceSession::configureStreams( const StreamConfiguration& requestedConfiguration, ICameraDeviceSession::configureStreams_cb _hidl_cb) { @@ -979,6 +1025,8 @@ Return<void> CameraDeviceSession::configureStreams( // the corresponding resources of the deleted streams. if (ret == OK) { postProcessConfigurationLocked(requestedConfiguration); + } else { + postProcessConfigurationFailureLocked(requestedConfiguration); } if (ret == -EINVAL) { diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h index af90e5a00..bcee259fb 100644 --- a/camera/device/3.2/default/CameraDeviceSession.h +++ b/camera/device/3.2/default/CameraDeviceSession.h @@ -120,6 +120,8 @@ protected: hidl_vec<camera3_stream_t*> *streams /*out*/); void postProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration); + void postProcessConfigurationFailureLocked(const StreamConfiguration& requestedConfiguration); + protected: // protecting mClosed/mDisconnected/mInitFail @@ -142,6 +144,7 @@ protected: camera3_device_t* mDevice; const uint32_t mDeviceVersion; + const bool mFreeBufEarly; bool mIsAELockAvailable; bool mDerivePostRawSensKey; uint32_t mNumPartialResults; @@ -293,6 +296,8 @@ protected: bool initialize(); + static bool shouldFreeBufEarly(); + Status initStatus() const; // Validate and import request's input buffer and acquire fence diff --git a/camera/device/3.3/default/CameraDeviceSession.cpp b/camera/device/3.3/default/CameraDeviceSession.cpp index d36e9ed4a..60174fb92 100644 --- a/camera/device/3.3/default/CameraDeviceSession.cpp +++ b/camera/device/3.3/default/CameraDeviceSession.cpp @@ -92,6 +92,8 @@ Return<void> CameraDeviceSession::configureStreams_3_3( // the corresponding resources of the deleted streams. if (ret == OK) { postProcessConfigurationLocked(requestedConfiguration); + } else { + postProcessConfigurationFailureLocked(requestedConfiguration); } if (ret == -EINVAL) { diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp index 6a18161f2..f2e031c67 100644 --- a/camera/device/3.4/default/CameraDeviceSession.cpp +++ b/camera/device/3.4/default/CameraDeviceSession.cpp @@ -154,6 +154,8 @@ Return<void> CameraDeviceSession::configureStreams_3_4( // the corresponding resources of the deleted streams. if (ret == OK) { postProcessConfigurationLocked_3_4(requestedConfiguration); + } else { + postProcessConfigurationFailureLocked_3_4(requestedConfiguration); } if (ret == -EINVAL) { @@ -215,6 +217,23 @@ bool CameraDeviceSession::preProcessConfigurationLocked_3_4( (*streams)[i] = &mStreamMap[id]; } + if (mFreeBufEarly) { + // Remove buffers of deleted streams + for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) { + int id = it->first; + bool found = false; + for (const auto& stream : requestedConfiguration.streams) { + if (id == stream.v3_2.id) { + found = true; + break; + } + } + if (!found) { + // Unmap all buffers of deleted stream + cleanupBuffersLocked(id); + } + } + } return true; } @@ -236,7 +255,9 @@ void CameraDeviceSession::postProcessConfigurationLocked_3_4( // Unmap all buffers of deleted stream // in case the configuration call succeeds and HAL // is able to release the corresponding resources too. - cleanupBuffersLocked(id); + if (!mFreeBufEarly) { + cleanupBuffersLocked(id); + } it = mStreamMap.erase(it); } else { ++it; @@ -255,6 +276,26 @@ void CameraDeviceSession::postProcessConfigurationLocked_3_4( mResultBatcher_3_4.setBatchedStreams(mVideoStreamIds); } +void CameraDeviceSession::postProcessConfigurationFailureLocked_3_4( + const StreamConfiguration& requestedConfiguration) { + if (mFreeBufEarly) { + // Re-build the buf cache entry for deleted streams + for(auto it = mStreamMap.begin(); it != mStreamMap.end(); it++) { + int id = it->first; + bool found = false; + for (const auto& stream : requestedConfiguration.streams) { + if (id == stream.v3_2.id) { + found = true; + break; + } + } + if (!found) { + mCirculatingBuffers.emplace(id, CirculatingBuffers{}); + } + } + } +} + Return<void> CameraDeviceSession::processCaptureRequest_3_4( const hidl_vec<V3_4::CaptureRequest>& requests, const hidl_vec<V3_2::BufferCache>& cachesToRemove, diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h index 5d6a112e3..fdc8a5afd 100644 --- a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h +++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h @@ -84,6 +84,8 @@ protected: camera3_stream_configuration_t *stream_list /*out*/, hidl_vec<camera3_stream_t*> *streams /*out*/); void postProcessConfigurationLocked_3_4(const StreamConfiguration& requestedConfiguration); + void postProcessConfigurationFailureLocked_3_4( + const StreamConfiguration& requestedConfiguration); Return<void> processCaptureRequest_3_4( const hidl_vec<V3_4::CaptureRequest>& requests, diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index f9c868db8..19666f53a 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -102,11 +102,20 @@ namespace implementation { std::unique_ptr<android::CryptoPlugin::SubSample[]> legacySubSamples = std::make_unique<android::CryptoPlugin::SubSample[]>(subSamples.size()); + size_t destSize = 0; for (size_t i = 0; i < subSamples.size(); i++) { - legacySubSamples[i].mNumBytesOfClearData - = subSamples[i].numBytesOfClearData; - legacySubSamples[i].mNumBytesOfEncryptedData - = subSamples[i].numBytesOfEncryptedData; + uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData; + legacySubSamples[i].mNumBytesOfClearData = numBytesOfClearData; + uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData; + legacySubSamples[i].mNumBytesOfEncryptedData = numBytesOfEncryptedData; + if (__builtin_add_overflow(destSize, numBytesOfClearData, &destSize)) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow"); + return Void(); + } + if (__builtin_add_overflow(destSize, numBytesOfEncryptedData, &destSize)) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow"); + return Void(); + } } AString detailMessage; @@ -138,11 +147,25 @@ namespace implementation { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } + + if (destSize > destBuffer.size) { + _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large"); + return Void(); + } + + base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer())); destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset); } else if (destination.type == BufferType::NATIVE_HANDLE) { + if (!secure) { + _hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure"); + return Void(); + } native_handle_t *handle = const_cast<native_handle_t *>( destination.secureMemory.getNativeHandle()); destPtr = static_cast<void *>(handle); + } else { + _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type"); + return Void(); } ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(), legacyMode, legacyPattern, srcPtr, legacySubSamples.get(), diff --git a/drm/1.0/default/DrmFactory.cpp b/drm/1.0/default/DrmFactory.cpp index 7e5d998e4..05951d7c0 100644 --- a/drm/1.0/default/DrmFactory.cpp +++ b/drm/1.0/default/DrmFactory.cpp @@ -1,6 +1,6 @@ /* * 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 diff --git a/drm/1.0/default/LegacyPluginPath.cpp b/drm/1.0/default/LegacyPluginPath.cpp index 369059d2c..d0a8f90a7 100644 --- a/drm/1.0/default/LegacyPluginPath.cpp +++ b/drm/1.0/default/LegacyPluginPath.cpp @@ -16,6 +16,8 @@ #include "LegacyPluginPath.h" +#include <unistd.h> + #include <cutils/properties.h> namespace android { @@ -24,12 +26,16 @@ namespace drm { namespace V1_0 { namespace implementation { +// 64-bit DRM depends on OEM libraries that aren't +// provided for all devices. If the drm hal service +// is running as 64-bit use the 64-bit libs, otherwise +// use the 32-bit libs. const char* getDrmPluginPath() { - if (property_get_bool("drm.64bit.enabled", false)) { - return "/vendor/lib64/mediadrm"; - } else { - return "/vendor/lib/mediadrm"; - } +#if defined(__LP64__) + return "/vendor/lib64/mediadrm"; +#else + return "/vendor/lib/mediadrm"; +#endif } } // namespace implementation diff --git a/drm/1.0/default/include/PluginLoader.h b/drm/1.0/default/include/PluginLoader.h index f387b3cbc..0c45fb3ef 100644 --- a/drm/1.0/default/include/PluginLoader.h +++ b/drm/1.0/default/include/PluginLoader.h @@ -85,7 +85,10 @@ class PluginLoader { libraries.push(library); T* result = createFactoryFunc(); return result; - } + } else { + ALOGE("Failed to lookup symbol %s in library %s: %s", + entry, path, library->lastError()); + } } return NULL; } diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp index 7c9e6518b..0f5057756 100644 --- a/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp +++ b/graphics/composer/2.1/utils/hwc2onfbadapter/HWC2OnFbAdapter.cpp @@ -32,6 +32,8 @@ #include <log/log.h> #include <sync/sync.h> +using namespace HWC2; + namespace android { namespace { @@ -629,9 +631,10 @@ hwc2_function_pointer_t getFunctionHook(hwc2_device_t* /*device*/, int32_t descr } } -void getCapabilitiesHook(hwc2_device_t* /*device*/, uint32_t* outCount, - int32_t* /*outCapabilities*/) { - *outCount = 0; +void getCapabilitiesHook(hwc2_device_t* device, uint32_t* outCount, + int32_t* outCapabilities) { + auto& adapter = HWC2OnFbAdapter::cast(device); + adapter.getCapabilities(outCount, outCapabilities); } int closeHook(hw_device_t* device) { @@ -656,6 +659,10 @@ HWC2OnFbAdapter::HWC2OnFbAdapter(framebuffer_device_t* fbDevice) mFbInfo.xdpi_scaled = int(mFbDevice->xdpi * 1000.0f); mFbInfo.ydpi_scaled = int(mFbDevice->ydpi * 1000.0f); + // Present fences aren't supported, always indicate PresentFenceIsNotReliable + // for FB devices + mCapabilities.insert(Capability::PresentFenceIsNotReliable); + mVsyncThread.start(0, mFbInfo.vsync_period_ns); } @@ -791,6 +798,23 @@ void HWC2OnFbAdapter::enableVsync(bool enable) { mVsyncThread.enableCallback(enable); } +void HWC2OnFbAdapter::getCapabilities(uint32_t* outCount, + int32_t* outCapabilities) { + if (outCapabilities == nullptr) { + *outCount = mCapabilities.size(); + return; + } + + auto capabilityIter = mCapabilities.cbegin(); + for (size_t written = 0; written < *outCount; ++written) { + if (capabilityIter == mCapabilities.cend()) { + return; + } + outCapabilities[written] = static_cast<int32_t>(*capabilityIter); + ++capabilityIter; + } +} + int64_t HWC2OnFbAdapter::VsyncThread::now() { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h index d6272fdb1..f1f11ef2b 100644 --- a/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h +++ b/graphics/composer/2.1/utils/hwc2onfbadapter/include/hwc2onfbadapter/HWC2OnFbAdapter.h @@ -23,7 +23,11 @@ #include <thread> #include <unordered_set> +#define HWC2_INCLUDE_STRINGIFICATION +#define HWC2_USE_CPP11 #include <hardware/hwcomposer2.h> +#undef HWC2_INCLUDE_STRINGIFICATION +#undef HWC2_USE_CPP11 struct framebuffer_device_t; @@ -75,6 +79,7 @@ public: void setVsyncCallback(HWC2_PFN_VSYNC callback, hwc2_callback_data_t data); void enableVsync(bool enable); + void getCapabilities(uint32_t* outCount, int32_t* outCapabilities); private: framebuffer_device_t* mFbDevice{nullptr}; @@ -90,6 +95,8 @@ private: buffer_handle_t mBuffer{nullptr}; + std::unordered_set<HWC2::Capability> mCapabilities; + class VsyncThread { public: static int64_t now(); diff --git a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc index a41d902cc..efe6dadbc 100644 --- a/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc +++ b/graphics/composer/2.2/default/android.hardware.graphics.composer@2.2-service.rc @@ -4,3 +4,4 @@ service vendor.hwcomposer-2-2 /vendor/bin/hw/android.hardware.graphics.composer@ group graphics drmrpc capabilities SYS_NICE onrestart restart surfaceflinger + writepid /dev/cpuset/system-background/tasks diff --git a/health/2.0/README b/health/2.0/README index 11e6a7aaf..dfd965aa5 100644 --- a/health/2.0/README +++ b/health/2.0/README @@ -6,12 +6,7 @@ Upgrading from health@1.0 HAL 1. If the device does not have a vendor-specific libhealthd AND does not implement storage-related APIs, just do the following: - 1.1 (recommended) To remove healthd from the build, - PRODUCT_PACKAGES += android.hardware.health@2.0-service.override - DEVICE_FRAMEWORK_MANIFEST_FILE += \ - system/libhidl/vintfdata/manifest_healthd_exclude.xml - 1.2 To keep healthd in the build, - PRODUCT_PACKAGES += android.hardware.health@2.0-service + PRODUCT_PACKAGES += android.hardware.health@2.0-service Otherwise, continue to Step 2. diff --git a/keymaster/4.0/support/Keymaster.cpp b/keymaster/4.0/support/Keymaster.cpp index 444298b5b..9325cc069 100644 --- a/keymaster/4.0/support/Keymaster.cpp +++ b/keymaster/4.0/support/Keymaster.cpp @@ -164,10 +164,10 @@ static void computeHmac(const Keymaster::KeymasterSet& keymasters, sharingCheck = curSharingCheck; firstKeymaster = false; } - CHECK(curSharingCheck == sharingCheck) - << "HMAC computation failed for " << *keymaster // - << " Expected: " << sharingCheck // - << " got: " << curSharingCheck; + if (curSharingCheck != sharingCheck) + LOG(WARNING) << "HMAC computation failed for " << *keymaster // + << " Expected: " << sharingCheck // + << " got: " << curSharingCheck; }); CHECK(rc.isOk()) << "Failed to communicate with " << *keymaster << " error: " << rc.description(); diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp index 784ae30c0..a2b43f06d 100644 --- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp +++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp @@ -3899,6 +3899,33 @@ TEST_F(AttestationTest, EcAttestation) { } /* + * AttestationTest.EcAttestationByKeySize + * + * Verifies that attesting to EC keys works and generates the expected output. + */ +TEST_F(AttestationTest, EcAttestationByKeySize) { + ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder() + .Authorization(TAG_NO_AUTH_REQUIRED) + .EcdsaSigningKey(256) + .Digest(Digest::SHA_2_256) + .Authorization(TAG_INCLUDE_UNIQUE_ID))); + + hidl_vec<hidl_vec<uint8_t>> cert_chain; + ASSERT_EQ(ErrorCode::OK, + AttestKey(AuthorizationSetBuilder() + .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge")) + .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf("foo")), + &cert_chain)); + EXPECT_GE(cert_chain.size(), 2U); + EXPECT_TRUE(verify_chain(cert_chain)); + + EXPECT_TRUE(verify_attestation_record("challenge", "foo", // + key_characteristics_.softwareEnforced, // + key_characteristics_.hardwareEnforced, // + SecLevel(), cert_chain[0])); +} + +/* * AttestationTest.EcAttestationRequiresAttestationAppId * * Verifies that attesting to EC keys requires app ID diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h index c276ad382..363547350 100644 --- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h +++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h @@ -40,7 +40,7 @@ /* As component is switching states (loaded<->idle<->execute), dequeueMessage() * expects the events to be received within this duration */ -#define DEFAULT_TIMEOUT 150000 +#define DEFAULT_TIMEOUT 100000 /* Time interval between successive Input/Output enqueues */ #define DEFAULT_TIMEOUT_Q 2000 /* While the component is amidst a process call, asynchronous commands like |