Merge "[DON'T BLOCK] Test ownership migration rules" into main
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 2266483..bfbc457 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -86,6 +86,13 @@
flag {
namespace: "camera_platform"
+ name: "camera_extensions_characteristics_get"
+ description: "Enable get extension specific camera characteristics API"
+ bug: "280649914"
+}
+
+flag {
+ namespace: "camera_platform"
name: "delay_lazy_hal_instantiation"
description: "Only trigger lazy HAL instantiation when the HAL is needed for an operation."
bug: "319735068"
diff --git a/media/audio/aconfig/audio_framework.aconfig b/media/audio/aconfig/audio_framework.aconfig
index f7a3949..c64deeb 100644
--- a/media/audio/aconfig/audio_framework.aconfig
+++ b/media/audio/aconfig/audio_framework.aconfig
@@ -30,6 +30,15 @@
bug: "316414750"
}
+flag {
+ name: "foreground_audio_control"
+ namespace: "media_audio"
+ description:
+ "Audio focus gain requires FGS or delegation to "
+ "take effect"
+ bug: "296232417"
+}
+
# TODO remove
flag {
name: "focus_freeze_test_api"
diff --git a/media/codec2/components/avc/C2SoftAvcDec.cpp b/media/codec2/components/avc/C2SoftAvcDec.cpp
index 96a4c4a..3385b95 100644
--- a/media/codec2/components/avc/C2SoftAvcDec.cpp
+++ b/media/codec2/components/avc/C2SoftAvcDec.cpp
@@ -416,6 +416,7 @@
ivdext_create_op_t s_create_op = {};
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+ s_create_ip.u4_keep_threads_active = 1;
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorFormat;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index e424860..80a5e67 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -152,6 +152,17 @@
.build());
addParameter(
+ DefineParam(mBitrateMode, C2_PARAMKEY_BITRATE_MODE)
+ .withDefault(new C2StreamBitrateModeTuning::output(0u, C2Config::BITRATE_VARIABLE))
+ .withFields({C2F(mBitrateMode, value).oneOf({
+ C2Config::BITRATE_CONST,
+ C2Config::BITRATE_VARIABLE,
+ C2Config::BITRATE_IGNORE})
+ })
+ .withSetter(Setter<decltype(*mBitrateMode)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
DefineParam(mBitrate, C2_PARAMKEY_BITRATE)
.withDefault(new C2StreamBitrateInfo::output(0u, 64000))
.withFields({C2F(mBitrate, value).inRange(4096, 12000000)})
@@ -536,6 +547,9 @@
std::shared_ptr<C2StreamPictureSizeInfo::input> getSize_l() const { return mSize; }
std::shared_ptr<C2StreamIntraRefreshTuning::output> getIntraRefresh_l() const { return mIntraRefresh; }
std::shared_ptr<C2StreamFrameRateInfo::output> getFrameRate_l() const { return mFrameRate; }
+ std::shared_ptr<C2StreamBitrateModeTuning::output> getBitrateMode_l() const {
+ return mBitrateMode;
+ }
std::shared_ptr<C2StreamBitrateInfo::output> getBitrate_l() const { return mBitrate; }
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> getRequestSync_l() const { return mRequestSync; }
std::shared_ptr<C2StreamGopTuning::output> getGop_l() const { return mGop; }
@@ -552,6 +566,7 @@
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+ std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
std::shared_ptr<C2StreamProfileLevelInfo::output> mProfileLevel;
std::shared_ptr<C2StreamSyncFrameIntervalTuning::output> mSyncFramePeriod;
std::shared_ptr<C2StreamGopTuning::output> mGop;
@@ -1154,6 +1169,7 @@
{
IntfImpl::Lock lock = mIntf->lock();
mSize = mIntf->getSize_l();
+ mBitrateMode = mIntf->getBitrateMode_l();
mBitrate = mIntf->getBitrate_l();
mFrameRate = mIntf->getFrameRate_l();
mIntraRefresh = mIntf->getIntraRefresh_l();
@@ -1326,8 +1342,23 @@
} else {
ps_init_ip->u4_enable_recon = 0;
}
+
+ switch (mBitrateMode->value) {
+ case C2Config::BITRATE_IGNORE:
+ ps_init_ip->e_rc_mode = IVE_RC_NONE;
+ break;
+ case C2Config::BITRATE_CONST:
+ ps_init_ip->e_rc_mode = IVE_RC_CBR_NON_LOW_DELAY;
+ break;
+ case C2Config::BITRATE_VARIABLE:
+ ps_init_ip->e_rc_mode = IVE_RC_STORAGE;
+ break;
+ default:
+ ps_init_ip->e_rc_mode = DEFAULT_RC_MODE;
+ break;
+ break;
+ }
ps_init_ip->e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT;
- ps_init_ip->e_rc_mode = DEFAULT_RC_MODE;
ps_init_ip->u4_max_framerate = DEFAULT_MAX_FRAMERATE;
ps_init_ip->u4_max_bitrate = DEFAULT_MAX_BITRATE;
ps_init_ip->u4_num_bframes = mBframes;
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.h b/media/codec2/components/avc/C2SoftAvcEnc.h
index cde6604..33d166f 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.h
+++ b/media/codec2/components/avc/C2SoftAvcEnc.h
@@ -191,6 +191,7 @@
std::shared_ptr<C2StreamIntraRefreshTuning::output> mIntraRefresh;
std::shared_ptr<C2StreamFrameRateInfo::output> mFrameRate;
std::shared_ptr<C2StreamBitrateInfo::output> mBitrate;
+ std::shared_ptr<C2StreamBitrateModeTuning::output> mBitrateMode;
std::shared_ptr<C2StreamRequestSyncFrameTuning::output> mRequestSync;
std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects;
diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp
index 15d6dcd..81db2a1 100644
--- a/media/codec2/components/hevc/C2SoftHevcDec.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp
@@ -407,6 +407,7 @@
ivdext_create_op_t s_create_op = {};
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t);
+ s_create_ip.u4_keep_threads_active = 1;
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorformat;
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index 439323c..491098d 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -433,6 +433,7 @@
s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(ivdext_fill_mem_rec_ip_t);
s_fill_mem_ip.u4_share_disp_buf = 0;
+ s_fill_mem_ip.u4_keep_threads_active = 1;
s_fill_mem_ip.e_output_format = mIvColorformat;
s_fill_mem_ip.u4_deinterlace = 1;
s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
@@ -474,6 +475,7 @@
s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = mHeight;
s_init_ip.u4_share_disp_buf = 0;
s_init_ip.u4_deinterlace = 1;
+ s_init_ip.u4_keep_threads_active = 1;
s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords;
s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorformat;
s_init_op.s_ivd_init_op_t.u4_size = sizeof(ivdext_init_op_t);
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 5f525d7..2a8ebc6 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -788,7 +788,7 @@
if (VALUE_OR_RETURN_STATUS(filterOutAndProcessParameter<int>(
parameters, String8(AudioParameter::keyOffloadCodecAverageBitRate),
[&](int value) {
- return value > 0 ?
+ return value >= 0 ?
mOffloadMetadata.averageBitRatePerSecond = value, OK : BAD_VALUE;
}))) {
updateMetadata = true;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index bc1a97c..d50c06b 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2454,6 +2454,11 @@
return true;
}
+ // Make sure abs(timeUs) does not overflow
+ if (timeUs == INT64_MIN) {
+ return false;
+ }
+
// Ensure that the timeUs value does not have extremely low or high values
// that would cause an underflow or overflow, like in the calculation -
// mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 33df27b..4d6a67b 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2254,7 +2254,10 @@
static void mapFormat(AString componentName, const sp<AMessage> &format, const char *kind,
bool reverse);
-mediametrics_handle_t MediaCodec::createMediaMetrics(const sp<AMessage>& format, uint32_t flags) {
+mediametrics_handle_t MediaCodec::createMediaMetrics(const sp<AMessage>& format,
+ uint32_t flags,
+ status_t* err) {
+ *err = OK;
mediametrics_handle_t nextMetricsHandle = mediametrics_create(kCodecKeyName);
bool isEncoder = (flags & CONFIGURE_FLAG_ENCODE);
@@ -2334,7 +2337,9 @@
mErrorLog.log(LOG_TAG, base::StringPrintf(
"Invalid size(s), width=%d, height=%d", mWidth, mHeight));
mediametrics_delete(nextMetricsHandle);
- return BAD_VALUE;
+ // Set the error code and return null handle.
+ *err = BAD_VALUE;
+ return 0;
}
} else {
@@ -2417,7 +2422,11 @@
updateCodecImportance(format);
// Create and set up metrics for this codec.
- mediametrics_handle_t nextMetricsHandle = createMediaMetrics(format, flags);
+ status_t err = OK;
+ mediametrics_handle_t nextMetricsHandle = createMediaMetrics(format, flags, &err);
+ if (err != OK) {
+ return err;
+ }
sp<AMessage> msg = new AMessage(kWhatConfigure, this);
msg->setMessage("format", format);
@@ -2452,7 +2461,6 @@
sp<AMessage> callback = mCallback;
- status_t err;
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
toMediaResourceSubType(mIsHardware, mDomain)));
@@ -4837,30 +4845,32 @@
}
}
}
- int32_t largeFrameParam;
- if (format->findInt32(KEY_BUFFER_BATCH_MAX_OUTPUT_SIZE, &largeFrameParam) ||
+ int32_t largeFrameParamMax = 0, largeFrameParamThreshold = 0;
+ if (format->findInt32(KEY_BUFFER_BATCH_MAX_OUTPUT_SIZE, &largeFrameParamMax) ||
format->findInt32(KEY_BUFFER_BATCH_THRESHOLD_OUTPUT_SIZE,
- &largeFrameParam)) {
- if(mComponentName.startsWith("OMX")) {
- mErrorLog.log(LOG_TAG,
- "Large Frame params are not supported on OMX codecs."
- "Currently only supported on C2 audio codec.");
- PostReplyWithError(replyID, INVALID_OPERATION);
- break;
- }
- AString mime;
- CHECK(format->findString("mime", &mime));
- if (!mime.startsWith("audio")) {
- mErrorLog.log(LOG_TAG,
- "Large Frame params only works with audio codec");
- PostReplyWithError(replyID, INVALID_OPERATION);
- break;
- }
- if (!(mFlags & kFlagIsAsync)) {
- mErrorLog.log(LOG_TAG, "Large Frame audio" \
- "config works only with async mode");
- PostReplyWithError(replyID, INVALID_OPERATION);
- break;
+ &largeFrameParamThreshold)) {
+ if (largeFrameParamMax > 0 || largeFrameParamThreshold > 0) {
+ if(mComponentName.startsWith("OMX")) {
+ mErrorLog.log(LOG_TAG,
+ "Large Frame params are not supported on OMX codecs."
+ "Currently only supported on C2 audio codec.");
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ break;
+ }
+ AString mime;
+ CHECK(format->findString("mime", &mime));
+ if (!mime.startsWith("audio")) {
+ mErrorLog.log(LOG_TAG,
+ "Large Frame params only works with audio codec");
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ break;
+ }
+ if (!(mFlags & kFlagIsAsync)) {
+ mErrorLog.log(LOG_TAG, "Large Frame audio" \
+ "config works only with async mode");
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ break;
+ }
}
}
diff --git a/media/libstagefright/data/media_codecs_sw.xml b/media/libstagefright/data/media_codecs_sw.xml
index 24020d1..dc7d787 100644
--- a/media/libstagefright/data/media_codecs_sw.xml
+++ b/media/libstagefright/data/media_codecs_sw.xml
@@ -330,6 +330,7 @@
<!-- Video Quality control -->
<!-- supports QP bounding with standard keys -->
<Feature name="qp-bounds" />
+ <Feature name="bitrate-modes" value="VBR,CBR" />
<Attribute name="software-codec" />
</MediaCodec>
<MediaCodec name="c2.android.vp8.encoder" type="video/x-vnd.on2.vp8" variant="slow-cpu,!slow-cpu">
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 6622f4f..b0b1427 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -331,7 +331,10 @@
friend struct ResourceManagerClient;
// to create the metrics associated with this codec.
- mediametrics_handle_t createMediaMetrics(const sp<AMessage>& format, uint32_t flags);
+ // Any error in this function will be captured by the output argument err.
+ mediametrics_handle_t createMediaMetrics(const sp<AMessage>& format,
+ uint32_t flags,
+ status_t* err);
private:
enum State {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index ff1b5e0..34569ba 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7876,16 +7876,12 @@
// (mRequestedLatencyMode = AUDIO_LATENCY_MODE_LOW)
// AND
// - At least one active track is spatialized
- bool hasSpatializedActiveTrack = false;
for (const auto& track : mActiveTracks) {
if (track->isSpatialized()) {
- hasSpatializedActiveTrack = true;
+ latencyMode = mRequestedLatencyMode;
break;
}
}
- if (hasSpatializedActiveTrack && mRequestedLatencyMode == AUDIO_LATENCY_MODE_LOW) {
- latencyMode = AUDIO_LATENCY_MODE_LOW;
- }
}
if (latencyMode != mSetLatencyMode) {
@@ -7899,7 +7895,7 @@
}
status_t SpatializerThread::setRequestedLatencyMode(audio_latency_mode_t mode) {
- if (mode != AUDIO_LATENCY_MODE_LOW && mode != AUDIO_LATENCY_MODE_FREE) {
+ if (mode < 0 || mode >= AUDIO_LATENCY_MODE_CNT) {
return BAD_VALUE;
}
audio_utils::lock_guard _l(mutex());
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.cc b/services/camera/virtualcamera/VirtualCameraDevice.cc
index a244c0f..52fe272 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.cc
+++ b/services/camera/virtualcamera/VirtualCameraDevice.cc
@@ -72,10 +72,9 @@
constexpr MetadataBuilder::ControlRegion kDefaultEmptyControlRegion{};
-const std::array<int32_t, 3> kOutputFormats{
- ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
- ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
- ANDROID_SCALER_AVAILABLE_FORMATS_BLOB};
+const std::array<PixelFormat, 3> kOutputFormats{
+ PixelFormat::IMPLEMENTATION_DEFINED, PixelFormat::YCBCR_420_888,
+ PixelFormat::BLOB};
struct Resolution {
Resolution(const int w, const int h) : width(w), height(h) {
@@ -93,6 +92,11 @@
const int height;
};
+bool isSupportedOutputFormat(const PixelFormat pixelFormat) {
+ return std::find(kOutputFormats.begin(), kOutputFormats.end(), pixelFormat) !=
+ kOutputFormats.end();
+}
+
std::optional<Resolution> getMaxResolution(
const std::vector<SupportedStreamConfiguration>& configs) {
auto itMax = std::max_element(configs.begin(), configs.end(),
@@ -151,9 +155,11 @@
.setFlashAvailable(false)
.setLensFacing(
static_cast<camera_metadata_enum_android_lens_facing>(lensFacing))
+ .setFocalLength(43.0)
.setSensorOrientation(static_cast<int32_t>(sensorOrientation))
.setSensorReadoutTimestamp(
ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED)
+ .setSensorPhysicalSize(36.0, 24.0)
.setAvailableFaceDetectModes({ANDROID_STATISTICS_FACE_DETECT_MODE_OFF})
.setAvailableMaxDigitalZoom(1.0)
.setControlAvailableModes({ANDROID_CONTROL_MODE_AUTO})
@@ -172,6 +178,10 @@
.setControlAvailableAwbModes({ANDROID_CONTROL_AWB_MODE_AUTO})
.setControlZoomRatioRange(/*min=*/1.0, /*max=*/1.0)
.setMaxJpegSize(kMaxJpegSize)
+ .setMaxNumberOutputStreams(
+ VirtualCameraDevice::kMaxNumberOfRawStreams,
+ VirtualCameraDevice::kMaxNumberOfProcessedStreams,
+ VirtualCameraDevice::kMaxNumberOfStallStreams)
.setSyncMaxLatency(ANDROID_SYNC_MAX_LATENCY_UNKNOWN)
.setAvailableRequestKeys({})
.setAvailableRequestKeys({ANDROID_CONTROL_AF_MODE})
@@ -188,6 +198,7 @@
}
builder.setSensorActiveArraySize(0, 0, maxResolution->width,
maxResolution->height);
+ builder.setSensorPixelArraySize(maxResolution->width, maxResolution->height);
std::vector<MetadataBuilder::StreamConfiguration> outputConfigurations;
@@ -198,7 +209,7 @@
getResolutionToMaxFpsMap(supportedInputConfig);
// Add configurations for all unique input resolutions and output formats.
- for (int32_t format : kOutputFormats) {
+ for (const PixelFormat format : kOutputFormats) {
std::transform(
resolutionToMaxFpsMap.begin(), resolutionToMaxFpsMap.end(),
std::back_inserter(outputConfigurations), [format](const auto& entry) {
@@ -207,7 +218,7 @@
return MetadataBuilder::StreamConfiguration{
.width = resolution.width,
.height = resolution.height,
- .format = format,
+ .format = static_cast<int32_t>(format),
.minFrameDuration = std::chrono::nanoseconds(1s) / maxFps,
.minStallDuration = 0s};
});
@@ -297,6 +308,8 @@
return false;
}
+ int numberOfProcessedStreams = 0;
+ int numberOfStallStreams = 0;
for (const Stream& stream : streamConfiguration.streams) {
ALOGV("%s: Configuration queried: %s", __func__, stream.toString().c_str());
@@ -305,15 +318,18 @@
return false;
}
- // TODO(b/301023410) remove hardcoded format checks, verify against configuration.
if (stream.rotation != StreamRotation::ROTATION_0 ||
- (stream.format != PixelFormat::IMPLEMENTATION_DEFINED &&
- stream.format != PixelFormat::YCBCR_420_888 &&
- stream.format != PixelFormat::BLOB)) {
+ !isSupportedOutputFormat(stream.format)) {
ALOGV("Unsupported output stream type");
return false;
}
+ if (stream.format == PixelFormat::BLOB) {
+ numberOfStallStreams++;
+ } else {
+ numberOfProcessedStreams++;
+ }
+
auto matchesSupportedInputConfig =
[&stream](const SupportedStreamConfiguration& config) {
return stream.width == config.width && stream.height == config.height;
@@ -325,6 +341,19 @@
return false;
}
}
+
+ if (numberOfProcessedStreams > kMaxNumberOfProcessedStreams) {
+ ALOGE("%s: %d processed streams exceeds the supported maximum of %d",
+ __func__, numberOfProcessedStreams, kMaxNumberOfProcessedStreams);
+ return false;
+ }
+
+ if (numberOfStallStreams > kMaxNumberOfStallStreams) {
+ ALOGE("%s: %d stall streams exceeds the supported maximum of %d", __func__,
+ numberOfStallStreams, kMaxNumberOfStallStreams);
+ return false;
+ }
+
return true;
}
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.h b/services/camera/virtualcamera/VirtualCameraDevice.h
index 10d52af..3700625 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.h
+++ b/services/camera/virtualcamera/VirtualCameraDevice.h
@@ -94,6 +94,19 @@
uint32_t getCameraId() const { return mCameraId; }
+ // Maximal number of RAW streams - virtual camera doesn't support RAW streams.
+ static const int32_t kMaxNumberOfRawStreams = 0;
+
+ // Maximal number of non-jpeg streams configured concurrently in single
+ // session. This should be at least 3 and can be increased at the potential
+ // cost of more CPU/GPU load if there are many concurrent streams.
+ static const int32_t kMaxNumberOfProcessedStreams = 3;
+
+ // Maximal number of stalling (in case of virtual camera only jpeg for now)
+ // streams. Can be increaed at the cost of potential cost of more GPU/CPU
+ // load.
+ static const int32_t kMaxNumberOfStallStreams = 1;
+
private:
std::shared_ptr<VirtualCameraDevice> sharedFromThis();
diff --git a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
index 027ecb7..35bf752 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <algorithm>
+#include <iterator>
#include <memory>
#include "VirtualCameraDevice.h"
@@ -22,6 +24,7 @@
#include "aidl/android/companion/virtualcamera/VirtualCameraConfiguration.h"
#include "aidl/android/hardware/camera/device/CameraMetadata.h"
#include "aidl/android/hardware/camera/device/StreamConfiguration.h"
+#include "aidl/android/hardware/graphics/common/PixelFormat.h"
#include "android/binder_interface_utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -55,6 +58,20 @@
constexpr int kHdHeight = 720;
constexpr int kMaxFps = 30;
+const Stream kVgaYUV420Stream = Stream{
+ .streamType = StreamType::OUTPUT,
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .format = PixelFormat::YCBCR_420_888,
+};
+
+const Stream kVgaJpegStream = Stream{
+ .streamType = StreamType::OUTPUT,
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .format = PixelFormat::BLOB,
+};
+
struct AvailableStreamConfiguration {
const int width;
const int height;
@@ -105,10 +122,11 @@
std::vector<AvailableStreamConfiguration> expectedAvailableStreamConfigs;
};
-class VirtualCameraDeviceTest
+class VirtualCameraDeviceCharacterisicsTest
: public testing::TestWithParam<VirtualCameraConfigTestParam> {};
-TEST_P(VirtualCameraDeviceTest, cameraCharacteristicsForInputFormat) {
+TEST_P(VirtualCameraDeviceCharacterisicsTest,
+ cameraCharacteristicsForInputFormat) {
const VirtualCameraConfigTestParam& param = GetParam();
std::shared_ptr<VirtualCameraDevice> camera =
ndk::SharedRefBase::make<VirtualCameraDevice>(kCameraId,
@@ -137,7 +155,7 @@
}
INSTANTIATE_TEST_SUITE_P(
- cameraCharacteristicsForInputFormat, VirtualCameraDeviceTest,
+ cameraCharacteristicsForInputFormat, VirtualCameraDeviceCharacterisicsTest,
testing::Values(
VirtualCameraConfigTestParam{
.inputConfig =
@@ -227,6 +245,67 @@
.streamConfiguration =
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}}));
+class VirtualCameraDeviceTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ mCamera = ndk::SharedRefBase::make<VirtualCameraDevice>(
+ kCameraId, VirtualCameraConfiguration{
+ .supportedStreamConfigs = {SupportedStreamConfiguration{
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps}},
+ .virtualCameraCallback = nullptr,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0,
+ .lensFacing = LensFacing::FRONT});
+ }
+
+ protected:
+ std::shared_ptr<VirtualCameraDevice> mCamera;
+};
+
+TEST_F(VirtualCameraDeviceTest, configureMaximalNumberOfNonStallStreamsSuceeds) {
+ StreamConfiguration config;
+ std::fill_n(std::back_insert_iterator(config.streams),
+ VirtualCameraDevice::kMaxNumberOfProcessedStreams,
+ kVgaYUV420Stream);
+
+ bool aidl_ret;
+ ASSERT_TRUE(mCamera->isStreamCombinationSupported(config, &aidl_ret).isOk());
+ EXPECT_TRUE(aidl_ret);
+}
+
+TEST_F(VirtualCameraDeviceTest, configureTooManyNonStallStreamsFails) {
+ StreamConfiguration config;
+ std::fill_n(std::back_insert_iterator(config.streams),
+ VirtualCameraDevice::kMaxNumberOfProcessedStreams + 1,
+ kVgaYUV420Stream);
+
+ bool aidl_ret;
+ ASSERT_TRUE(mCamera->isStreamCombinationSupported(config, &aidl_ret).isOk());
+ EXPECT_FALSE(aidl_ret);
+}
+
+TEST_F(VirtualCameraDeviceTest, configureMaximalNumberOfStallStreamsSuceeds) {
+ StreamConfiguration config;
+ std::fill_n(std::back_insert_iterator(config.streams),
+ VirtualCameraDevice::kMaxNumberOfStallStreams, kVgaJpegStream);
+
+ bool aidl_ret;
+ ASSERT_TRUE(mCamera->isStreamCombinationSupported(config, &aidl_ret).isOk());
+ EXPECT_TRUE(aidl_ret);
+}
+
+TEST_F(VirtualCameraDeviceTest, configureTooManyStallStreamsFails) {
+ StreamConfiguration config;
+ std::fill_n(std::back_insert_iterator(config.streams),
+ VirtualCameraDevice::kMaxNumberOfStallStreams + 1, kVgaJpegStream);
+
+ bool aidl_ret;
+ ASSERT_TRUE(mCamera->isStreamCombinationSupported(config, &aidl_ret).isOk());
+ EXPECT_FALSE(aidl_ret);
+}
+
} // namespace
} // namespace virtualcamera
} // namespace companion
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.cc b/services/camera/virtualcamera/util/MetadataBuilder.cc
index c2daa3b..bf4758f 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.cc
+++ b/services/camera/virtualcamera/util/MetadataBuilder.cc
@@ -82,6 +82,13 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setFocalLength(float focalLength) {
+ std::vector<float> focalLengths({focalLength});
+ mEntryMap[ANDROID_LENS_FOCAL_LENGTH] = focalLengths;
+ mEntryMap[ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS] = focalLengths;
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setSensorOrientation(int32_t sensorOrientation) {
mEntryMap[ANDROID_SENSOR_ORIENTATION] =
std::vector<int32_t>({sensorOrientation});
@@ -240,6 +247,14 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setMaxNumberOutputStreams(
+ const int32_t maxRawStreams, const int32_t maxProcessedStreams,
+ const int32_t maxStallStreams) {
+ mEntryMap[ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS] = std::vector<int32_t>(
+ {maxRawStreams, maxProcessedStreams, maxStallStreams});
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setSyncMaxLatency(
camera_metadata_enum_android_sync_max_latency latency) {
mEntryMap[ANDROID_SYNC_MAX_LATENCY] =
@@ -310,6 +325,20 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setSensorPixelArraySize(int width,
+ int height) {
+ mEntryMap[ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE] =
+ std::vector<int32_t>({width, height});
+ return *this;
+}
+
+MetadataBuilder& MetadataBuilder::setSensorPhysicalSize(float width,
+ float height) {
+ mEntryMap[ANDROID_SENSOR_INFO_PHYSICAL_SIZE] =
+ std::vector<float>({width, height});
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setControlAeCompensationRange(int32_t min,
int32_t max) {
mEntryMap[ANDROID_CONTROL_AE_COMPENSATION_RANGE] =
diff --git a/services/camera/virtualcamera/util/MetadataBuilder.h b/services/camera/virtualcamera/util/MetadataBuilder.h
index fc4d51a..d35fa3d 100644
--- a/services/camera/virtualcamera/util/MetadataBuilder.h
+++ b/services/camera/virtualcamera/util/MetadataBuilder.h
@@ -78,6 +78,10 @@
camera_metadata_enum_android_sensor_readout_timestamp_t
sensorReadoutTimestamp);
+ // See ANDROID_LENS_FOCAL_LENGTH and ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS
+ // in CameraMetadataTag.aidl.
+ MetadataBuilder& setFocalLength(float focalLength);
+
// See ANDROID_SENSOR_ORIENTATION in CameraMetadataTag.aidl.
MetadataBuilder& setSensorOrientation(int32_t sensorOrientation);
@@ -90,6 +94,12 @@
// See ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE in CameraMetadataTag.aidl.
MetadataBuilder& setSensorActiveArraySize(int x0, int y0, int x1, int y1);
+ // See ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE in CameraMetadataTag.aidl.
+ MetadataBuilder& setSensorPixelArraySize(int width, int height);
+
+ // See ANDROID_SENSOR_INFO_PHYSICAL_SIZE in CameraMetadataTag.aidl.
+ MetadataBuilder& setSensorPhysicalSize(float width, float height);
+
// See ANDROID_STATISTICS_FACE_DETECT_MODE in CameraMetadataTag.aidl.
MetadataBuilder& setAvailableFaceDetectModes(
const std::vector<camera_metadata_enum_android_statistics_face_detect_mode_t>&
@@ -173,6 +183,14 @@
// See ANDROID_JPEG_SIZE in CameraMetadataTag.aidl.
MetadataBuilder& setMaxJpegSize(int32_t size);
+ // The maximum numbers of different types of output streams
+ // that can be configured and used simultaneously by a camera device.
+ //
+ // See ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS in CameraMetadataTag.aidl.
+ MetadataBuilder& setMaxNumberOutputStreams(int32_t maxRawStreams,
+ int32_t maxProcessedStreams,
+ int32_t maxStallStreams);
+
// See ANDROID_SYNC_MAX_LATENCY in CameraMetadataTag.aidl.
MetadataBuilder& setSyncMaxLatency(
camera_metadata_enum_android_sync_max_latency setSyncMaxLatency);
diff --git a/services/mediaresourcemanager/DefaultResourceModel.cpp b/services/mediaresourcemanager/DefaultResourceModel.cpp
index 7bad715..990df82 100644
--- a/services/mediaresourcemanager/DefaultResourceModel.cpp
+++ b/services/mediaresourcemanager/DefaultResourceModel.cpp
@@ -44,7 +44,9 @@
clients.clear();
MediaResourceParcel mediaResource{.type = reclimRequestInfo.mResources[0].type,
.subType = reclimRequestInfo.mResources[0].subType};
- ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid,
+ reclimRequestInfo.mClientId,
+ &mediaResource};
// Resolve the secure-unsecure codec conflicts if there is any.
switch (reclimRequestInfo.mResources[0].type) {
@@ -116,7 +118,9 @@
const ReclaimRequestInfo& reclimRequestInfo,
std::vector<ClientInfo>& clients) {
MediaResourceParcel mediaResource;
- ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{reclimRequestInfo.mCallingPid,
+ reclimRequestInfo.mClientId,
+ &mediaResource};
// 1. Look to find the client(s) with the other resources, for the given
// primary type.
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 3a02443..305f6fe 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -474,6 +474,7 @@
const std::vector<MediaResourceParcel>& resources,
std::vector<ClientInfo>& targetClients) {
int32_t callingPid = clientInfo.pid;
+ int64_t clientId = clientInfo.id;
std::scoped_lock lock{mLock};
if (!mProcessInfo->isPidTrusted(callingPid)) {
pid_t actualCallingPid = IPCThreadState::self()->getCallingPid();
@@ -508,7 +509,7 @@
if (secureCodec != NULL) {
MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
.subType = secureCodec->subType};
- ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &mediaResource};
if (!mSupportsMultipleSecureCodecs) {
if (!getAllClients_l(resourceRequestInfo, targetClients)) {
return false;
@@ -525,7 +526,7 @@
if (!mSupportsSecureWithNonSecureCodec) {
MediaResourceParcel mediaResource{.type = MediaResource::Type::kSecureCodec,
.subType = nonSecureCodec->subType};
- ResourceRequestInfo resourceRequestInfo{callingPid, &mediaResource};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &mediaResource};
if (!getAllClients_l(resourceRequestInfo, targetClients)) {
return false;
}
@@ -533,7 +534,7 @@
}
if (drmSession != NULL) {
- ResourceRequestInfo resourceRequestInfo{callingPid, drmSession};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, drmSession};
getClientForResource_l(resourceRequestInfo, targetClients);
if (targetClients.size() == 0) {
return false;
@@ -542,18 +543,18 @@
if (targetClients.size() == 0 && graphicMemory != nullptr) {
// if no secure/non-secure codec conflict, run second pass to handle other resources.
- ResourceRequestInfo resourceRequestInfo{callingPid, graphicMemory};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, graphicMemory};
getClientForResource_l(resourceRequestInfo, targetClients);
}
if (targetClients.size() == 0) {
// if we are here, run the third pass to free one codec with the same type.
if (secureCodec != nullptr) {
- ResourceRequestInfo resourceRequestInfo{callingPid, secureCodec};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, secureCodec};
getClientForResource_l(resourceRequestInfo, targetClients);
}
if (nonSecureCodec != nullptr) {
- ResourceRequestInfo resourceRequestInfo{callingPid, nonSecureCodec};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, nonSecureCodec};
getClientForResource_l(resourceRequestInfo, targetClients);
}
}
@@ -562,12 +563,12 @@
// if we are here, run the fourth pass to free one codec with the different type.
if (secureCodec != nullptr) {
MediaResource temp(MediaResource::Type::kNonSecureCodec, secureCodec->subType, 1);
- ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &temp};
getClientForResource_l(resourceRequestInfo, targetClients);
}
if (nonSecureCodec != nullptr) {
MediaResource temp(MediaResource::Type::kSecureCodec, nonSecureCodec->subType, 1);
- ResourceRequestInfo resourceRequestInfo{callingPid, &temp};
+ ResourceRequestInfo resourceRequestInfo{callingPid, clientId, &temp};
getClientForResource_l(resourceRequestInfo, targetClients);
}
}
@@ -914,6 +915,11 @@
for (auto& [pid, infos] : mMap) {
for (const auto& [id, info] : infos) {
+ if (pid == resourceRequestInfo.mCallingPid && id == resourceRequestInfo.mClientId) {
+ ALOGI("%s: Skip the client[%jd] for which the resource request is made",
+ __func__, id);
+ continue;
+ }
if (hasResourceType(type, subType, info.resources)) {
if (!isCallingPriorityHigher_l(resourceRequestInfo.mCallingPid, pid)) {
// some higher/equal priority process owns the resource,
diff --git a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
index af093ca..0a0a8f4 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
+++ b/services/mediaresourcemanager/ResourceManagerServiceNew.cpp
@@ -248,7 +248,7 @@
// Use the Resource Model to get a list of all the clients that hold the
// needed/requested resources.
uint32_t callingImportance = std::max(0, clientInfo.importance);
- ReclaimRequestInfo reclaimRequestInfo{callingPid, callingImportance, resources};
+ ReclaimRequestInfo reclaimRequestInfo{callingPid, clientInfo.id, callingImportance, resources};
std::vector<ClientInfo> clients;
if (!mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients)) {
if (clients.empty()) {
@@ -300,7 +300,10 @@
// Use the DefaultResourceModel to get all the clients with the resources requested.
std::vector<MediaResourceParcel> resources{*resourceRequestInfo.mResource};
- ReclaimRequestInfo reclaimRequestInfo{resourceRequestInfo.mCallingPid, 0, resources};
+ ReclaimRequestInfo reclaimRequestInfo{resourceRequestInfo.mCallingPid,
+ resourceRequestInfo.mClientId,
+ 0, // default importance
+ resources};
std::vector<ClientInfo> clients;
mDefaultResourceModel->getAllClients(reclaimRequestInfo, clients);
diff --git a/services/mediaresourcemanager/ResourceManagerServiceUtils.h b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
index 32cb219..e8f1515 100644
--- a/services/mediaresourcemanager/ResourceManagerServiceUtils.h
+++ b/services/mediaresourcemanager/ResourceManagerServiceUtils.h
@@ -166,11 +166,13 @@
/*
* Resource Reclaim request info that encapsulates
* - the calling/requesting process pid.
+ * - id of the client that made reclaim request.
* - the calling/requesting client's importance.
* - the list of resources requesting (to be reclaimed from others)
*/
struct ReclaimRequestInfo {
int mCallingPid = -1;
+ int64_t mClientId = 0;
uint32_t mCallingClientImportance = 0;
const std::vector<::aidl::android::media::MediaResourceParcel>& mResources;
};
@@ -178,11 +180,14 @@
/*
* Resource request info that encapsulates
* - the calling/requesting process pid.
+ * - the calling/requesting client's id.
* - the resource requesting (to be reclaimed from others)
*/
struct ResourceRequestInfo {
// pid of the calling/requesting process.
int mCallingPid = -1;
+ // id of the calling/requesting client.
+ int64_t mClientId = 0;
// resources requested.
const ::aidl::android::media::MediaResourceParcel* mResource;
};
diff --git a/services/mediaresourcemanager/ResourceTracker.cpp b/services/mediaresourcemanager/ResourceTracker.cpp
index 22381c3..3ee20cd 100644
--- a/services/mediaresourcemanager/ResourceTracker.cpp
+++ b/services/mediaresourcemanager/ResourceTracker.cpp
@@ -715,6 +715,11 @@
MediaResource::SubType subType = resourceRequestInfo.mResource->subType;
for (auto& [pid, /* ResourceInfos */ infos] : mMap) {
for (const auto& [id, /* ResourceInfo */ info] : infos) {
+ if (pid == resourceRequestInfo.mCallingPid && id == resourceRequestInfo.mClientId) {
+ ALOGI("%s: Skip the client[%jd] for which the resource request is made",
+ __func__, id);
+ continue;
+ }
if (hasResourceType(type, subType, info.resources)) {
if (!isCallingPriorityHigher(resourceRequestInfo.mCallingPid, pid)) {
// some higher/equal priority process owns the resource,
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 7e8a4a0..2c8659d 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -165,6 +165,7 @@
DISALLOW_EVIL_CONSTRUCTORS(TestClient);
};
+// [pid, uid] used by the test.
static const int kTestPid1 = 30;
static const int kTestUid1 = 1010;
@@ -175,6 +176,12 @@
static const int kMidPriorityPid = 25;
static const int kHighPriorityPid = 10;
+// Client Ids used by the test.
+static const int kLowPriorityClientId = 1111;
+static const int kMidPriorityClientId = 2222;
+static const int kHighPriorityClientId = 3333;
+
+// Client importance used by the test.
static const int32_t kHighestCodecImportance = 0;
static const int32_t kLowestCodecImportance = 100;
static const int32_t kMidCodecImportance = 50;
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index b3a0932..027987e 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -337,7 +337,7 @@
// priority too low to reclaim resource
ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kLowPriorityPid),
.uid = static_cast<int32_t>(kTestUid1),
- .id = 0,
+ .id = kLowPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(clientInfo, resources, &result));
@@ -475,9 +475,9 @@
MediaResource resource(MediaResource::Type::kSecureCodec,
MediaResource::SubType::kUnspecifiedSubType,
1);
- ResourceRequestInfo requestInfoHigh { kHighPriorityPid, &resource};
- ResourceRequestInfo requestInfoMid { kMidPriorityPid, &resource};
- ResourceRequestInfo requestInfoLow { kLowPriorityPid, &resource};
+ ResourceRequestInfo requestInfoHigh { kHighPriorityPid, kHighPriorityClientId, &resource};
+ ResourceRequestInfo requestInfoMid { kMidPriorityPid, kMidPriorityClientId, &resource};
+ ResourceRequestInfo requestInfoLow { kLowPriorityPid, kLowPriorityClientId, &resource};
EXPECT_FALSE(mService->getAllClients_l(requestInfoLow, targetClients));
// some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
@@ -491,6 +491,81 @@
EXPECT_EQ(getId(mTestClient1), targetClients[1].mClientId);
}
+ // test set up
+ // ---------------------------------------------------------------------------
+ // pid/priority client/clientId type number
+ // ---------------------------------------------------------------------------
+ // kTestPid1(30) mTestClient1 secure codec 1
+ // graphic memory 200
+ // graphic memory 200
+ // ---------------------------------------------------------------------------
+ // kTestPid2(20) mTestClient2 non-secure codec 1
+ // graphic memory 300
+ // ---------------------------------------------------
+ // mTestClient3 secure codec 1
+ // graphic memory 100
+ // ---------------------------------------------------------------------------
+ // kHighPriorityPid(10) kHighPriorityClient secure codec 1
+ // ---------------------------------------------------------------------------
+ // The kHighPriorityClient tries to reclaim request (after adding self)
+ // This should pass (and shouldn't be considered as a new client trying to
+ // reclaim from an existing client from same/higher priority process).
+ void testSelfReclaimResourceSecure() {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+ resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
+
+ ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = kLowPriorityClientId,
+ .name = "none"};
+ ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = kMidPriorityClientId,
+ .name = "none"};
+ // HighPriority process with client id kHighPriorityClientId.
+ ClientInfoParcel highPriorityClient1{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = kHighPriorityClientId,
+ .name = "none"};
+ // HighPriority process with client id 0xABCD.
+ ClientInfoParcel highPriorityClient2{.pid = static_cast<int32_t>(kHighPriorityPid),
+ .uid = static_cast<int32_t>(kTestUid2),
+ .id = 0xABCD,
+ .name = "none"};
+
+ addResource();
+
+ // Add a secure codec resource for the highPriorityClient1.
+ std::shared_ptr<IResourceManagerClient> testClient4 =
+ createTestClient(kHighPriorityPid, kTestUid2);
+ std::vector<MediaResourceParcel> resources1;
+ resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
+ mService->addResource(highPriorityClient1, testClient4, resources1);
+
+ // secure codecs can't coexist and secure codec can't coexist with non-secure codec.
+ updateConfig(false, false);
+
+ // priority too low
+ CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result));
+ CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result));
+
+ // highPriorityClient2 tries to reclaim SecureCodec with Graphic memory.
+ // This should fail as this process already has an instance of secure
+ // codec through testClient4.
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient2, resources, &result));
+
+ // highPriorityClient1 tries to reclaim SecureCodec with Graphic memory.
+ // This should reclaim all secure and non-secure codecs.
+ CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient1, resources, &result));
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
+
+ // Make sure there is nothing left.
+ CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient1, resources, &result));
+ }
+
void testReclaimResourceSecure() {
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
@@ -498,15 +573,15 @@
ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kLowPriorityClientId,
.name = "none"};
ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kMidPriorityClientId,
.name = "none"};
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
// ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
@@ -553,7 +628,6 @@
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result));
}
-
// ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
{
addResource();
@@ -650,15 +724,15 @@
ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kLowPriorityClientId,
.name = "none"};
ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kMidPriorityClientId,
.name = "none"};
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
// ### secure codec can't coexist with non-secure codec ###
@@ -751,8 +825,8 @@
MediaResource resource(MediaResource::Type::kGraphicMemory,
MediaResource::SubType::kUnspecifiedSubType,
1);
- ResourceRequestInfo requestInfoHigh { kHighPriorityPid, &resource};
- ResourceRequestInfo requestInfoLow { kLowPriorityPid, &resource};
+ ResourceRequestInfo requestInfoHigh { kHighPriorityPid, kHighPriorityClientId, &resource};
+ ResourceRequestInfo requestInfoLow { kLowPriorityPid, kLowPriorityClientId, &resource};
EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(requestInfoHigh, clientInfo));
addResource();
@@ -910,7 +984,7 @@
reclaimResources.push_back(createNonSecureVideoCodecResource());
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -951,7 +1025,7 @@
reclaimResources.push_back(createNonSecureAudioCodecResource());
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -992,7 +1066,7 @@
reclaimResources.push_back(createNonSecureImageCodecResource());
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -1034,7 +1108,7 @@
reclaimResources.push_back(createGraphicMemoryResource(100));
ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid),
.uid = static_cast<int32_t>(kTestUid2),
- .id = 0,
+ .id = kHighPriorityClientId,
.name = "none"};
CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, reclaimResources, &result));
@@ -1786,6 +1860,10 @@
testRemoveClient();
}
+TEST_F(ResourceManagerServiceTest, selfReclaimResource) {
+ testSelfReclaimResourceSecure();
+}
+
TEST_F(ResourceManagerServiceTest, reclaimResource) {
testReclaimResourceSecure();
testReclaimResourceNonSecure();
@@ -1873,6 +1951,10 @@
testRemoveClient();
}
+TEST_F(ResourceManagerServiceNewTest, selfReclaimResource) {
+ testSelfReclaimResourceSecure();
+}
+
TEST_F(ResourceManagerServiceNewTest, reclaimResource) {
testReclaimResourceSecure();
testReclaimResourceNonSecure();