Merge "Fix use-after-free in AMediaExtractor_getSampleCryptoInfo" into tm-dev
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 74e3223..f7989bd 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -208,7 +208,11 @@
}
status_t DrmManager::loadPlugIns() {
+#if __LP64__
+ String8 pluginDirPath("/system/lib64/drm");
+#else
String8 pluginDirPath("/system/lib/drm");
+#endif
loadPlugIns(pluginDirPath);
return DRM_NO_ERROR;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
index 02ac943..b82d996 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
@@ -144,7 +144,6 @@
"libclearkeydevicefiles-protos",
"libjsmn",
"libprotobuf-cpp-lite",
- "libutils",
],
shared_libs: [
"android.hidl.allocator@1.0",
@@ -157,6 +156,7 @@
"libhidlbase",
"libhidlmemory",
"liblog",
+ "libutils",
],
fuzz_config: {
cc: [
diff --git a/drm/mediadrm/plugins/clearkey/service-lazy.mk b/drm/mediadrm/plugins/clearkey/service-lazy.mk
new file mode 100644
index 0000000..0d16f4c
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/service-lazy.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+PRODUCT_PACKAGES += android.hardware.drm-service-lazy.clearkey
diff --git a/drm/mediadrm/plugins/clearkey/service.mk b/drm/mediadrm/plugins/clearkey/service.mk
new file mode 100644
index 0000000..15988fb
--- /dev/null
+++ b/drm/mediadrm/plugins/clearkey/service.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+PRODUCT_PACKAGES += android.hardware.drm-service.clearkey
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
index f370f5e..3965bcc 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.h
@@ -49,7 +49,7 @@
#define INPUT_DUMP_EXT "m2v"
#define GENERATE_FILE_NAMES() { \
nsecs_t now = systemTime(); \
- sprintf(mInFile, "%s_%" PRId64 ".%s",
+ sprintf(mInFile, "%s_%" PRId64 ".%s", \
INPUT_DUMP_PATH, now, \
INPUT_DUMP_EXT); \
}
diff --git a/media/codec2/fuzzer/Android.bp b/media/codec2/fuzzer/Android.bp
index 3adc212..147a52e 100644
--- a/media/codec2/fuzzer/Android.bp
+++ b/media/codec2/fuzzer/Android.bp
@@ -38,6 +38,12 @@
"-Wall",
"-Werror",
],
+
+ fuzz_config: {
+ cc: [
+ "wonsik@google.com",
+ ],
+ },
}
cc_fuzz {
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index a73b493..c36ae94 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -67,6 +67,7 @@
"libstagefright_codecbase",
"libstagefright_foundation",
"libstagefright_omx",
+ "libstagefright_surface_utils",
"libstagefright_xmlparser",
"libui",
"libutils",
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index cb362c9..88fe1f3 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -871,6 +871,11 @@
}
config->mTunneled = true;
}
+
+ int32_t pushBlankBuffersOnStop = 0;
+ if (msg->findInt32(KEY_PUSH_BLANK_BUFFERS_ON_STOP, &pushBlankBuffersOnStop)) {
+ config->mPushBlankBuffersOnStop = pushBlankBuffersOnStop == 1;
+ }
}
}
setSurface(surface);
@@ -1841,7 +1846,13 @@
}
state->set(STOPPING);
}
-
+ {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ if (config->mPushBlankBuffersOnStop) {
+ mChannel->pushBlankBufferToOutputSurface();
+ }
+ }
mChannel->reset();
(new AMessage(kWhatStop, this))->post();
}
@@ -1929,6 +1940,13 @@
config->mInputSurfaceDataspace = HAL_DATASPACE_UNKNOWN;
}
}
+ {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ if (config->mPushBlankBuffersOnStop) {
+ mChannel->pushBlankBufferToOutputSurface();
+ }
+ }
mChannel->reset();
// thiz holds strong ref to this while the thread is running.
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 674714f..a086128 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -15,6 +15,7 @@
*/
//#define LOG_NDEBUG 0
+#include <utils/Errors.h>
#define LOG_TAG "CCodecBufferChannel"
#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <utils/Log.h>
@@ -48,6 +49,7 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/SkipCutBuffer.h>
+#include <media/stagefright/SurfaceUtils.h>
#include <media/MediaCodecBuffer.h>
#include <mediadrm/ICrypto.h>
#include <system/window.h>
@@ -2180,4 +2182,13 @@
}
}
+status_t CCodecBufferChannel::pushBlankBufferToOutputSurface() {
+ Mutexed<OutputSurface>::Locked output(mOutputSurface);
+ sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(output->surface.get());
+ if (nativeWindow == nullptr) {
+ return INVALID_OPERATION;
+ }
+ return pushBlankBuffersToNativeWindow(nativeWindow.get());
+}
+
} // namespace android
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 26eef30..b3a5f4b 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -181,6 +181,11 @@
void setMetaMode(MetaMode mode);
+ /**
+ * Push a blank buffer to the configured native output surface.
+ */
+ status_t pushBlankBufferToOutputSurface();
+
private:
class QueueGuard;
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index c15b5ca..132902b 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -324,7 +324,8 @@
: mInputFormat(new AMessage),
mOutputFormat(new AMessage),
mUsingSurface(false),
- mTunneled(false) { }
+ mTunneled(false),
+ mPushBlankBuffersOnStop(false) { }
void CCodecConfig::initializeStandardParams() {
typedef Domain D;
@@ -963,8 +964,6 @@
.limitTo(D::ENCODER & D::VIDEO & D::READ));
/* still to do
- constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
-
not yet used by MediaCodec, but defined as MediaFormat
KEY_AUDIO_SESSION_ID // we use "audio-hw-sync"
KEY_OUTPUT_REORDER_DEPTH
diff --git a/media/codec2/sfplugin/CCodecConfig.h b/media/codec2/sfplugin/CCodecConfig.h
index 88e6239..2e7b866 100644
--- a/media/codec2/sfplugin/CCodecConfig.h
+++ b/media/codec2/sfplugin/CCodecConfig.h
@@ -148,6 +148,8 @@
bool mTunneled;
sp<NativeHandle> mSidebandHandle;
+ bool mPushBlankBuffersOnStop;
+
CCodecConfig();
/// initializes the members required to manage the format: descriptors, reflector,
@@ -396,4 +398,3 @@
} // namespace android
#endif // C_CODEC_H_
-
diff --git a/media/codec2/vndk/platform/C2BqBuffer.cpp b/media/codec2/vndk/platform/C2BqBuffer.cpp
index 2cca3c8..63b0f39 100644
--- a/media/codec2/vndk/platform/C2BqBuffer.cpp
+++ b/media/codec2/vndk/platform/C2BqBuffer.cpp
@@ -576,14 +576,7 @@
}
~Impl() {
- bool noInit = false;
for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
- if (!noInit && mProducer) {
- Return<HStatus> transResult =
- mProducer->detachBuffer(static_cast<int32_t>(i));
- noInit = !transResult.isOk() ||
- static_cast<HStatus>(transResult) == HStatus::NO_INIT;
- }
mBuffers[i].clear();
}
}
@@ -692,15 +685,6 @@
{
sp<GraphicBuffer> buffers[NUM_BUFFER_SLOTS];
std::scoped_lock<std::mutex> lock(mMutex);
- bool noInit = false;
- for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
- if (!noInit && mProducer) {
- Return<HStatus> transResult =
- mProducer->detachBuffer(static_cast<int32_t>(i));
- noInit = !transResult.isOk() ||
- static_cast<HStatus>(transResult) == HStatus::NO_INIT;
- }
- }
int32_t oldGeneration = mGeneration;
if (producer) {
mProducer = producer;
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index e2eec7a..2a12191 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -36,11 +36,11 @@
"libaudiomanager",
"libaudiopolicy",
"libaudioclient_aidl_conversion",
+ "libutils",
],
static_libs: [
"android.media.audio.common.types-V1-cpp",
"liblog",
- "libutils",
"libcutils",
"libaaudio",
"libjsoncpp",
diff --git a/media/libaaudio/scripts/measure_device_power.py b/media/libaaudio/scripts/measure_device_power.py
index fd7f85f..1f90933 100755
--- a/media/libaaudio/scripts/measure_device_power.py
+++ b/media/libaaudio/scripts/measure_device_power.py
@@ -79,28 +79,42 @@
SORTED_ENERGY_LIST = sorted(ENERGY_DICTIONARY, key=ENERGY_DICTIONARY.get)
-# Sometimes "adb unroot" returns 1!
+# Sometimes adb returns 1 for no apparent reason.
# So try several times.
# @return 0 on success
-def adbUnroot():
+def adbTryMultiple(command):
returnCode = 1
count = 0
limit = 5
while count < limit and returnCode != 0:
- print(('Try to adb unroot {} of {}'.format(count, limit)))
+ print(('Try to adb {} {} of {}'.format(command, count, limit)))
subprocess.call(["adb", "wait-for-device"])
time.sleep(PRE_DELAY_SECONDS)
- returnCode = subprocess.call(["adb", "unroot"])
+ returnCode = subprocess.call(["adb", command])
print(('returnCode = {}'.format(returnCode)))
count += 1
return returnCode
+# Sometimes "adb root" returns 1!
+# So try several times.
+# @return 0 on success
+def adbRoot():
+ return adbTryMultiple("root");
+
+# Sometimes "adb unroot" returns 1!
+# So try several times.
+# @return 0 on success
+def adbUnroot():
+ return adbTryMultiple("unroot");
+
# @param commandString String containing shell command
# @return Both the stdout and stderr of the commands run
def runCommand(commandString):
print(commandString)
if commandString == "adb unroot":
result = adbUnroot()
+ elif commandString == "adb root":
+ result = adbRoot()
else:
commandArray = commandString.split(' ')
result = subprocess.run(commandArray, check=True, capture_output=True).stdout
@@ -111,6 +125,8 @@
def adbCommand(commandString):
if commandString == "unroot":
result = adbUnroot()
+ elif commandString == "root":
+ result = adbRoot()
else:
print(("adb " + commandString))
commandArray = ["adb"] + commandString.split(' ')
@@ -230,7 +246,7 @@
print((command + "\n"))
comment = command[1:].strip() # remove leading '#'
elif command.endswith('\\'):
- command = command[:-1].strip() # remove \\
+ command = command[:-1].strip() # remove trailing '\'
runCommand(command)
elif command:
report = averageEnergyForCommand(command, DEFAULT_NUM_ITERATIONS)
diff --git a/media/libaaudio/scripts/synthmark_tests.txt b/media/libaaudio/scripts/synthmark_tests.txt
index 24e719d..8b6d47e 100644
--- a/media/libaaudio/scripts/synthmark_tests.txt
+++ b/media/libaaudio/scripts/synthmark_tests.txt
@@ -1,31 +1,36 @@
# Measure energy consumption with synthmark.
-# ADPF <400 RR
-adb root \
-adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 400 \
-adb shell synthmark -tj -n1 -N50 -B2 -z1
-adb shell synthmark -tj -n1 -N75 -B2 -z1
-adb shell synthmark -tj -n1 -N100 -B2 -z1
-
-# ADPF <500 RR
-adb root \
-adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 500 \
-adb shell synthmark -tj -n1 -N50 -B2 -z1
-adb shell synthmark -tj -n1 -N75 -B2 -z1
-adb shell synthmark -tj -n1 -N100 -B2 -z1
-
-# ADPF <600 RR
-adb root \
-adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 600 \
-adb shell synthmark -tj -n1 -N50 -B2 -z1
-adb shell synthmark -tj -n1 -N75 -B2 -z1
-adb shell synthmark -tj -n1 -N100 -B2 -z1
-
# None
adb shell synthmark -tj -n1 -N50 -B2 -z0
adb shell synthmark -tj -n1 -N75 -B2 -z0
adb shell synthmark -tj -n1 -N100 -B2 -z0
+# ADPF PID
+adb shell synthmark -tj -n1 -N50 -B2 -z1
+adb shell synthmark -tj -n1 -N75 -B2 -z1
+adb shell synthmark -tj -n1 -N100 -B2 -z1
+
+# ADPF <400 RR
+# adb root \
+# adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 400 \
+# adb shell synthmark -tj -n1 -N50 -B2 -z1
+# adb shell synthmark -tj -n1 -N75 -B2 -z1
+# adb shell synthmark -tj -n1 -N100 -B2 -z1
+
+# ADPF <500 RR
+# adb root \
+# adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 500 \
+# adb shell synthmark -tj -n1 -N50 -B2 -z1
+# adb shell synthmark -tj -n1 -N75 -B2 -z1
+# adb shell synthmark -tj -n1 -N100 -B2 -z1
+
+# ADPF <600 RR
+# adb root \
+# adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 600 \
+# adb shell synthmark -tj -n1 -N50 -B2 -z1
+# adb shell synthmark -tj -n1 -N75 -B2 -z1
+# adb shell synthmark -tj -n1 -N100 -B2 -z1
+
# uclamp
# adb root \
# adb shell synthmark -tj -n1 -N75 -B2 -u1
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 450d390..7c7a969 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -202,10 +202,18 @@
break;
case AAUDIO_STREAM_STATE_STARTED:
{
- // Sleep until the readCounter catches up and we only have
- // the getBufferSize() frames of data sitting in the buffer.
- int64_t nextReadPosition = mAudioEndpoint->getDataWriteCounter() - getBufferSize();
- wakeTime = mClockModel.convertPositionToTime(nextReadPosition);
+ // Calculate when there will be room available to write to the buffer.
+ // If the appBufferSize is smaller than the endpointBufferSize then
+ // we will have room to write data beyond the appBufferSize.
+ // That is a technique used to reduce glitches without adding latency.
+ const int32_t appBufferSize = getBufferSize();
+ // The endpoint buffer size is set to the maximum that can be written.
+ // If we use it then we must carve out some room to write data when we wake up.
+ const int32_t endBufferSize = mAudioEndpoint->getBufferSizeInFrames()
+ - getFramesPerBurst();
+ const int32_t bestBufferSize = std::min(appBufferSize, endBufferSize);
+ int64_t targetReadPosition = mAudioEndpoint->getDataWriteCounter() - bestBufferSize;
+ wakeTime = mClockModel.convertPositionToTime(targetReadPosition);
}
break;
default:
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 4b42203..872faca 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -562,7 +562,9 @@
int32_t AAudioProperty_getMinimumSleepMicros() {
const int32_t minMicros = 1; // arbitrary
// Higher values can increase latency for moderate workloads.
- const int32_t defaultMicros = 1; // arbitrary
+ // Short values can cause the CPU to short cycle if there is a bug in
+ // calculating the wakeup times.
+ const int32_t defaultMicros = 100; // arbitrary
const int32_t maxMicros = 200; // arbitrary
int32_t prop = property_get_int32(AAUDIO_PROP_MINIMUM_SLEEP_USEC, defaultMicros);
if (prop < minMicros) {
diff --git a/media/libmediahelper/Android.bp b/media/libmediahelper/Android.bp
index b9d795d..165a8ad 100644
--- a/media/libmediahelper/Android.bp
+++ b/media/libmediahelper/Android.bp
@@ -44,7 +44,10 @@
"-Wextra",
"-Wall",
],
- shared_libs: ["libutils", "liblog"],
+ shared_libs: [
+ "libutils",
+ "liblog",
+ ],
header_libs: [
"libmedia_helper_headers",
"libaudio_system_headers",
@@ -52,7 +55,7 @@
export_header_lib_headers: [
"libmedia_helper_headers",
],
- clang: true,
+
host_supported: true,
target: {
darwin: {
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index 55b1ed7..b3f7f25 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -216,7 +216,8 @@
sp<AMessage> format = new AMessage;
status_t err = convertMetaDataToMessage(trackMeta, &format);
if (err != OK) {
- format = NULL;
+ ALOGE("getImageInternal: convertMetaDataToMessage() failed, unable to extract image");
+ return NULL;
}
uint32_t bitDepth = 8;
@@ -400,7 +401,8 @@
sp<AMessage> format = new AMessage;
status_t err = convertMetaDataToMessage(trackMeta, &format);
if (err != OK) {
- format = NULL;
+ ALOGE("getFrameInternal: convertMetaDataToMessage() failed, unable to extract frame");
+ return NULL;
}
Vector<AString> matchingCodecs;
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index e47e7ff..10baec4 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -253,6 +253,40 @@
],
},
}
+
+cc_library_shared {
+ name: "libstagefright_surface_utils",
+
+ srcs: [
+ "SurfaceUtils.cpp",
+ ],
+
+ shared_libs: [
+ "libgui",
+ "liblog",
+ "libui",
+ "libutils",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
+
cc_library {
name: "libstagefright",
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 2a75342..5a27362 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -186,9 +186,12 @@
// XXX suppress until we get our representation right
static bool kEmitHistogram = false;
+static int64_t getId(IResourceManagerClient const * client) {
+ return (int64_t) client;
+}
static int64_t getId(const std::shared_ptr<IResourceManagerClient> &client) {
- return (int64_t) client.get();
+ return getId(client.get());
}
static bool isResourceError(status_t err) {
@@ -205,12 +208,20 @@
////////////////////////////////////////////////////////////////////////////////
struct ResourceManagerClient : public BnResourceManagerClient {
- explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
+ explicit ResourceManagerClient(MediaCodec* codec, int32_t pid) :
+ mMediaCodec(codec), mPid(pid) {}
Status reclaimResource(bool* _aidl_return) override {
sp<MediaCodec> codec = mMediaCodec.promote();
if (codec == NULL) {
- // codec is already gone.
+ // Codec is already gone, so remove the resources as well
+ ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
+ std::shared_ptr<IResourceManagerService> service =
+ IResourceManagerService::fromBinder(binder);
+ if (service == nullptr) {
+ ALOGW("MediaCodec::ResourceManagerClient unable to find ResourceManagerService");
+ }
+ service->removeClient(mPid, getId(this));
*_aidl_return = true;
return Status::ok();
}
@@ -247,6 +258,7 @@
private:
wp<MediaCodec> mMediaCodec;
+ int32_t mPid;
DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
};
@@ -820,7 +832,7 @@
mGetCodecBase(getCodecBase),
mGetCodecInfo(getCodecInfo) {
mResourceManagerProxy = new ResourceManagerServiceProxy(pid, uid,
- ::ndk::SharedRefBase::make<ResourceManagerClient>(this));
+ ::ndk::SharedRefBase::make<ResourceManagerClient>(this, pid));
if (!mGetCodecBase) {
mGetCodecBase = [](const AString &name, const char *owner) {
return GetCodecBase(name, owner);
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 1b31392..ca17117 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -120,8 +120,6 @@
},
},
- clang: true,
-
sanitize: {
misc_undefined: [
"unsigned-integer-overflow",
@@ -172,7 +170,7 @@
shared_libs: [
"liblog",
- "libutils", // for sp<>
+ "libutils", // for sp<>
// actually invokes this, but called from folks who already load it
// "libmediandk",
],
@@ -200,8 +198,6 @@
"ColorUtils_fill.cpp",
],
- clang: true,
-
sanitize: {
misc_undefined: [
"unsigned-integer-overflow",
@@ -218,4 +214,3 @@
],
}
-
diff --git a/media/libstagefright/renderfright/Android.bp b/media/libstagefright/renderfright/Android.bp
index 9a7bad9..3c00a1c 100644
--- a/media/libstagefright/renderfright/Android.bp
+++ b/media/libstagefright/renderfright/Android.bp
@@ -87,7 +87,7 @@
enabled: true,
},
double_loadable: true,
- clang: true,
+
cflags: [
"-fvisibility=hidden",
"-Werror=format",
diff --git a/media/libstagefright/xmlparser/Android.bp b/media/libstagefright/xmlparser/Android.bp
index 055dd80..afc873c 100644
--- a/media/libstagefright/xmlparser/Android.bp
+++ b/media/libstagefright/xmlparser/Android.bp
@@ -41,8 +41,6 @@
"-Wall",
],
- clang: true,
-
sanitize: {
misc_undefined: [
"unsigned-integer-overflow",
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
index d1655ef..713b0ac 100644
--- a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -125,7 +125,7 @@
void SourceClientCollection::dump(String8 *dst) const
{
- dst->append("\n Audio sources (%zu):\n", size());
+ dst->appendFormat("\n Audio sources (%zu):\n", size());
for (size_t i = 0; i < size(); i++) {
const std::string prefix = base::StringPrintf(" %zu. ", i + 1);
dst->appendFormat("%s", prefix.c_str());
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index f08d4ad..49a0dde 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -287,9 +287,12 @@
sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
// close unused outputs after device disconnection or direct outputs that have
// been opened by checkOutputsForDevice() to query dynamic parameters
+ // "outputs" vector never contains duplicated outputs
if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)
|| (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
- (desc->mDirectOpenCount == 0))) {
+ (desc->mDirectOpenCount == 0))
+ || (((desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) &&
+ !isOutputOnlyAvailableRouteToSomeDevice(desc))) {
clearAudioSourcesForOutput(output);
closeOutput(output);
}
@@ -5361,6 +5364,29 @@
}
}
+
+bool AudioPolicyManager::isOutputOnlyAvailableRouteToSomeDevice(
+ const sp<SwAudioOutputDescriptor>& outputDesc) {
+ if (outputDesc->isDuplicated()) {
+ return false;
+ }
+ DeviceVector devices = outputDesc->supportedDevices();
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if (desc == outputDesc || desc->isDuplicated()) {
+ continue;
+ }
+ DeviceVector sharedDevices = desc->filterSupportedDevices(devices);
+ if (!sharedDevices.isEmpty()
+ && (desc->devicesSupportEncodedFormats(sharedDevices.types())
+ == outputDesc->devicesSupportEncodedFormats(sharedDevices.types()))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
status_t AudioPolicyManager::getSpatializerOutput(const audio_config_base_t *mixerConfig,
const audio_attributes_t *attr,
audio_io_handle_t *output) {
@@ -5376,80 +5402,67 @@
}
if (!canBeSpatializedInt(
attr, configPtr, devicesTypeAddress)) {
- ALOGW("%s provided attributes or mixer config cannot be spatialized", __func__);
+ ALOGV("%s provided attributes or mixer config cannot be spatialized", __func__);
return BAD_VALUE;
}
sp<IOProfile> profile =
getSpatializerOutputProfile(configPtr, devicesTypeAddress);
if (profile == nullptr) {
- ALOGW("%s no suitable output profile for provided attributes or mixer config", __func__);
+ ALOGV("%s no suitable output profile for provided attributes or mixer config", __func__);
return BAD_VALUE;
}
- if (mSpatializerOutput != nullptr && mSpatializerOutput->mProfile == profile
- && configPtr != nullptr
- && configPtr->channel_mask == mSpatializerOutput->mMixerChannelMask) {
- *output = mSpatializerOutput->mIoHandle;
- ALOGV("%s returns current spatializer output %d", __func__, *output);
- return NO_ERROR;
- }
- mSpatializerOutput.clear();
+ std::vector<sp<SwAudioOutputDescriptor>> spatializerOutputs;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
- if (!desc->isDuplicated() && desc->mProfile == profile) {
- ALOGV("%s found output %d for spatializer profile", __func__, desc->mIoHandle);
- mSpatializerOutput = desc;
- break;
+ if (!desc->isDuplicated()
+ && (desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
+ spatializerOutputs.push_back(desc);
+ ALOGV("%s adding opened spatializer Output %d", __func__, desc->mIoHandle);
}
}
- if (mSpatializerOutput == nullptr) {
- ALOGW("%s no opened spatializer output for profile %s",
- __func__, profile->getName().c_str());
- return BAD_VALUE;
+ mSpatializerOutput.clear();
+ bool outputsChanged = false;
+ for (const auto& desc : spatializerOutputs) {
+ if (desc->mProfile == profile
+ && (configPtr == nullptr
+ || configPtr->channel_mask == desc->mMixerChannelMask)) {
+ mSpatializerOutput = desc;
+ ALOGV("%s reusing current spatializer output %d", __func__, desc->mIoHandle);
+ } else {
+ ALOGV("%s closing spatializerOutput output %d to match channel mask %#x"
+ " and devices %s", __func__, desc->mIoHandle,
+ configPtr != nullptr ? configPtr->channel_mask : 0,
+ devices.toString().c_str());
+ closeOutput(desc->mIoHandle);
+ outputsChanged = true;
+ }
}
- if (configPtr != nullptr
- && configPtr->channel_mask != mSpatializerOutput->mMixerChannelMask) {
- audio_config_base_t savedMixerConfig = {
- .sample_rate = mSpatializerOutput->getSamplingRate(),
- .format = mSpatializerOutput->getFormat(),
- .channel_mask = mSpatializerOutput->mMixerChannelMask,
- };
- DeviceVector savedDevices = mSpatializerOutput->devices();
-
- ALOGV("%s reopening spatializer output to match channel mask %#x (current mask %#x)",
- __func__, configPtr->channel_mask, mSpatializerOutput->mMixerChannelMask);
-
- closeOutput(mSpatializerOutput->mIoHandle);
- //from now on mSpatializerOutput is null
-
+ if (mSpatializerOutput == nullptr) {
sp<SwAudioOutputDescriptor> desc =
openOutputWithProfileAndDevice(profile, devices, mixerConfig);
- if (desc == nullptr) {
- // re open the spatializer output with previous channel mask
- desc = openOutputWithProfileAndDevice(profile, savedDevices, &savedMixerConfig);
- if (desc == nullptr) {
- ALOGE("%s failed to restore mSpatializerOutput with previous config", __func__);
- } else {
- mSpatializerOutput = desc;
- }
- mPreviousOutputs = mOutputs;
- mpClientInterface->onAudioPortListUpdate();
- *output = AUDIO_IO_HANDLE_NONE;
- ALOGW("%s could not open spatializer output with requested config", __func__);
- return BAD_VALUE;
+ if (desc != nullptr) {
+ mSpatializerOutput = desc;
+ outputsChanged = true;
}
- mSpatializerOutput = desc;
- mPreviousOutputs = mOutputs;
- mpClientInterface->onAudioPortListUpdate();
}
checkVirtualizerClientRoutes();
+ if (outputsChanged) {
+ mPreviousOutputs = mOutputs;
+ mpClientInterface->onAudioPortListUpdate();
+ }
+
+ if (mSpatializerOutput == nullptr) {
+ ALOGV("%s could not open spatializer output with requested config", __func__);
+ return BAD_VALUE;
+ }
*output = mSpatializerOutput->mIoHandle;
- ALOGV("%s returns new spatializer output %d", __func__, *output);
- return NO_ERROR;
+ ALOGV("%s returning new spatializer output %d", __func__, *output);
+ return OK;
}
status_t AudioPolicyManager::releaseSpatializerOutput(audio_io_handle_t output) {
@@ -5460,9 +5473,12 @@
return BAD_VALUE;
}
- mSpatializerOutput.clear();
-
- checkVirtualizerClientRoutes();
+ if (!isOutputOnlyAvailableRouteToSomeDevice(mSpatializerOutput)) {
+ ALOGV("%s closing spatializer output %d", __func__, mSpatializerOutput->mIoHandle);
+ closeOutput(mSpatializerOutput->mIoHandle);
+ //from now on mSpatializerOutput is null
+ checkVirtualizerClientRoutes();
+ }
return NO_ERROR;
}
@@ -5539,6 +5555,7 @@
return status;
}
+ mEngine->updateDeviceSelectionCache();
mCommunnicationStrategy = mEngine->getProductStrategyForAttributes(
mEngine->getAttributesForStreamType(AUDIO_STREAM_VOICE_CALL));
@@ -5738,6 +5755,21 @@
inputDesc->close();
}
}
+
+ // Check if spatializer outputs can be closed until used.
+ // mOutputs vector never contains duplicated outputs at this point.
+ std::vector<audio_io_handle_t> outputsClosed;
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if ((desc->mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0
+ && !isOutputOnlyAvailableRouteToSomeDevice(desc)) {
+ outputsClosed.push_back(desc->mIoHandle);
+ desc->close();
+ }
+ }
+ for (auto output : outputsClosed) {
+ removeOutput(output);
+ }
}
void AudioPolicyManager::addOutput(audio_io_handle_t output,
@@ -6432,6 +6464,18 @@
return false;
}
+bool AudioPolicyManager::isHearingAidUsedForComm() const {
+ DeviceVector devices = mEngine->getOutputDevicesForStream(AUDIO_STREAM_VOICE_CALL,
+ true /*fromCache*/);
+ for (const auto &device : devices) {
+ if (device->type() == AUDIO_DEVICE_OUT_HEARING_AID) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
void AudioPolicyManager::checkA2dpSuspend()
{
audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
@@ -7229,13 +7273,15 @@
bool isBtScoVolSrc = (volumeSource != VOLUME_SOURCE_NONE) && (btScoVolSrc == volumeSource);
bool isScoRequested = isScoRequestedForComm();
+ bool isHAUsed = isHearingAidUsedForComm();
+
// do not change in call volume if bluetooth is connected and vice versa
// if sco and call follow same curves, bypass forceUseForComm
if ((callVolSrc != btScoVolSrc) &&
((isVoiceVolSrc && isScoRequested) ||
- (isBtScoVolSrc && !isScoRequested))) {
+ (isBtScoVolSrc && !(isScoRequested || isHAUsed)))) {
ALOGV("%s cannot set volume group %d volume when is%srequested for comm", __func__,
- volumeSource, isScoRequested ? " " : "n ot ");
+ volumeSource, isScoRequested ? " " : " not ");
// Do not return an error here as AudioService will always set both voice call
// and bluetooth SCO volumes due to stream aliasing.
return NO_ERROR;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index b12b71a..0d9b5bf 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -1097,6 +1097,16 @@
void checkVirtualizerClientRoutes();
/**
+ * @brief Returns true if at least one device can only be reached via the output passed
+ * as argument. Always returns false for duplicated outputs.
+ * This can be used to decide if an output can be closed without forbidding
+ * playback to any given device.
+ * @param outputDesc the output to consider
+ * @return true if at least one device can only be reached via the output.
+ */
+ bool isOutputOnlyAvailableRouteToSomeDevice(const sp<SwAudioOutputDescriptor>& outputDesc);
+
+ /**
* @brief getInputForDevice selects an input handle for a given input device and
* requester context
* @param device to be used by requester, selected by policy mix rules or engine
@@ -1189,6 +1199,8 @@
bool isScoRequestedForComm() const;
+ bool isHearingAidUsedForComm() const;
+
bool areAllActiveTracksRerouted(const sp<SwAudioOutputDescriptor>& output);
/**
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index da0a4a9..18339b0 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -1938,12 +1938,16 @@
while (!exitPending())
{
sp<AudioPolicyService> svc;
+ int numTimesBecameEmpty = 0;
while (!mAudioCommands.isEmpty() && !exitPending()) {
nsecs_t curTime = systemTime();
// commands are sorted by increasing time stamp: execute them from index 0 and up
if (mAudioCommands[0]->mTime <= curTime) {
sp<AudioCommand> command = mAudioCommands[0];
mAudioCommands.removeAt(0);
+ if (mAudioCommands.isEmpty()) {
+ ++numTimesBecameEmpty;
+ }
mLastCommand = command;
switch (command->mCommand) {
@@ -2180,8 +2184,9 @@
}
}
- // release delayed commands wake lock if the queue is empty
- if (mAudioCommands.isEmpty()) {
+ // release delayed commands wake lock as many times as we made the queue is
+ // empty during popping.
+ while (numTimesBecameEmpty--) {
release_wake_lock(mName.string());
}
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 3b466d7..389233e 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -459,9 +459,7 @@
}
std::lock_guard lock(mLock);
mScreenSensor = sensorHandle;
- if (mPoseController != nullptr) {
- mPoseController->setScreenSensor(mScreenSensor);
- }
+ checkSensorsState_l();
return Status::ok();
}
@@ -569,9 +567,6 @@
sp<media::ISpatializerHeadTrackingCallback> callback;
{
std::lock_guard lock(mLock);
- if (mActualHeadTrackingMode == SpatializerHeadTrackingMode::DISABLED) {
- return;
- }
callback = mHeadTrackingCallback;
if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
@@ -595,7 +590,6 @@
ALOGV("%s(%d)", __func__, (int) mode);
sp<media::ISpatializerHeadTrackingCallback> callback;
SpatializerHeadTrackingMode spatializerMode;
- bool modeChanged = false;
{
std::lock_guard lock(mLock);
if (!mSupportsHeadTracking) {
@@ -615,21 +609,19 @@
LOG_ALWAYS_FATAL("Unknown mode: %d", mode);
}
}
- modeChanged = mActualHeadTrackingMode != spatializerMode;
mActualHeadTrackingMode = spatializerMode;
- if (modeChanged && mEngine != nullptr) {
+ if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
std::vector<SpatializerHeadTrackingMode>{spatializerMode});
}
callback = mHeadTrackingCallback;
}
- if (callback != nullptr && modeChanged) {
+ if (callback != nullptr) {
callback->onHeadTrackingModeChanged(spatializerMode);
}
}
status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTracks) {
- std::shared_ptr<SpatializerPoseController> poseController;
bool outputChanged = false;
sp<media::INativeSpatializerCallback> callback;
@@ -663,14 +655,9 @@
if (mSupportsHeadTracking) {
checkPoseController_l();
checkSensorsState_l();
- poseController = mPoseController;
}
callback = mSpatializerCallback;
}
- if (poseController != nullptr) {
- poseController->calculateAsync();
- poseController->waitUntilCalculated();
- }
if (outputChanged && callback != nullptr) {
callback->onOutputChanged(output);
@@ -750,7 +737,7 @@
if (isControllerNeeded && mPoseController == nullptr) {
mPoseController = std::make_shared<SpatializerPoseController>(
static_cast<SpatializerPoseController::Listener*>(this),
- 10ms, std::chrono::microseconds::max());
+ 10ms, std::nullopt);
LOG_ALWAYS_FATAL_IF(mPoseController == nullptr,
"%s could not allocate pose controller", __func__);
mPoseController->setDisplayOrientation(mDisplayOrientation);
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 58a57ac..0a9f4d9 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -46,9 +46,8 @@
// high will result in high prediction errors whenever the head accelerates (changes velocity).
constexpr auto kPredictionDuration = 50ms;
-// After losing this many consecutive samples from either sensor, we would treat the measurement as
-// stale;
-constexpr auto kMaxLostSamples = 4;
+// After not getting a pose sample for this long, we would treat the measurement as stale.
+constexpr auto kFreshnessTimeout = 50ms;
// Auto-recenter kicks in after the head has been still for this long.
constexpr auto kAutoRecenterWindowDuration = 6s;
@@ -79,14 +78,14 @@
} // namespace
SpatializerPoseController::SpatializerPoseController(Listener* listener,
- std::chrono::microseconds sensorPeriod,
- std::chrono::microseconds maxUpdatePeriod)
+ std::chrono::microseconds sensorPeriod,
+ std::optional<std::chrono::microseconds> maxUpdatePeriod)
: mListener(listener),
mSensorPeriod(sensorPeriod),
mProcessor(createHeadTrackingProcessor(HeadTrackingProcessor::Options{
.maxTranslationalVelocity = kMaxTranslationalVelocity / kTicksPerSecond,
.maxRotationalVelocity = kMaxRotationalVelocity / kTicksPerSecond,
- .freshnessTimeout = Ticks(sensorPeriod * kMaxLostSamples).count(),
+ .freshnessTimeout = Ticks(kFreshnessTimeout).count(),
.predictionDuration = Ticks(kPredictionDuration).count(),
.autoRecenterWindowDuration = Ticks(kAutoRecenterWindowDuration).count(),
.autoRecenterTranslationalThreshold = kAutoRecenterTranslationThreshold,
@@ -102,8 +101,12 @@
std::optional<HeadTrackingMode> modeIfChanged;
{
std::unique_lock lock(mMutex);
- mCondVar.wait_for(lock, maxUpdatePeriod,
- [this] { return mShouldExit || mShouldCalculate; });
+ if (maxUpdatePeriod.has_value()) {
+ mCondVar.wait_for(lock, maxUpdatePeriod.value(),
+ [this] { return mShouldExit || mShouldCalculate; });
+ } else {
+ mCondVar.wait(lock, [this] { return mShouldExit || mShouldCalculate; });
+ }
if (mShouldExit) {
ALOGV("Exiting thread");
return;
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index 2b5c189..2c6d79a 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -60,10 +60,10 @@
* Ctor.
* sensorPeriod determines how often to receive updates from the sensors (input rate).
* maxUpdatePeriod determines how often to produce an output when calculateAsync() isn't
- * invoked.
+ * invoked; passing nullopt means an output is never produced.
*/
SpatializerPoseController(Listener* listener, std::chrono::microseconds sensorPeriod,
- std::chrono::microseconds maxUpdatePeriod);
+ std::optional<std::chrono::microseconds> maxUpdatePeriod);
/** Dtor. */
~SpatializerPoseController();
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 1f0e095..5db3fa6 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -721,8 +721,10 @@
}
*status = false;
+ camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
+ return mDevice->infoPhysical(id);};
ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.string(),
- sessionConfiguration, mOverrideForPerfClass, status);
+ sessionConfiguration, mOverrideForPerfClass, getMetadata, status);
switch (ret) {
case OK:
// Expected, do nothing.
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 6058429..5da77d6 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -441,6 +441,10 @@
newFormat->setInt32(KEY_TILE_HEIGHT, mGridHeight);
newFormat->setInt32(KEY_GRID_ROWS, mGridRows);
newFormat->setInt32(KEY_GRID_COLUMNS, mGridCols);
+ int32_t left, top, right, bottom;
+ if (newFormat->findRect("crop", &left, &top, &right, &bottom)) {
+ newFormat->setRect("crop", 0, 0, mOutputWidth - 1, mOutputHeight - 1);
+ }
}
}
newFormat->setInt32(KEY_IS_DEFAULT, 1 /*isPrimary*/);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 4cc03f0..d545484 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -40,7 +40,6 @@
#include <android-base/logging.h>
#include <cutils/properties.h>
#include <hwbinder/IPCThreadState.h>
-#include <utils/SessionConfigurationUtils.h>
#include <utils/Trace.h>
#include "api2/HeicCompositeStream.h"
@@ -338,14 +337,15 @@
status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
const SessionConfiguration &configuration, bool overrideForPerfClass,
- bool *status /*out*/) const {
+ metadataGetter getMetadata, bool *status /*out*/) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) {
return NAME_NOT_FOUND;
}
- return deviceInfo->isSessionConfigurationSupported(configuration, overrideForPerfClass, status);
+ return deviceInfo->isSessionConfigurationSupported(configuration,
+ overrideForPerfClass, getMetadata, status);
}
status_t CameraProviderManager::getCameraIdIPCTransport(const std::string &id,
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 3d108bd..d934ae8 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -33,6 +33,7 @@
#include <utils/Errors.h>
#include <android/hardware/ICameraService.h>
#include <utils/IPCTransport.h>
+#include <utils/SessionConfigurationUtils.h>
#include <aidl/android/hardware/camera/provider/ICameraProvider.h>
#include <android/hardware/camera/common/1.0/types.h>
#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
@@ -278,7 +279,7 @@
*/
status_t isSessionConfigurationSupported(const std::string& id,
const SessionConfiguration &configuration,
- bool overrideForPerfClass,
+ bool overrideForPerfClass, camera3::metadataGetter getMetadata,
bool *status /*out*/) const;
/**
@@ -587,6 +588,7 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
bool /*overrideForPerfClass*/,
+ camera3::metadataGetter /*getMetadata*/,
bool * /*status*/) {
return INVALID_OPERATION;
}
@@ -639,6 +641,7 @@
CameraMetadata *characteristics) const override;
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &configuration, bool /*overrideForPerfClass*/,
+ camera3::metadataGetter /*getMetadata*/,
bool *status /*out*/) = 0;
virtual status_t filterSmallJpegSizes() override;
virtual void notifyDeviceStateChange(
@@ -658,6 +661,8 @@
// A copy of mCameraCharacteristics without performance class
// override
std::unique_ptr<CameraMetadata> mCameraCharNoPCOverride;
+ // Only contains characteristics for hidden physical cameras,
+ // not for public physical cameras.
std::unordered_map<std::string, CameraMetadata> mPhysicalCameraCharacteristics;
void queryPhysicalCameraIds();
SystemCameraKind getSystemCameraKind();
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index 6f35e56..f58ed00 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -693,15 +693,11 @@
}
status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
- const SessionConfiguration &configuration, bool overrideForPerfClass, bool *status) {
+ const SessionConfiguration &configuration, bool overrideForPerfClass,
+ camera3::metadataGetter getMetadata, bool *status) {
camera::device::StreamConfiguration streamConfiguration;
bool earlyExit = false;
- camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
- CameraMetadata physicalChars;
- getPhysicalCameraCharacteristics(id.c_str(), &physicalChars);
- return physicalChars;
- };
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
streamConfiguration, overrideForPerfClass, &earlyExit);
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
index aa71e85..97a8fed 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.h
@@ -129,7 +129,7 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
- bool overrideForPerfClass,
+ bool overrideForPerfClass, camera3::metadataGetter /*getMetadata*/,
bool *status/*status*/);
std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index 3c5ea75..9cbfbcf 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -878,15 +878,11 @@
}
status_t HidlProviderInfo::HidlDeviceInfo3::isSessionConfigurationSupported(
- const SessionConfiguration &configuration, bool overrideForPerfClass, bool *status) {
+ const SessionConfiguration &configuration, bool overrideForPerfClass,
+ metadataGetter getMetadata, bool *status) {
hardware::camera::device::V3_8::StreamConfiguration streamConfiguration;
bool earlyExit = false;
- camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
- CameraMetadata physicalChars;
- getPhysicalCameraCharacteristics(id.c_str(), &physicalChars);
- return physicalChars;
- };
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
streamConfiguration, overrideForPerfClass, &earlyExit);
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
index 4181fea..e0f1646 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.h
@@ -105,7 +105,7 @@
virtual status_t isSessionConfigurationSupported(
const SessionConfiguration &/*configuration*/,
- bool overrideForPerfClass,
+ bool overrideForPerfClass, camera3::metadataGetter getMetadata,
bool *status/*status*/);
sp<hardware::camera::device::V3_2::ICameraDevice> startDeviceInterface();
};
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 8abcc95..038c075 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -48,7 +48,7 @@
namespace android {
namespace camera3 {
-typedef std::function<CameraMetadata (const String8 &, int targetSdkVersion)> metadataGetter;
+typedef std::function<CameraMetadata (const String8 &, bool overrideForPerfClass)> metadataGetter;
class StreamConfiguration {
public:
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index e0584df..b4610bc 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -732,6 +732,7 @@
return true;
}
+ int failedClientPid = -1;
{
Mutex::Autolock lock(mLock);
bool found = false;
@@ -746,11 +747,14 @@
}
}
if (found) {
+ failedClientPid = mMap.keyAt(i);
break;
}
}
- if (!found) {
- ALOGV("didn't find failed client");
+ if (found) {
+ ALOGW("Failed to reclaim resources from client with pid %d", failedClientPid);
+ } else {
+ ALOGW("Failed to reclaim resources from unlocateable client");
}
}
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index 6d8ae03..fe74a5c 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -390,7 +390,9 @@
static_cast<int32_t>(Result::INVALID_STATE));
}
- HidlResult res = mFilter->releaseAvHandle(hidl_handle(makeFromAidl(in_handle)), in_avDataId);
+ hidl_handle handle;
+ handle.setTo(makeFromAidl(in_handle), true);
+ HidlResult res = mFilter->releaseAvHandle(handle, in_avDataId);
if (res != HidlResult::SUCCESS) {
return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
}