Merge "Fix memory leak in playback time accumulation"
diff --git a/drm/OWNERS b/drm/OWNERS
index e788754..090c021 100644
--- a/drm/OWNERS
+++ b/drm/OWNERS
@@ -1 +1,3 @@
jtinker@google.com
+kelzhan@google.com
+robertshih@google.com
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index 99ff450..434246f 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -763,6 +763,43 @@
return hasQueuedWork;
}
+int SimpleC2Component::getHalPixelFormatForBitDepth10(bool allowRGBA1010102) {
+ // Save supported hal pixel formats for bit depth of 10, the first time this is called
+ if (!mBitDepth10HalPixelFormats.size()) {
+ std::vector<int> halPixelFormats;
+ // TODO(b/178229371) Enable HAL_PIXEL_FORMAT_YCBCR_P010 once framework supports it
+ // halPixelFormats.push_back(HAL_PIXEL_FORMAT_YCBCR_P010);
+
+ // since allowRGBA1010102 can chance in each call, but mBitDepth10HalPixelFormats
+ // is populated only once, allowRGBA1010102 is not considered at this stage.
+ halPixelFormats.push_back(HAL_PIXEL_FORMAT_RGBA_1010102);
+
+ for (int halPixelFormat : halPixelFormats) {
+ std::shared_ptr<C2GraphicBlock> block;
+
+ uint32_t gpuConsumerFlags = halPixelFormat == HAL_PIXEL_FORMAT_RGBA_1010102
+ ? C2AndroidMemoryUsage::HW_TEXTURE_READ
+ : 0;
+ C2MemoryUsage usage = {C2MemoryUsage::CPU_READ | gpuConsumerFlags,
+ C2MemoryUsage::CPU_WRITE};
+ // TODO(b/214411172) Use AHardwareBuffer_isSupported once it supports P010
+ c2_status_t status =
+ mOutputBlockPool->fetchGraphicBlock(320, 240, halPixelFormat, usage, &block);
+ if (status == C2_OK) {
+ mBitDepth10HalPixelFormats.push_back(halPixelFormat);
+ }
+ }
+ // Add YV12 in the end as a fall-back option
+ mBitDepth10HalPixelFormats.push_back(HAL_PIXEL_FORMAT_YV12);
+ }
+ // When RGBA1010102 is not allowed and if the first supported hal pixel is format is
+ // HAL_PIXEL_FORMAT_RGBA_1010102, then return HAL_PIXEL_FORMAT_YV12
+ if (!allowRGBA1010102 && mBitDepth10HalPixelFormats[0] == HAL_PIXEL_FORMAT_RGBA_1010102) {
+ return HAL_PIXEL_FORMAT_YV12;
+ }
+ // Return the first entry from supported formats
+ return mBitDepth10HalPixelFormats[0];
+}
std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size) {
return C2Buffer::CreateLinearBuffer(block->share(offset, size, ::C2Fence()));
diff --git a/media/codec2/components/base/include/SimpleC2Component.h b/media/codec2/components/base/include/SimpleC2Component.h
index 3b4e212..d244f45 100644
--- a/media/codec2/components/base/include/SimpleC2Component.h
+++ b/media/codec2/components/base/include/SimpleC2Component.h
@@ -167,6 +167,7 @@
static constexpr uint32_t NO_DRAIN = ~0u;
C2ReadView mDummyReadView;
+ int getHalPixelFormatForBitDepth10(bool allowRGBA1010102);
private:
const std::shared_ptr<C2ComponentInterface> mIntf;
@@ -250,6 +251,7 @@
class BlockingBlockPool;
std::shared_ptr<BlockingBlockPool> mOutputBlockPool;
+ std::vector<int> mBitDepth10HalPixelFormats;
SimpleC2Component() = delete;
};
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index ffe72dc..2ed8541 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -335,7 +335,6 @@
std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
mIntf(intfImpl),
mCodecCtx(nullptr) {
- mIsFormatR10G10B10A2Supported = IsFormatR10G10B10A2SupportedForLegacyRendering();
gettimeofday(&mTimeStart, nullptr);
gettimeofday(&mTimeEnd, nullptr);
}
@@ -633,25 +632,20 @@
IntfImpl::Lock lock = mIntf->lock();
std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects =
mIntf->getColorAspects_l();
-
+ bool allowRGBA1010102 = false;
if (codedColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
codedColorAspects->matrix == C2Color::MATRIX_BT2020 &&
codedColorAspects->transfer == C2Color::TRANSFER_ST2084) {
- if (buffer->image_format != libgav1::kImageFormatYuv420) {
+ allowRGBA1010102 = true;
+ }
+ format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
+ if ((format == HAL_PIXEL_FORMAT_RGBA_1010102) &&
+ (buffer->image_format != libgav1::kImageFormatYuv420)) {
ALOGE("Only YUV420 output is supported when targeting RGBA_1010102");
- mSignalledError = true;
- work->result = C2_OMITTED;
- work->workletsProcessed = 1u;
- return false;
- }
- // TODO (b/201787956) For devices that do not support HAL_PIXEL_FORMAT_RGBA_1010102,
- // HAL_PIXEL_FORMAT_YV12 is used as a temporary work around.
- if (!mIsFormatR10G10B10A2Supported) {
- ALOGE("HAL_PIXEL_FORMAT_RGBA_1010102 isn't supported");
- format = HAL_PIXEL_FORMAT_YV12;
- } else {
- format = HAL_PIXEL_FORMAT_RGBA_1010102;
- }
+ mSignalledError = true;
+ work->result = C2_OMITTED;
+ work->workletsProcessed = 1u;
+ return false;
}
}
C2MemoryUsage usage = {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.h b/media/codec2/components/gav1/C2SoftGav1Dec.h
index f82992d..134fa0d 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.h
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.h
@@ -82,7 +82,6 @@
struct timeval mTimeStart; // Time at the start of decode()
struct timeval mTimeEnd; // Time at the end of decode()
- bool mIsFormatR10G10B10A2Supported;
bool initDecoder();
void getVuiParams(const libgav1::DecoderBuffer *buffer);
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.cpp b/media/codec2/components/vpx/C2SoftVpxDec.cpp
index 0a27821..5fc89be 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxDec.cpp
@@ -352,7 +352,6 @@
mCodecCtx(nullptr),
mCoreCount(1),
mQueue(new Mutexed<ConversionQueue>) {
- mIsFormatR10G10B10A2Supported = IsFormatR10G10B10A2SupportedForLegacyRendering();
}
C2SoftVpxDec::~C2SoftVpxDec() {
@@ -683,19 +682,13 @@
if (img->fmt == VPX_IMG_FMT_I42016) {
IntfImpl::Lock lock = mIntf->lock();
std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects = mIntf->getDefaultColorAspects_l();
-
+ bool allowRGBA1010102 = false;
if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 &&
defaultColorAspects->matrix == C2Color::MATRIX_BT2020 &&
defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) {
- // TODO (b/201787956) For devices that do not support HAL_PIXEL_FORMAT_RGBA_1010102,
- // HAL_PIXEL_FORMAT_YV12 is used as a temporary work around.
- if (!mIsFormatR10G10B10A2Supported) {
- ALOGE("HAL_PIXEL_FORMAT_RGBA_1010102 isn't supported");
- format = HAL_PIXEL_FORMAT_YV12;
- } else {
- format = HAL_PIXEL_FORMAT_RGBA_1010102;
- }
+ allowRGBA1010102 = true;
}
+ format = getHalPixelFormatForBitDepth10(allowRGBA1010102);
}
C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16), mHeight, format, usage, &block);
diff --git a/media/codec2/components/vpx/C2SoftVpxDec.h b/media/codec2/components/vpx/C2SoftVpxDec.h
index ade162d..2065165 100644
--- a/media/codec2/components/vpx/C2SoftVpxDec.h
+++ b/media/codec2/components/vpx/C2SoftVpxDec.h
@@ -80,7 +80,7 @@
};
std::shared_ptr<Mutexed<ConversionQueue>> mQueue;
std::vector<sp<ConverterThread>> mConverterThreads;
- bool mIsFormatR10G10B10A2Supported;
+
status_t initDecoder();
status_t destroyDecoder();
void finishWork(uint64_t index, const std::unique_ptr<C2Work> &work,
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
index b761c35..bff9db5 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -118,22 +118,6 @@
} // namespace
-bool IsFormatR10G10B10A2SupportedForLegacyRendering() {
- const AHardwareBuffer_Desc desc = {
- .width = 320,
- .height = 240,
- .format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM,
- .layers = 1,
- .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN |
- AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
- .stride = 0,
- .rfu0 = 0,
- .rfu1 = 0,
- };
-
- return AHardwareBuffer_isSupported(&desc);
-}
-
status_t ImageCopy(uint8_t *imgBase, const MediaImage2 *img, const C2GraphicView &view) {
if (view.crop().width != img->mWidth || view.crop().height != img->mHeight) {
return BAD_VALUE;
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.h b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
index c4651a4..9fa642d 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.h
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.h
@@ -27,11 +27,6 @@
namespace android {
/**
- * Check if R10G10B10A2 is supported in legacy rendering path that involves GPU
- */
-bool IsFormatR10G10B10A2SupportedForLegacyRendering();
-
-/**
* Converts an RGB view to planar YUV 420 media image.
*
* \param dstY pointer to media image buffer
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index be81481..40efb38 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -834,33 +834,18 @@
aps->onNewAudioModulesAvailable();
}
-status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
- audio_policy_dev_state_t state,
- const char* device_address,
- const char* device_name,
+status_t AudioSystem::setDeviceConnectionState(audio_policy_dev_state_t state,
+ const android::media::audio::common::AudioPort& port,
audio_format_t encodedFormat) {
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- const char* address = "";
- const char* name = "";
if (aps == 0) return PERMISSION_DENIED;
- if (device_address != NULL) {
- address = device_address;
- }
- if (device_name != NULL) {
- name = device_name;
- }
-
- AudioDevice deviceAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_device_AudioDevice(device, address));
-
return statusTFromBinderStatus(
aps->setDeviceConnectionState(
- deviceAidl,
VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_policy_dev_state_t_AudioPolicyDeviceState(state)),
- name,
+ port,
VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_format_t_AudioFormatDescription(encodedFormat))));
}
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 88e7396..292d92f 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -803,6 +803,12 @@
return result.value_or(0);
}
+status_t AudioFlingerClientAdapter::setDeviceConnectedState(
+ const struct audio_port_v7 *port, bool connected) {
+ media::AudioPort aidlPort = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_v7_AudioPort(*port));
+ return statusTFromBinderStatus(mDelegate->setDeviceConnectedState(aidlPort, connected));
+}
////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
@@ -1292,4 +1298,10 @@
return Status::ok();
}
+Status AudioFlingerServerAdapter::setDeviceConnectedState(
+ const media::AudioPort& port, bool connected) {
+ audio_port_v7 portLegacy = VALUE_OR_RETURN_BINDER(aidl2legacy_AudioPort_audio_port_v7(port));
+ return Status::fromStatusT(mDelegate->setDeviceConnectedState(&portLegacy, connected));
+}
+
} // namespace android
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index c55c66e..6afe023 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -225,4 +225,6 @@
int getAAudioMixerBurstCount();
int getAAudioHardwareBurstMinUsec();
+
+ void setDeviceConnectedState(in AudioPort devicePort, boolean connected);
}
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index c3e8dfb..69328a7 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -50,6 +50,7 @@
import android.media.audio.common.AudioMode;
import android.media.audio.common.AudioProfile;
import android.media.audio.common.AudioOffloadInfo;
+import android.media.audio.common.AudioPort;
import android.media.audio.common.AudioSource;
import android.media.audio.common.AudioStreamType;
import android.media.audio.common.AudioUsage;
@@ -64,9 +65,8 @@
interface IAudioPolicyService {
oneway void onNewAudioModulesAvailable();
- void setDeviceConnectionState(in AudioDevice device,
- in AudioPolicyDeviceState state,
- @utf8InCpp String deviceName,
+ void setDeviceConnectionState(in AudioPolicyDeviceState state,
+ in android.media.audio.common.AudioPort port,
in AudioFormatDescription encodedFormat);
AudioPolicyDeviceState getDeviceConnectionState(in AudioDevice device);
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 4280a6a..e0cb47e 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -30,6 +30,7 @@
#include <android/media/ISpatializer.h>
#include <android/media/audio/common/AudioMMapPolicyInfo.h>
#include <android/media/audio/common/AudioMMapPolicyType.h>
+#include <android/media/audio/common/AudioPort.h>
#include <media/AidlConversionUtil.h>
#include <media/AudioContainers.h>
#include <media/AudioDeviceTypeAddr.h>
@@ -263,8 +264,8 @@
// IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
//
static void onNewAudioModulesAvailable();
- static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state,
- const char *device_address, const char *device_name,
+ static status_t setDeviceConnectionState(audio_policy_dev_state_t state,
+ const android::media::audio::common::AudioPort& port,
audio_format_t encodedFormat);
static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index b4ee4dc..e047378 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -358,6 +358,8 @@
virtual int32_t getAAudioMixerBurstCount() = 0;
virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
+
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
};
/**
@@ -454,14 +456,12 @@
status_t setVibratorInfos(const std::vector<media::AudioVibratorInfo>& vibratorInfos) override;
status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) override;
-
status_t getMmapPolicyInfos(
media::audio::common::AudioMMapPolicyType policyType,
std::vector<media::audio::common::AudioMMapPolicyInfo> *policyInfos) override;
-
int32_t getAAudioMixerBurstCount() override;
-
int32_t getAAudioHardwareBurstMinUsec() override;
+ status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) override;
private:
const sp<media::IAudioFlingerService> mDelegate;
@@ -550,6 +550,7 @@
GET_MMAP_POLICY_INFOS = media::BnAudioFlingerService::TRANSACTION_getMmapPolicyInfos,
GET_AAUDIO_MIXER_BURST_COUNT = media::BnAudioFlingerService::TRANSACTION_getAAudioMixerBurstCount,
GET_AAUDIO_HARDWARE_BURST_MIN_USEC = media::BnAudioFlingerService::TRANSACTION_getAAudioHardwareBurstMinUsec,
+ SET_DEVICE_CONNECTED_STATE = media::BnAudioFlingerService::TRANSACTION_setDeviceConnectedState,
};
/**
@@ -669,6 +670,7 @@
std::vector<media::audio::common::AudioMMapPolicyInfo> *_aidl_return) override;
Status getAAudioMixerBurstCount(int32_t* _aidl_return) override;
Status getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override;
+ Status setDeviceConnectedState(const media::AudioPort& port, bool connected) override;
private:
const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 8b09d76..3180b7d 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -489,6 +489,32 @@
}
#endif
+status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+ if (mDevice == 0) return NO_INIT;
+#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
+ if (supportsSetConnectedState7_1) {
+ AudioPort hidlPort;
+ if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
+ return result;
+ }
+ Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
+ if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
+ return processReturn("setConnectedState_7_1", ret);
+ } else if (ret == Result::OK) {
+ return NO_ERROR;
+ }
+ supportsSetConnectedState7_1 = false;
+ }
+#endif
+ DeviceAddress hidlAddress;
+ if (status_t result = CoreUtils::deviceAddressFromHal(
+ port->ext.device.type, port->ext.device.address, &hidlAddress);
+ result != NO_ERROR) {
+ return result;
+ }
+ return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
+}
+
status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
if (mDevice == 0) return NO_INIT;
native_handle_t* hidlHandle = native_handle_create(1, 0);
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index 104db40..cd9535e 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -132,13 +132,16 @@
return INVALID_OPERATION;
}
+ status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
+
status_t dump(int fd, const Vector<String16>& args) override;
private:
friend class DevicesFactoryHalHidl;
sp<::android::hardware::audio::CPP_VERSION::IDevice> mDevice;
- sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice> mPrimaryDevice;
// Null if it's not a primary device.
+ sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice> mPrimaryDevice;
+ bool supportsSetConnectedState7_1 = true;
// Can not be constructed directly by clients.
explicit DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device);
diff --git a/media/libaudiohal/impl/DeviceHalLocal.cpp b/media/libaudiohal/impl/DeviceHalLocal.cpp
index 1384c1e..e473e41 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.cpp
+++ b/media/libaudiohal/impl/DeviceHalLocal.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "DeviceHalLocal"
//#define LOG_NDEBUG 0
+#include <media/AudioParameter.h>
#include <utils/Log.h>
#include "DeviceHalLocal.h"
@@ -232,6 +233,14 @@
return INVALID_OPERATION;
}
+status_t DeviceHalLocal::setConnectedState(const struct audio_port_v7 *port, bool connected) {
+ AudioParameter param(String8(port->ext.device.address));
+ const String8 key(connected ?
+ AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect);
+ param.addInt(key, port->ext.device.type);
+ return setParameters(param.toString());
+}
+
status_t DeviceHalLocal::dump(int fd, const Vector<String16>& /* args */) {
return mDev->dump(mDev, fd);
}
diff --git a/media/libaudiohal/impl/DeviceHalLocal.h b/media/libaudiohal/impl/DeviceHalLocal.h
index b06e253..3e586cf 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.h
+++ b/media/libaudiohal/impl/DeviceHalLocal.h
@@ -128,6 +128,8 @@
return INVALID_OPERATION;
}
+ status_t setConnectedState(const struct audio_port_v7 *port, bool connected) override;
+
status_t dump(int fd, const Vector<String16>& args) override;
void closeOutputStream(struct audio_stream_out *stream_out);
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 70c3199..9ca7118 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -128,6 +128,9 @@
virtual int32_t getAAudioMixerBurstCount() = 0;
virtual int32_t getAAudioHardwareBurstMinUsec() = 0;
+ // Update the connection status of an external device.
+ virtual status_t setConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
+
virtual status_t dump(int fd, const Vector<String16>& args) = 0;
protected:
diff --git a/media/libmedia/MediaResource.cpp b/media/libmedia/MediaResource.cpp
index ec52a49..a6f0b60 100644
--- a/media/libmedia/MediaResource.cpp
+++ b/media/libmedia/MediaResource.cpp
@@ -43,10 +43,10 @@
}
//static
-MediaResource MediaResource::CodecResource(bool secure, bool video, int64_t instanceCount) {
+MediaResource MediaResource::CodecResource(bool secure, SubType subType, int64_t instanceCount) {
return MediaResource(
secure ? Type::kSecureCodec : Type::kNonSecureCodec,
- video ? SubType::kVideoCodec : SubType::kAudioCodec,
+ subType,
instanceCount);
}
diff --git a/media/libmedia/include/media/MediaResource.h b/media/libmedia/include/media/MediaResource.h
index 4712528..3b69d4f 100644
--- a/media/libmedia/include/media/MediaResource.h
+++ b/media/libmedia/include/media/MediaResource.h
@@ -37,7 +37,8 @@
MediaResource(Type type, SubType subType, int64_t value);
MediaResource(Type type, const std::vector<uint8_t> &id, int64_t value);
- static MediaResource CodecResource(bool secure, bool video, int64_t instanceCount = 1);
+ static MediaResource CodecResource(bool secure, MediaResourceSubType subType,
+ int64_t instanceCount = 1);
static MediaResource GraphicMemoryResource(int64_t value);
static MediaResource CpuBoostResource();
static MediaResource VideoBatteryResource();
@@ -62,6 +63,7 @@
case MediaResource::SubType::kUnspecifiedSubType: return "unspecified";
case MediaResource::SubType::kAudioCodec: return "audio-codec";
case MediaResource::SubType::kVideoCodec: return "video-codec";
+ case MediaResource::SubType::kImageCodec: return "image-codec";
default: return def;
}
}
diff --git a/media/libmediahelper/AudioValidator.cpp b/media/libmediahelper/AudioValidator.cpp
index 7eddbe1..5a0d517 100644
--- a/media/libmediahelper/AudioValidator.cpp
+++ b/media/libmediahelper/AudioValidator.cpp
@@ -47,8 +47,7 @@
const effect_descriptor_t& desc, std::string_view bugNumber)
{
status_t status = NO_ERROR;
- if (checkStringOverflow(desc.name)
- | /* always */ checkStringOverflow(desc.implementor)) {
+ if (checkStringOverflow(desc.name) || checkStringOverflow(desc.implementor)) {
status = BAD_VALUE;
}
return safetyNetLog(status, bugNumber);
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index 8c86e16..609298f 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -206,6 +206,7 @@
}
const char *mime;
+ bool isHeif = false;
if (!trackMeta->findCString(kKeyMIMEType, &mime)) {
ALOGE("image track has no mime type");
return NULL;
@@ -215,6 +216,7 @@
mime = MEDIA_MIMETYPE_VIDEO_HEVC;
trackMeta = new MetaData(*trackMeta);
trackMeta->setCString(kKeyMIMEType, mime);
+ isHeif = true;
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_AVIF)) {
mime = MEDIA_MIMETYPE_VIDEO_AV1;
trackMeta = new MetaData(*trackMeta);
@@ -240,6 +242,16 @@
format->setInt32("width", thumbWidth);
}
+ // If decoding tiled HEIF check decoder supports tile dimensions instead
+ if (!thumbnail && isHeif && format != NULL) {
+ int32_t tileWidth, tileHeight;
+ if (trackMeta->findInt32(kKeyTileWidth, &tileWidth) && tileWidth > 0
+ && trackMeta->findInt32(kKeyTileHeight, &tileHeight) && tileHeight > 0) {
+ format->setInt32("height", tileHeight);
+ format->setInt32("width", tileWidth);
+ }
+ }
+
MediaCodecList::findMatchingCodecs(
mime,
false, /* encoder */
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index a0c8f8a..f81a5eb 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -4448,30 +4448,31 @@
memset(&aspects, 0, sizeof(aspects));
// Color metadata may have changed.
sp<MetaData> meta = mSource->getFormat();
- // TRICKY: using | instead of || because we want to execute all findInt32-s
- if (meta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries)
- | meta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer)
- | meta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs)
- | meta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) {
- int32_t primaries, transfer, coeffs;
- bool fullRange;
- ALOGV("primaries=%s transfer=%s matrix=%s range=%s",
- asString(aspects.mPrimaries),
- asString(aspects.mTransfer),
- asString(aspects.mMatrixCoeffs),
- asString(aspects.mRange));
- ColorUtils::convertCodecColorAspectsToIsoAspects(
- aspects, &primaries, &transfer, &coeffs, &fullRange);
- mOwner->beginBox("colr");
- mOwner->writeFourcc("nclx");
- mOwner->writeInt16(primaries);
- mOwner->writeInt16(transfer);
- mOwner->writeInt16(coeffs);
- mOwner->writeInt8(int8_t(fullRange ? 0x80 : 0x0));
- mOwner->endBox(); // colr
- } else {
+ bool findPrimaries = meta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries);
+ bool findTransfer = meta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer);
+ bool findMatrix = meta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs);
+ bool findRange = meta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange);
+ if (!findPrimaries && !findTransfer && !findMatrix && !findRange) {
ALOGV("no color information");
+ return;
}
+
+ int32_t primaries, transfer, coeffs;
+ bool fullRange;
+ ALOGV("primaries=%s transfer=%s matrix=%s range=%s",
+ asString(aspects.mPrimaries),
+ asString(aspects.mTransfer),
+ asString(aspects.mMatrixCoeffs),
+ asString(aspects.mRange));
+ ColorUtils::convertCodecColorAspectsToIsoAspects(
+ aspects, &primaries, &transfer, &coeffs, &fullRange);
+ mOwner->beginBox("colr");
+ mOwner->writeFourcc("nclx");
+ mOwner->writeInt16(primaries);
+ mOwner->writeInt16(transfer);
+ mOwner->writeInt16(coeffs);
+ mOwner->writeInt8(int8_t(fullRange ? 0x80 : 0x0));
+ mOwner->endBox(); // colr
}
void MPEG4Writer::Track::writeMdcvAndClliBoxes() {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e9dcb26..c0e69d2 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -102,6 +102,8 @@
static const char *kCodecMode = "android.media.mediacodec.mode"; /* audio, video */
static const char *kCodecModeVideo = "video"; /* values returned for kCodecMode */
static const char *kCodecModeAudio = "audio";
+static const char *kCodecModeImage = "image";
+static const char *kCodecModeUnknown = "unknown";
static const char *kCodecEncoder = "android.media.mediacodec.encoder"; /* 0,1 */
static const char *kCodecSecure = "android.media.mediacodec.secure"; /* 0, 1 */
static const char *kCodecWidth = "android.media.mediacodec.width"; /* 0..n */
@@ -656,6 +658,24 @@
notify->post();
}
+static MediaResourceSubType toMediaResourceSubType(MediaCodec::Domain domain) {
+ switch (domain) {
+ case MediaCodec::DOMAIN_VIDEO: return MediaResourceSubType::kVideoCodec;
+ case MediaCodec::DOMAIN_AUDIO: return MediaResourceSubType::kAudioCodec;
+ case MediaCodec::DOMAIN_IMAGE: return MediaResourceSubType::kImageCodec;
+ default: return MediaResourceSubType::kUnspecifiedSubType;
+ }
+}
+
+static const char * toCodecMode(MediaCodec::Domain domain) {
+ switch (domain) {
+ case MediaCodec::DOMAIN_VIDEO: return kCodecModeVideo;
+ case MediaCodec::DOMAIN_AUDIO: return kCodecModeAudio;
+ case MediaCodec::DOMAIN_IMAGE: return kCodecModeImage;
+ default: return kCodecModeUnknown;
+ }
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -751,9 +771,9 @@
mFlags(0),
mStickyError(OK),
mSoftRenderer(NULL),
- mIsVideo(false),
- mVideoWidth(0),
- mVideoHeight(0),
+ mDomain(DOMAIN_UNKNOWN),
+ mWidth(0),
+ mHeight(0),
mRotationDegrees(0),
mHDRMetadataFlags(0),
mDequeueInputTimeoutGeneration(0),
@@ -1165,7 +1185,7 @@
});
}
- if (mIsVideo && (mFlags & kFlagIsEncoder)) {
+ if (mDomain == DOMAIN_VIDEO && (mFlags & kFlagIsEncoder)) {
mBytesInput += buffer->size();
mFramesInput++;
}
@@ -1194,7 +1214,7 @@
CHECK_NE(mState, UNINITIALIZED);
- if (mIsVideo && (mFlags & kFlagIsEncoder)) {
+ if (mDomain == DOMAIN_VIDEO && (mFlags & kFlagIsEncoder)) {
int32_t flags = 0;
(void) buffer->meta()->findInt32("flags", &flags);
@@ -1402,7 +1422,13 @@
mCodecInfo->getSupportedMediaTypes(&mediaTypes);
for (size_t i = 0; i < mediaTypes.size(); ++i) {
if (mediaTypes[i].startsWith("video/")) {
- mIsVideo = true;
+ mDomain = DOMAIN_VIDEO;
+ break;
+ } else if (mediaTypes[i].startsWith("audio/")) {
+ mDomain = DOMAIN_AUDIO;
+ break;
+ } else if (mediaTypes[i].startsWith("image/")) {
+ mDomain = DOMAIN_IMAGE;
break;
}
}
@@ -1415,7 +1441,7 @@
return NAME_NOT_FOUND;
}
- if (mIsVideo) {
+ if (mDomain == DOMAIN_VIDEO) {
// video codec needs dedicated looper
if (mCodecLooper == NULL) {
mCodecLooper = new ALooper;
@@ -1448,17 +1474,16 @@
if (mMetricsHandle != 0) {
mediametrics_setCString(mMetricsHandle, kCodecCodec, name.c_str());
- mediametrics_setCString(mMetricsHandle, kCodecMode,
- mIsVideo ? kCodecModeVideo : kCodecModeAudio);
+ mediametrics_setCString(mMetricsHandle, kCodecMode, toCodecMode(mDomain));
}
- if (mIsVideo) {
+ if (mDomain == DOMAIN_VIDEO) {
mBatteryChecker = new BatteryChecker(new AMessage(kWhatCheckBatteryStats, this));
}
status_t err;
std::vector<MediaResourceParcel> resources;
- resources.push_back(MediaResource::CodecResource(secureCodec, mIsVideo));
+ resources.push_back(MediaResource::CodecResource(secureCodec, toMediaResourceSubType(mDomain)));
for (int i = 0; i <= kMaxRetry; ++i) {
if (i > 0) {
// Don't try to reclaim resource for the first time.
@@ -1539,16 +1564,16 @@
mediametrics_setCString(mMetricsHandle, kCodecLogSessionId, mLogSessionId.c_str());
}
- if (mIsVideo) {
- format->findInt32("width", &mVideoWidth);
- format->findInt32("height", &mVideoHeight);
+ if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) {
+ format->findInt32("width", &mWidth);
+ format->findInt32("height", &mHeight);
if (!format->findInt32("rotation-degrees", &mRotationDegrees)) {
mRotationDegrees = 0;
}
if (mMetricsHandle != 0) {
- mediametrics_setInt32(mMetricsHandle, kCodecWidth, mVideoWidth);
- mediametrics_setInt32(mMetricsHandle, kCodecHeight, mVideoHeight);
+ mediametrics_setInt32(mMetricsHandle, kCodecWidth, mWidth);
+ mediametrics_setInt32(mMetricsHandle, kCodecHeight, mHeight);
mediametrics_setInt32(mMetricsHandle, kCodecRotation, mRotationDegrees);
int32_t maxWidth = 0;
if (format->findInt32("max-width", &maxWidth)) {
@@ -1562,21 +1587,23 @@
if (format->findInt32("color-format", &colorFormat)) {
mediametrics_setInt32(mMetricsHandle, kCodecColorFormat, colorFormat);
}
- float frameRate = -1.0;
- if (format->findFloat("frame-rate", &frameRate)) {
- mediametrics_setDouble(mMetricsHandle, kCodecFrameRate, frameRate);
- }
- float captureRate = -1.0;
- if (format->findFloat("capture-rate", &captureRate)) {
- mediametrics_setDouble(mMetricsHandle, kCodecCaptureRate, captureRate);
- }
- float operatingRate = -1.0;
- if (format->findFloat("operating-rate", &operatingRate)) {
- mediametrics_setDouble(mMetricsHandle, kCodecOperatingRate, operatingRate);
- }
- int32_t priority = -1;
- if (format->findInt32("priority", &priority)) {
- mediametrics_setInt32(mMetricsHandle, kCodecPriority, priority);
+ if (mDomain == DOMAIN_VIDEO) {
+ float frameRate = -1.0;
+ if (format->findFloat("frame-rate", &frameRate)) {
+ mediametrics_setDouble(mMetricsHandle, kCodecFrameRate, frameRate);
+ }
+ float captureRate = -1.0;
+ if (format->findFloat("capture-rate", &captureRate)) {
+ mediametrics_setDouble(mMetricsHandle, kCodecCaptureRate, captureRate);
+ }
+ float operatingRate = -1.0;
+ if (format->findFloat("operating-rate", &operatingRate)) {
+ mediametrics_setDouble(mMetricsHandle, kCodecOperatingRate, operatingRate);
+ }
+ int32_t priority = -1;
+ if (format->findInt32("priority", &priority)) {
+ mediametrics_setInt32(mMetricsHandle, kCodecPriority, priority);
+ }
}
int32_t colorStandard = -1;
if (format->findInt32(KEY_COLOR_STANDARD, &colorStandard)) {
@@ -1598,9 +1625,9 @@
}
// Prevent possible integer overflow in downstream code.
- if (mVideoWidth < 0 || mVideoHeight < 0 ||
- (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
- ALOGE("Invalid size(s), width=%d, height=%d", mVideoWidth, mVideoHeight);
+ if (mWidth < 0 || mHeight < 0 ||
+ (uint64_t)mWidth * mHeight > (uint64_t)INT32_MAX / 4) {
+ ALOGE("Invalid size(s), width=%d, height=%d", mWidth, mHeight);
return BAD_VALUE;
}
@@ -1633,7 +1660,7 @@
}
// push min/max QP to MediaMetrics after shaping
- if (mIsVideo && mMetricsHandle != 0) {
+ if (mDomain == DOMAIN_VIDEO && mMetricsHandle != 0) {
int32_t qpIMin = -1;
if (format->findInt32("video-qp-i-min", &qpIMin)) {
mediametrics_setInt32(mMetricsHandle, kCodecRequestedVideoQPIMin, qpIMin);
@@ -1686,7 +1713,8 @@
status_t err;
std::vector<MediaResourceParcel> resources;
- resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
+ resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
+ toMediaResourceSubType(mDomain)));
// Don't know the buffer size at this point, but it's fine to use 1 because
// the reclaimResource call doesn't consider the requester's buffer size for now.
resources.push_back(MediaResource::GraphicMemoryResource(1));
@@ -2267,7 +2295,7 @@
}
uint64_t MediaCodec::getGraphicBufferSize() {
- if (!mIsVideo) {
+ if (mDomain != DOMAIN_VIDEO && mDomain != DOMAIN_IMAGE) {
return 0;
}
@@ -2275,7 +2303,7 @@
size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
for (size_t i = 0; i < portNum; ++i) {
// TODO: this is just an estimation, we should get the real buffer size from ACodec.
- size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
+ size += mPortBuffers[i].size() * mWidth * mHeight * 3 / 2;
}
return size;
}
@@ -2287,7 +2315,8 @@
status_t err;
std::vector<MediaResourceParcel> resources;
- resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
+ resources.push_back(MediaResource::CodecResource(mFlags & kFlagIsSecure,
+ toMediaResourceSubType(mDomain)));
// Don't know the buffer size at this point, but it's fine to use 1 because
// the reclaimResource call doesn't consider the requester's buffer size for now.
resources.push_back(MediaResource::GraphicMemoryResource(1));
@@ -3219,8 +3248,8 @@
: MediaCodecInfo::Attributes(0);
if (!(attr & MediaCodecInfo::kFlagIsSoftwareOnly)) {
// software codec is currently ignored.
- mResourceManagerProxy->addResource(
- MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
+ mResourceManagerProxy->addResource(MediaResource::CodecResource(
+ mFlags & kFlagIsSecure, toMediaResourceSubType(mDomain)));
}
postPendingRepliesAndDeferredMessages("kWhatComponentAllocated");
@@ -3386,7 +3415,7 @@
}
CHECK_EQ(mState, STARTING);
- if (mIsVideo) {
+ if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) {
mResourceManagerProxy->addResource(
MediaResource::GraphicMemoryResource(getGraphicBufferSize()));
}
diff --git a/media/libstagefright/foundation/ColorUtils.cpp b/media/libstagefright/foundation/ColorUtils.cpp
index a5affb9..6dc8157 100644
--- a/media/libstagefright/foundation/ColorUtils.cpp
+++ b/media/libstagefright/foundation/ColorUtils.cpp
@@ -590,9 +590,10 @@
uint32_t gfxRange = range;
uint32_t gfxStandard = standard;
uint32_t gfxTransfer = transfer;
- // TRICKY: use & to ensure all three mappings are completed
- if (!(sGfxRanges.map(range, &gfxRange) & sGfxStandards.map(standard, &gfxStandard)
- & sGfxTransfers.map(transfer, &gfxTransfer))) {
+ bool mappedRange = sGfxRanges.map(range, &gfxRange);
+ bool mappedStandard = sGfxStandards.map(standard, &gfxStandard);
+ bool mappedTransfer = sGfxTransfers.map(transfer, &gfxTransfer);
+ if (! (mappedRange && mappedStandard && mappedTransfer)) {
ALOGW("could not safely map platform color aspects (R:%u(%s) S:%u(%s) T:%u(%s) to "
"graphics dataspace (R:%u S:%u T:%u)",
range, asString(range), standard, asString(standard), transfer, asString(transfer),
@@ -626,9 +627,10 @@
CU::ColorRange cuRange = CU::kColorRangeUnspecified;
CU::ColorStandard cuStandard = CU::kColorStandardUnspecified;
CU::ColorTransfer cuTransfer = CU::kColorTransferUnspecified;
- // TRICKY: use & to ensure all three mappings are completed
- if (!(sGfxRanges.map(gfxRange, &cuRange) & sGfxStandards.map(gfxStandard, &cuStandard)
- & sGfxTransfers.map(gfxTransfer, &cuTransfer))) {
+ bool mappedRange = sGfxRanges.map(gfxRange, &cuRange);
+ bool mappedStandard = sGfxStandards.map(gfxStandard, &cuStandard);
+ bool mappedTransfer = sGfxTransfers.map(gfxTransfer, &cuTransfer);
+ if (! (mappedRange && mappedStandard && mappedTransfer)) {
ALOGW("could not safely map graphics dataspace (R:%u S:%u T:%u) to "
"platform color aspects (R:%u(%s) S:%u(%s) T:%u(%s)",
gfxRange, gfxStandard, gfxTransfer,
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index b9a3197..29a87e9 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -70,6 +70,13 @@
using aidl::android::media::MediaResourceParcel;
struct MediaCodec : public AHandler {
+ enum Domain {
+ DOMAIN_UNKNOWN = 0,
+ DOMAIN_VIDEO = 1,
+ DOMAIN_AUDIO = 2,
+ DOMAIN_IMAGE = 3
+ };
+
enum ConfigureFlags {
CONFIGURE_FLAG_ENCODE = 1,
CONFIGURE_FLAG_USE_BLOCK_MODEL = 2,
@@ -438,10 +445,10 @@
sp<ResourceManagerServiceProxy> mResourceManagerProxy;
- bool mIsVideo;
+ Domain mDomain;
AString mLogSessionId;
- int32_t mVideoWidth;
- int32_t mVideoHeight;
+ int32_t mWidth;
+ int32_t mHeight;
int32_t mRotationDegrees;
int32_t mAllowFrameDroppingBySurface;
diff --git a/media/libwatchdog/Android.bp b/media/libwatchdog/Android.bp
index 411c206..5506a73 100644
--- a/media/libwatchdog/Android.bp
+++ b/media/libwatchdog/Android.bp
@@ -39,7 +39,7 @@
darwin: {
enabled: false,
},
- linux_glibc: {
+ glibc: {
cflags: [
"-Dsigev_notify_thread_id=_sigev_un._tid",
],
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 43f79ce..5b53331 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -386,6 +386,24 @@
return mAAudioHwBurstMinMicros;
}
+status_t AudioFlinger::setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) {
+ status_t final_result = NO_INIT;
+ Mutex::Autolock _l(mLock);
+ AutoMutex lock(mHardwareLock);
+ mHardwareStatus = AUDIO_HW_SET_CONNECTED_STATE;
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
+ status_t result = dev->setConnectedState(port, connected);
+ // Same logic as with setParameter: it's a success if at least one
+ // HAL module accepts the update.
+ if (final_result != NO_ERROR) {
+ final_result = result;
+ }
+ }
+ mHardwareStatus = AUDIO_HW_IDLE;
+ return final_result;
+}
+
// getDefaultVibratorInfo_l must be called with AudioFlinger lock held.
std::optional<media::AudioVibratorInfo> AudioFlinger::getDefaultVibratorInfo_l() {
if (mAudioVibratorInfos.empty()) {
@@ -4334,6 +4352,7 @@
case TransactionCode::SET_AUDIO_PORT_CONFIG:
case TransactionCode::SET_RECORD_SILENCED:
case TransactionCode::AUDIO_POLICY_READY:
+ case TransactionCode::SET_DEVICE_CONNECTED_STATE:
ALOGW("%s: transaction %d received from PID %d",
__func__, code, IPCThreadState::self()->getCallingPid());
// return status only for non void methods
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 8c546cc..59f22eb 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -290,6 +290,8 @@
virtual int32_t getAAudioHardwareBurstMinUsec();
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected);
+
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
const std::function<status_t()>& delegate) override;
@@ -912,6 +914,7 @@
AUDIO_HW_SET_MASTER_MUTE, // set_master_mute
AUDIO_HW_GET_MASTER_MUTE, // get_master_mute
AUDIO_HW_GET_MICROPHONES, // getMicrophones
+ AUDIO_HW_SET_CONNECTED_STATE, // setConnectedState
};
mutable hardware_call_state mHardwareStatus; // for dump only
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index e8e478b..5b2b87e 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -105,10 +105,8 @@
virtual void onNewAudioModulesAvailable() = 0;
// indicate a change in device connection status
- virtual status_t setDeviceConnectionState(audio_devices_t device,
- audio_policy_dev_state_t state,
- const char *device_address,
- const char *device_name,
+ virtual status_t setDeviceConnectionState(audio_policy_dev_state_t state,
+ const android::media::audio::common::AudioPort& port,
audio_format_t encodedFormat) = 0;
// retrieve a device connection status
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
@@ -546,6 +544,8 @@
virtual status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) = 0;
+
+ virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
};
// These are the signatures of createAudioPolicyManager/destroyAudioPolicyManager
diff --git a/services/audiopolicy/managerdefault/Android.bp b/services/audiopolicy/managerdefault/Android.bp
index 0165dc8..4b4817e 100644
--- a/services/audiopolicy/managerdefault/Android.bp
+++ b/services/audiopolicy/managerdefault/Android.bp
@@ -36,6 +36,8 @@
"libaudiopolicyenginedefault",
"framework-permission-aidl-cpp",
"libaudioclient_aidl_conversion",
+ "android.media.audio.common.types-V1-cpp",
+ "audioclient-types-aidl-cpp",
],
header_libs: [
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index bd295ce..cc36c08 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -38,6 +38,7 @@
#include <vector>
#include <Serializer.h>
+#include <android/media/audio/common/AudioPort.h>
#include <cutils/bitops.h>
#include <cutils/properties.h>
#include <media/AudioParameter.h>
@@ -53,6 +54,10 @@
namespace android {
+using android::media::audio::common::AudioDevice;
+using android::media::audio::common::AudioDeviceAddress;
+using android::media::audio::common::AudioPortDeviceExt;
+using android::media::audio::common::AudioPortExt;
using content::AttributionSourceState;
//FIXME: workaround for truncated touch sounds
@@ -97,44 +102,80 @@
// AudioPolicyInterface implementation
// ----------------------------------------------------------------------------
-status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
- audio_policy_dev_state_t state,
- const char *device_address,
- const char *device_name,
- audio_format_t encodedFormat)
-{
- status_t status = setDeviceConnectionStateInt(device, state, device_address,
- device_name, encodedFormat);
+status_t AudioPolicyManager::setDeviceConnectionState(audio_policy_dev_state_t state,
+ const android::media::audio::common::AudioPort& port, audio_format_t encodedFormat) {
+ status_t status = setDeviceConnectionStateInt(state, port, encodedFormat);
nextAudioPortGeneration();
return status;
}
+status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
+ audio_policy_dev_state_t state,
+ const char* device_address,
+ const char* device_name,
+ audio_format_t encodedFormat) {
+ media::AudioPort aidlPort;
+ if (status_t status = deviceToAudioPort(device, device_address, device_name, &aidlPort);
+ status == OK) {
+ return setDeviceConnectionState(state, aidlPort.hal, encodedFormat);
+ } else {
+ ALOGE("Failed to convert to AudioPort Parcelable: %s", statusToString(status).c_str());
+ return status;
+ }
+}
+
void AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
audio_policy_dev_state_t state)
{
- AudioParameter param(String8(device->address().c_str()));
- const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
- AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect);
- param.addInt(key, device->type());
- mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
+ audio_port_v7 devicePort;
+ device->toAudioPort(&devicePort);
+ if (status_t status = mpClientInterface->setDeviceConnectedState(
+ &devicePort, state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
+ status != OK) {
+ ALOGE("Error %d while setting connected state for device %s", status,
+ device->getDeviceTypeAddr().toString(false).c_str());
+ }
+}
+
+status_t AudioPolicyManager::setDeviceConnectionStateInt(
+ audio_policy_dev_state_t state, const android::media::audio::common::AudioPort& port,
+ audio_format_t encodedFormat) {
+ // TODO: b/211601178 Forward 'port' to Audio HAL via mHwModules. For now, only device_type,
+ // device_address and device_name are forwarded.
+ if (port.ext.getTag() != AudioPortExt::device) {
+ return BAD_VALUE;
+ }
+ audio_devices_t device_type;
+ std::string device_address;
+ if (status_t status = aidl2legacy_AudioDevice_audio_device(
+ port.ext.get<AudioPortExt::device>().device, &device_type, &device_address);
+ status != OK) {
+ return status;
+ };
+ const char* device_name = port.name.c_str();
+ // connect/disconnect only 1 device at a time
+ if (!audio_is_output_device(device_type) && !audio_is_input_device(device_type))
+ return BAD_VALUE;
+
+ sp<DeviceDescriptor> device = mHwModules.getDeviceDescriptor(
+ device_type, device_address.c_str(), device_name, encodedFormat,
+ state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
+ return device ? setDeviceConnectionStateInt(device, state) : INVALID_OPERATION;
}
status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
- const char *device_address,
- const char *device_name,
- audio_format_t encodedFormat)
-{
- ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s format 0x%X",
- deviceType, state, device_address, device_name, encodedFormat);
-
- // connect/disconnect only 1 device at a time
- if (!audio_is_output_device(deviceType) && !audio_is_input_device(deviceType)) return BAD_VALUE;
-
- sp<DeviceDescriptor> device =
- mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
- state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
- return device ? setDeviceConnectionStateInt(device, state) : INVALID_OPERATION;
+ const char* device_address,
+ const char* device_name,
+ audio_format_t encodedFormat) {
+ media::AudioPort aidlPort;
+ if (status_t status = deviceToAudioPort(deviceType, device_address, device_name, &aidlPort);
+ status == OK) {
+ return setDeviceConnectionStateInt(state, aidlPort.hal, encodedFormat);
+ } else {
+ ALOGE("Failed to convert to AudioPort Parcelable: %s", statusToString(status).c_str());
+ return status;
+ }
}
status_t AudioPolicyManager::setDeviceConnectionStateInt(const sp<DeviceDescriptor> &device,
@@ -399,6 +440,14 @@
return BAD_VALUE;
}
+status_t AudioPolicyManager::deviceToAudioPort(audio_devices_t device, const char* device_address,
+ const char* device_name,
+ media::AudioPort* aidlPort) {
+ DeviceDescriptorBase devDescr(device, device_address);
+ devDescr.setName(device_name);
+ return devDescr.writeToParcelable(aidlPort);
+}
+
void AudioPolicyManager::setEngineDeviceConnectionState(const sp<DeviceDescriptor> device,
audio_policy_dev_state_t state) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 165ac13..a145c70 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -35,6 +35,7 @@
#include <media/PatchBuilder.h>
#include "AudioPolicyInterface.h"
+#include <android/media/audio/common/AudioPort.h>
#include <AudioPolicyManagerObserver.h>
#include <AudioPolicyConfig.h>
#include <PolicyAudioPort.h>
@@ -95,11 +96,8 @@
virtual ~AudioPolicyManager();
// AudioPolicyInterface
- virtual status_t setDeviceConnectionState(audio_devices_t device,
- audio_policy_dev_state_t state,
- const char *device_address,
- const char *device_name,
- audio_format_t encodedFormat);
+ virtual status_t setDeviceConnectionState(audio_policy_dev_state_t state,
+ const android::media::audio::common::AudioPort& port, audio_format_t encodedFormat);
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
virtual status_t handleDeviceConfigChange(audio_devices_t device,
@@ -911,6 +909,16 @@
PatchBuilder buildMsdPatch(bool msdIsSource, const sp<DeviceDescriptor> &device) const;
status_t setMsdOutputPatches(const DeviceVector *outputDevices = nullptr);
void releaseMsdOutputPatches(const DeviceVector& devices);
+
+ // Overload of setDeviceConnectionState()
+ status_t setDeviceConnectionState(audio_devices_t deviceType,
+ audio_policy_dev_state_t state,
+ const char* device_address, const char* device_name,
+ audio_format_t encodedFormat);
+
+ // Called by setDeviceConnectionState()
+ status_t deviceToAudioPort(audio_devices_t deviceType, const char* device_address,
+ const char* device_name, media::AudioPort* aidPort);
private:
void onNewAudioModulesAvailableInt(DeviceVector *newDevices);
@@ -1030,6 +1038,9 @@
bool isValidAttributes(const audio_attributes_t *paa);
// Called by setDeviceConnectionState().
+ status_t setDeviceConnectionStateInt(audio_policy_dev_state_t state,
+ const android::media::audio::common::AudioPort& port,
+ audio_format_t encodedFormat);
status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
const char *device_address,
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index aaf6fba..63a1e71 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -307,4 +307,15 @@
return af->updateSecondaryOutputs(trackSecondaryOutputs);
}
+status_t AudioPolicyService::AudioPolicyClient::setDeviceConnectedState(
+ const struct audio_port_v7 *port, bool connected) {
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == nullptr) {
+ ALOGW("%s: could not get AudioFlinger", __func__);
+ return PERMISSION_DENIED;
+ }
+ return af->setDeviceConnectedState(port, connected);
+}
+
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 87a350f..582c048 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -119,14 +119,9 @@
}
Status AudioPolicyService::setDeviceConnectionState(
- const AudioDevice& deviceAidl,
media::AudioPolicyDeviceState stateAidl,
- const std::string& deviceNameAidl,
+ const android::media::audio::common::AudioPort& port,
const AudioFormatDescription& encodedFormatAidl) {
- audio_devices_t device;
- std::string address;
- RETURN_BINDER_STATUS_IF_ERROR(
- aidl2legacy_AudioDevice_audio_device(deviceAidl, &device, &address));
audio_policy_dev_state_t state = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioPolicyDeviceState_audio_policy_dev_state_t(stateAidl));
audio_format_t encodedFormat = VALUE_OR_RETURN_BINDER_STATUS(
@@ -147,7 +142,7 @@
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
status_t status = mAudioPolicyManager->setDeviceConnectionState(
- device, state, address.c_str(), deviceNameAidl.c_str(), encodedFormat);
+ state, port, encodedFormat);
if (status == NO_ERROR) {
onCheckSpatializer_l();
}
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index ac5af6b..39f2c97 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -82,9 +82,8 @@
//
binder::Status onNewAudioModulesAvailable() override;
binder::Status setDeviceConnectionState(
- const AudioDevice& device,
media::AudioPolicyDeviceState state,
- const std::string& deviceName,
+ const android::media::audio::common::AudioPort& port,
const AudioFormatDescription& encodedFormat) override;
binder::Status getDeviceConnectionState(const AudioDevice& device,
media::AudioPolicyDeviceState* _aidl_return) override;
@@ -808,6 +807,9 @@
status_t updateSecondaryOutputs(
const TrackSecondaryOutputsMap& trackSecondaryOutputs) override;
+ status_t setDeviceConnectedState(
+ const struct audio_port_v7 *port, bool connected) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index 8fbe8b2..2e220bc 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -31,7 +31,7 @@
static_libs: [
"libaudiopolicycomponents",
- "libgmock"
+ "libgmock",
],
header_libs: [
@@ -65,6 +65,12 @@
"liblog",
"libmedia_helper",
"libutils",
+ "android.media.audio.common.types-V1-cpp",
+ "libaudioclient_aidl_conversion",
+ "libstagefright_foundation",
+ "libshmemcompat",
+ "libshmemutil",
+ "audioclient-types-aidl-cpp",
],
static_libs: ["libaudiopolicycomponents"],
diff --git a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
index 84b40d2..adef8f1 100644
--- a/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyManagerTestClient.h
@@ -103,6 +103,11 @@
++mAudioPortListUpdateCount;
}
+ status_t setDeviceConnectedState(
+ const struct audio_port_v7 *port __unused, bool connected __unused) override {
+ return NO_ERROR;
+ }
+
// Helper methods for tests
size_t getActivePatchesCount() const { return mActivePatches.size(); }
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 4e0735b..da85658 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -96,6 +96,10 @@
const TrackSecondaryOutputsMap& trackSecondaryOutputs __unused) override {
return NO_INIT;
}
+ status_t setDeviceConnectedState(
+ const struct audio_port_v7 *port __unused, bool connected __unused) override {
+ return NO_INIT;
+ }
};
} // namespace android
diff --git a/services/audiopolicy/tests/AudioPolicyTestManager.h b/services/audiopolicy/tests/AudioPolicyTestManager.h
index ff06937..7441f20 100644
--- a/services/audiopolicy/tests/AudioPolicyTestManager.h
+++ b/services/audiopolicy/tests/AudioPolicyTestManager.h
@@ -35,6 +35,8 @@
using AudioPolicyManager::getAudioPatches;
using AudioPolicyManager::getDirectPlaybackSupport;
using AudioPolicyManager::getDirectProfilesForAttributes;
+ using AudioPolicyManager::setDeviceConnectionState;
+ using AudioPolicyManager::deviceToAudioPort;
uint32_t getAudioPortGeneration() const { return mAudioPortGeneration; }
};
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index df4389b..10f8dc0 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -111,16 +111,17 @@
continue;
}
std::string address = "11:22:33:44:55:66";
+ media::AudioPort aidlPort;
+ ASSERT_EQ(OK, manager.deviceToAudioPort(device->type(), address.c_str(), "" /*name*/,
+ &aidlPort));
ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
ASSERT_EQ(NO_ERROR, AudioSystem::setDeviceConnectionState(
- device->type(), AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.c_str(),
- "" /*device_name*/, AUDIO_FORMAT_DEFAULT));
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE, aidlPort.hal, AUDIO_FORMAT_DEFAULT));
ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
ASSERT_EQ(NO_ERROR, AudioSystem::setDeviceConnectionState(
- device->type(), AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(),
- "" /*device_name*/, AUDIO_FORMAT_DEFAULT));
+ AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, aidlPort.hal, AUDIO_FORMAT_DEFAULT));
ASSERT_EQ(AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
AudioSystem::getDeviceConnectionState(device->type(), address.c_str()));
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 9b0d0e7..efbae47 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1763,7 +1763,7 @@
bool isCompositeStream = false;
for (const auto& gbp : mConfiguredOutputs.valueAt(index).getGraphicBufferProducers()) {
sp<Surface> s = new Surface(gbp, false /*controlledByApp*/);
- isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) |
+ isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) ||
camera3::HeicCompositeStream::isHeicCompositeStream(s);
if (isCompositeStream) {
auto compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp));
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 69723b6..98cbbcf 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -581,7 +581,7 @@
mHandoutTotalBufferCount = 0;
mFrameCount = 0;
mLastTimestamp = 0;
- mUseMonoTimestamp = (isConsumedByHWComposer() | isVideoStream());
+ mUseMonoTimestamp = (isConsumedByHWComposer() || isVideoStream());
res = native_window_set_buffer_count(mConsumer.get(),
mTotalBufferCount);
diff --git a/services/mediaresourcemanager/IMediaResourceMonitor.h b/services/mediaresourcemanager/IMediaResourceMonitor.h
index f92d557..4dd87e1 100644
--- a/services/mediaresourcemanager/IMediaResourceMonitor.h
+++ b/services/mediaresourcemanager/IMediaResourceMonitor.h
@@ -32,6 +32,7 @@
enum {
TYPE_VIDEO_CODEC = 0,
TYPE_AUDIO_CODEC = 1,
+ TYPE_IMAGE_CODEC = 2,
};
virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type) = 0;
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 953686b..d50f8d5 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -51,8 +51,8 @@
class DeathNotifier : public RefBase {
public:
- DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
- int pid, int64_t clientId);
+ DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid,
+ int64_t clientId);
virtual ~DeathNotifier() {}
@@ -130,27 +130,48 @@
return itemsStr;
}
-static bool hasResourceType(MediaResource::Type type, const ResourceList& resources) {
+static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+ MediaResourceParcel resource) {
+ if (type != resource.type) {
+ return false;
+ }
+ switch (type) {
+ // Codec subtypes (e.g. video vs. audio) are each considered separate resources, so
+ // compare the subtypes as well.
+ case MediaResource::Type::kSecureCodec:
+ case MediaResource::Type::kNonSecureCodec:
+ if (resource.subType == subType) {
+ return true;
+ }
+ break;
+ // Non-codec resources are not segregated by the subtype (e.g. video vs. audio).
+ default:
+ return true;
+ }
+ return false;
+}
+
+static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+ const ResourceList& resources) {
for (auto it = resources.begin(); it != resources.end(); it++) {
- if (it->second.type == type) {
+ if (hasResourceType(type, subType, it->second)) {
return true;
}
}
return false;
}
-static bool hasResourceType(MediaResource::Type type, const ResourceInfos& infos) {
+static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
+ const ResourceInfos& infos) {
for (size_t i = 0; i < infos.size(); ++i) {
- if (hasResourceType(type, infos[i].resources)) {
+ if (hasResourceType(type, subType, infos[i].resources)) {
return true;
}
}
return false;
}
-static ResourceInfos& getResourceInfosForEdit(
- int pid,
- PidResourceInfosMap& map) {
+static ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) {
ssize_t index = map.indexOfKey(pid);
if (index < 0) {
// new pid
@@ -161,11 +182,8 @@
return map.editValueFor(pid);
}
-static ResourceInfo& getResourceInfoForEdit(
- uid_t uid,
- int64_t clientId,
- const std::shared_ptr<IResourceManagerClient>& client,
- ResourceInfos& infos) {
+static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId,
+ const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) {
ssize_t index = infos.indexOfKey(clientId);
if (index < 0) {
@@ -188,17 +206,24 @@
if (binder != NULL) {
sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder);
for (size_t i = 0; i < resources.size(); ++i) {
- if (resources[i].subType == MediaResource::SubType::kAudioCodec) {
- service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
- } else if (resources[i].subType == MediaResource::SubType::kVideoCodec) {
- service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
+ switch (resources[i].subType) {
+ case MediaResource::SubType::kAudioCodec:
+ service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
+ break;
+ case MediaResource::SubType::kVideoCodec:
+ service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
+ break;
+ case MediaResource::SubType::kImageCodec:
+ service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_IMAGE_CODEC);
+ break;
+ case MediaResource::SubType::kUnspecifiedSubType:
+ break;
}
}
}
}
-binder_status_t ResourceManagerService::dump(
- int fd, const char** /*args*/, uint32_t /*numArgs*/) {
+binder_status_t ResourceManagerService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) {
String8 result;
if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
@@ -275,8 +300,7 @@
return OK;
}
-struct SystemCallbackImpl :
- public ResourceManagerService::SystemCallbackInterface {
+struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface {
SystemCallbackImpl() : mClientToken(new BBinder()) {}
virtual void noteStartVideo(int uid) override {
@@ -303,8 +327,7 @@
ResourceManagerService::ResourceManagerService()
: ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {}
-ResourceManagerService::ResourceManagerService(
- const sp<ProcessInfoInterface> &processInfo,
+ResourceManagerService::ResourceManagerService(const sp<ProcessInfoInterface> &processInfo,
const sp<SystemCallbackInterface> &systemResource)
: mProcessInfo(processInfo),
mSystemCB(systemResource),
@@ -362,8 +385,8 @@
return Status::ok();
}
-void ResourceManagerService::onFirstAdded(
- const MediaResourceParcel& resource, const ResourceInfo& clientInfo) {
+void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource,
+ const ResourceInfo& clientInfo) {
// first time added
if (resource.type == MediaResource::Type::kCpuBoost
&& resource.subType == MediaResource::SubType::kUnspecifiedSubType) {
@@ -380,8 +403,8 @@
}
}
-void ResourceManagerService::onLastRemoved(
- const MediaResourceParcel& resource, const ResourceInfo& clientInfo) {
+void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource,
+ const ResourceInfo& clientInfo) {
if (resource.type == MediaResource::Type::kCpuBoost
&& resource.subType == MediaResource::SubType::kUnspecifiedSubType
&& mCpuBoostCount > 0) {
@@ -394,8 +417,8 @@
}
}
-void ResourceManagerService::mergeResources(
- MediaResourceParcel& r1, const MediaResourceParcel& r2) {
+void ResourceManagerService::mergeResources(MediaResourceParcel& r1,
+ const MediaResourceParcel& r2) {
// The resource entry on record is maintained to be in [0,INT64_MAX].
// Clamp if merging in the new resource value causes it to go out of bound.
// Note that the new resource value could be negative, eg.DrmSession, the
@@ -411,10 +434,7 @@
}
}
-Status ResourceManagerService::addResource(
- int32_t pid,
- int32_t uid,
- int64_t clientId,
+Status ResourceManagerService::addResource(int32_t pid, int32_t uid, int64_t clientId,
const std::shared_ptr<IResourceManagerClient>& client,
const std::vector<MediaResourceParcel>& resources) {
String8 log = String8::format("addResource(pid %d, clientId %lld, resources %s)",
@@ -473,8 +493,7 @@
return Status::ok();
}
-Status ResourceManagerService::removeResource(
- int32_t pid, int64_t clientId,
+Status ResourceManagerService::removeResource(int32_t pid, int64_t clientId,
const std::vector<MediaResourceParcel>& resources) {
String8 log = String8::format("removeResource(pid %d, clientId %lld, resources %s)",
pid, (long long) clientId, getString(resources).string());
@@ -583,22 +602,19 @@
return Status::ok();
}
-void ResourceManagerService::getClientForResource_l(
- int callingPid, const MediaResourceParcel *res,
+void ResourceManagerService::getClientForResource_l(int callingPid, const MediaResourceParcel *res,
Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
if (res == NULL) {
return;
}
std::shared_ptr<IResourceManagerClient> client;
- if (getLowestPriorityBiggestClient_l(callingPid, res->type, &client)) {
+ if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, &client)) {
clients->push_back(client);
}
}
-Status ResourceManagerService::reclaimResource(
- int32_t callingPid,
- const std::vector<MediaResourceParcel>& resources,
- bool* _aidl_return) {
+Status ResourceManagerService::reclaimResource(int32_t callingPid,
+ const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) {
String8 log = String8::format("reclaimResource(callingPid %d, resources %s)",
callingPid, getString(resources).string());
mServiceLog->add(log);
@@ -618,34 +634,43 @@
const MediaResourceParcel *graphicMemory = NULL;
const MediaResourceParcel *drmSession = NULL;
for (size_t i = 0; i < resources.size(); ++i) {
- MediaResource::Type type = resources[i].type;
- if (resources[i].type == MediaResource::Type::kSecureCodec) {
- secureCodec = &resources[i];
- } else if (type == MediaResource::Type::kNonSecureCodec) {
- nonSecureCodec = &resources[i];
- } else if (type == MediaResource::Type::kGraphicMemory) {
- graphicMemory = &resources[i];
- } else if (type == MediaResource::Type::kDrmSession) {
- drmSession = &resources[i];
+ switch (resources[i].type) {
+ case MediaResource::Type::kSecureCodec:
+ secureCodec = &resources[i];
+ break;
+ case MediaResource::Type::kNonSecureCodec:
+ nonSecureCodec = &resources[i];
+ break;
+ case MediaResource::Type::kGraphicMemory:
+ graphicMemory = &resources[i];
+ break;
+ case MediaResource::Type::kDrmSession:
+ drmSession = &resources[i];
+ break;
+ default:
+ break;
}
}
// first pass to handle secure/non-secure codec conflict
if (secureCodec != NULL) {
if (!mSupportsMultipleSecureCodecs) {
- if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) {
+ if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
+ secureCodec->subType, &clients)) {
return Status::ok();
}
}
if (!mSupportsSecureWithNonSecureCodec) {
- if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec, &clients)) {
+ if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec,
+ secureCodec->subType, &clients)) {
return Status::ok();
}
}
}
if (nonSecureCodec != NULL) {
if (!mSupportsSecureWithNonSecureCodec) {
- if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) {
+ if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec,
+ nonSecureCodec->subType, &clients)) {
return Status::ok();
}
}
@@ -681,11 +706,11 @@
}
}
- *_aidl_return = reclaimInternal(clients);
+ *_aidl_return = reclaimUnconditionallyFrom(clients);
return Status::ok();
}
-bool ResourceManagerService::reclaimInternal(
+bool ResourceManagerService::reclaimUnconditionallyFrom(
const Vector<std::shared_ptr<IResourceManagerClient>> &clients) {
if (clients.size() == 0) {
return false;
@@ -732,9 +757,7 @@
return false;
}
-Status ResourceManagerService::overridePid(
- int originalPid,
- int newPid) {
+Status ResourceManagerService::overridePid(int originalPid, int newPid) {
String8 log = String8::format("overridePid(originalPid %d, newPid %d)",
originalPid, newPid);
mServiceLog->add(log);
@@ -763,9 +786,7 @@
}
Status ResourceManagerService::overrideProcessInfo(
- const std::shared_ptr<IResourceManagerClient>& client,
- int pid,
- int procState,
+ const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState,
int oomScore) {
String8 log = String8::format("overrideProcessInfo(pid %d, procState %d, oomScore %d)",
pid, procState, oomScore);
@@ -799,8 +820,8 @@
return Status::ok();
}
-uintptr_t ResourceManagerService::addCookieAndLink_l(
- ::ndk::SpAIBinder binder, const sp<DeathNotifier>& notifier) {
+uintptr_t ResourceManagerService::addCookieAndLink_l(::ndk::SpAIBinder binder,
+ const sp<DeathNotifier>& notifier) {
std::scoped_lock lock{sCookieLock};
uintptr_t cookie;
@@ -813,8 +834,7 @@
return cookie;
}
-void ResourceManagerService::removeCookieAndUnlink_l(
- ::ndk::SpAIBinder binder, uintptr_t cookie) {
+void ResourceManagerService::removeCookieAndUnlink_l(::ndk::SpAIBinder binder, uintptr_t cookie) {
std::scoped_lock lock{sCookieLock};
AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(), (void*)cookie);
sCookieToDeathNotifierMap.erase(cookie);
@@ -889,16 +909,34 @@
MediaResource::Type::kNonSecureCodec,
MediaResource::Type::kGraphicMemory,
MediaResource::Type::kDrmSession}) {
- std::shared_ptr<IResourceManagerClient> client;
- if (getBiggestClient_l(pid, type, &client, true /* pendingRemovalOnly */)) {
- clients.add(client);
- break;
+ switch (type) {
+ // Codec resources are segregated by audio, video and image domains.
+ case MediaResource::Type::kSecureCodec:
+ case MediaResource::Type::kNonSecureCodec:
+ for (MediaResource::SubType subType : {MediaResource::SubType::kAudioCodec,
+ MediaResource::SubType::kVideoCodec,
+ MediaResource::SubType::kImageCodec}) {
+ std::shared_ptr<IResourceManagerClient> client;
+ if (getBiggestClientPendingRemoval_l(pid, type, subType, &client)) {
+ clients.add(client);
+ continue;
+ }
+ }
+ break;
+ // Non-codec resources are shared by audio, video and image codecs (no subtype).
+ default:
+ std::shared_ptr<IResourceManagerClient> client;
+ if (getBiggestClientPendingRemoval_l(pid, type,
+ MediaResource::SubType::kUnspecifiedSubType, &client)) {
+ clients.add(client);
+ }
+ break;
}
}
}
if (!clients.empty()) {
- reclaimInternal(clients);
+ reclaimUnconditionallyFrom(clients);
}
return Status::ok();
}
@@ -915,14 +953,13 @@
return mProcessInfo->getPriority(newPid, priority);
}
-bool ResourceManagerService::getAllClients_l(
- int callingPid, MediaResource::Type type,
- Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
+bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type,
+ MediaResource::SubType subType, Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
Vector<std::shared_ptr<IResourceManagerClient>> temp;
for (size_t i = 0; i < mMap.size(); ++i) {
ResourceInfos &infos = mMap.editValueAt(i);
for (size_t j = 0; j < infos.size(); ++j) {
- if (hasResourceType(type, infos[j].resources)) {
+ if (hasResourceType(type, subType, infos[j].resources)) {
if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) {
// some higher/equal priority process owns the resource,
// this request can't be fulfilled.
@@ -942,8 +979,8 @@
return true;
}
-bool ResourceManagerService::getLowestPriorityBiggestClient_l(
- int callingPid, MediaResource::Type type,
+bool ResourceManagerService::getLowestPriorityBiggestClient_l(int callingPid,
+ MediaResource::Type type, MediaResource::SubType subType,
std::shared_ptr<IResourceManagerClient> *client) {
int lowestPriorityPid;
int lowestPriority;
@@ -951,7 +988,7 @@
// Before looking into other processes, check if we have clients marked for
// pending removal in the same process.
- if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) {
+ if (getBiggestClientPendingRemoval_l(callingPid, type, subType, client)) {
return true;
}
if (!getPriority_l(callingPid, &callingPriority)) {
@@ -959,7 +996,7 @@
callingPid);
return false;
}
- if (!getLowestPriorityPid_l(type, &lowestPriorityPid, &lowestPriority)) {
+ if (!getLowestPriorityPid_l(type, subType, &lowestPriorityPid, &lowestPriority)) {
return false;
}
if (lowestPriority <= callingPriority) {
@@ -968,14 +1005,14 @@
return false;
}
- if (!getBiggestClient_l(lowestPriorityPid, type, client)) {
+ if (!getBiggestClient_l(lowestPriorityPid, type, subType, client)) {
return false;
}
return true;
}
-bool ResourceManagerService::getLowestPriorityPid_l(
- MediaResource::Type type, int *lowestPriorityPid, int *lowestPriority) {
+bool ResourceManagerService::getLowestPriorityPid_l(MediaResource::Type type,
+ MediaResource::SubType subType, int *lowestPriorityPid, int *lowestPriority) {
int pid = -1;
int priority = -1;
for (size_t i = 0; i < mMap.size(); ++i) {
@@ -983,7 +1020,7 @@
// no client on this process.
continue;
}
- if (!hasResourceType(type, mMap.valueAt(i))) {
+ if (!hasResourceType(type, subType, mMap.valueAt(i))) {
// doesn't have the requested resource type
continue;
}
@@ -1021,8 +1058,13 @@
return (callingPidPriority < priority);
}
-bool ResourceManagerService::getBiggestClient_l(
- int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client,
+bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
+ MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client) {
+ return getBiggestClient_l(pid, type, subType, client, true /* pendingRemovalOnly */);
+}
+
+bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type,
+ MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client,
bool pendingRemovalOnly) {
ssize_t index = mMap.indexOfKey(pid);
if (index < 0) {
@@ -1041,7 +1083,7 @@
}
for (auto it = resources.begin(); it != resources.end(); it++) {
const MediaResourceParcel &resource = it->second;
- if (resource.type == type) {
+ if (hasResourceType(type, subType, resource)) {
if (resource.value > largestValue) {
largestValue = resource.value;
clientTemp = infos[i].client;
@@ -1052,8 +1094,8 @@
if (clientTemp == NULL) {
ALOGE_IF(!pendingRemovalOnly,
- "getBiggestClient_l: can't find resource type %s for pid %d",
- asString(type), pid);
+ "getBiggestClient_l: can't find resource type %s and subtype %s for pid %d",
+ asString(type), asString(subType), pid);
return false;
}
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 9c2636e..6551371 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -77,26 +77,19 @@
int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
ResourceManagerService();
- explicit ResourceManagerService(
- const sp<ProcessInfoInterface> &processInfo,
+ explicit ResourceManagerService(const sp<ProcessInfoInterface> &processInfo,
const sp<SystemCallbackInterface> &systemResource);
virtual ~ResourceManagerService();
- void setObserverService(
- const std::shared_ptr<ResourceObserverService>& observerService);
+ void setObserverService(const std::shared_ptr<ResourceObserverService>& observerService);
// IResourceManagerService interface
Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
- Status addResource(
- int32_t pid,
- int32_t uid,
- int64_t clientId,
+ Status addResource(int32_t pid, int32_t uid, int64_t clientId,
const std::shared_ptr<IResourceManagerClient>& client,
const std::vector<MediaResourceParcel>& resources) override;
- Status removeResource(
- int32_t pid,
- int64_t clientId,
+ Status removeResource(int32_t pid, int64_t clientId,
const std::vector<MediaResourceParcel>& resources) override;
Status removeClient(int32_t pid, int64_t clientId) override;
@@ -104,20 +97,13 @@
// Tries to reclaim resource from processes with lower priority than the calling process
// according to the requested resources.
// Returns true if any resource has been reclaimed, otherwise returns false.
- Status reclaimResource(
- int32_t callingPid,
- const std::vector<MediaResourceParcel>& resources,
+ Status reclaimResource(int32_t callingPid, const std::vector<MediaResourceParcel>& resources,
bool* _aidl_return) override;
- Status overridePid(
- int originalPid,
- int newPid) override;
+ Status overridePid(int originalPid, int newPid) override;
- Status overrideProcessInfo(
- const std::shared_ptr<IResourceManagerClient>& client,
- int pid,
- int procState,
- int oomScore) override;
+ Status overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client, int pid,
+ int procState, int oomScore) override;
Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override;
@@ -132,30 +118,34 @@
// Reclaims resources from |clients|. Returns true if reclaim succeeded
// for all clients.
- bool reclaimInternal(
- const Vector<std::shared_ptr<IResourceManagerClient>> &clients);
+ bool reclaimUnconditionallyFrom(const Vector<std::shared_ptr<IResourceManagerClient>> &clients);
// Gets the list of all the clients who own the specified resource type.
// Returns false if any client belongs to a process with higher priority than the
// calling process. The clients will remain unchanged if returns false.
- bool getAllClients_l(int callingPid, MediaResource::Type type,
+ bool getAllClients_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType,
Vector<std::shared_ptr<IResourceManagerClient>> *clients);
// Gets the client who owns specified resource type from lowest possible priority process.
// Returns false if the calling process priority is not higher than the lowest process
// priority. The client will remain unchanged if returns false.
bool getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type,
- std::shared_ptr<IResourceManagerClient> *client);
+ MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client);
// Gets lowest priority process that has the specified resource type.
// Returns false if failed. The output parameters will remain unchanged if failed.
- bool getLowestPriorityPid_l(MediaResource::Type type, int *pid, int *priority);
+ bool getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType, int *pid,
+ int *priority);
// Gets the client who owns biggest piece of specified resource type from pid.
- // Returns false if failed. The client will remain unchanged if failed.
- bool getBiggestClient_l(int pid, MediaResource::Type type,
+ // Returns false with no change to client if there are no clients holdiing resources of thisi
+ // type.
+ bool getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType,
std::shared_ptr<IResourceManagerClient> *client,
bool pendingRemovalOnly = false);
+ // Same method as above, but with pendingRemovalOnly as true.
+ bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
+ MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client);
bool isCallingPriorityHigher_l(int callingPid, int pid);
diff --git a/services/mediaresourcemanager/aidl/android/media/MediaResourceSubType.aidl b/services/mediaresourcemanager/aidl/android/media/MediaResourceSubType.aidl
index af2ba68..72a0551 100644
--- a/services/mediaresourcemanager/aidl/android/media/MediaResourceSubType.aidl
+++ b/services/mediaresourcemanager/aidl/android/media/MediaResourceSubType.aidl
@@ -26,4 +26,5 @@
kUnspecifiedSubType = 0,
kAudioCodec = 1,
kVideoCodec = 2,
+ kImageCodec = 3,
}
diff --git a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
index 8e29312..1624477 100644
--- a/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
+++ b/services/mediaresourcemanager/test/ResourceManagerServiceTestUtils.h
@@ -119,11 +119,11 @@
struct TestClient : public BnResourceManagerClient {
TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
- : mReclaimed(false), mPid(pid), mService(service) {}
+ : mPid(pid), mService(service) {}
Status reclaimResource(bool* _aidl_return) override {
mService->removeClient(mPid, getId(ref<TestClient>()));
- mReclaimed = true;
+ mWasReclaimResourceCalled = true;
*_aidl_return = true;
return Status::ok();
}
@@ -133,18 +133,16 @@
return Status::ok();
}
- bool reclaimed() const {
- return mReclaimed;
- }
-
- void reset() {
- mReclaimed = false;
+ bool checkIfReclaimedAndReset() {
+ bool wasReclaimResourceCalled = mWasReclaimResourceCalled;
+ mWasReclaimResourceCalled = false;
+ return wasReclaimResourceCalled;
}
virtual ~TestClient() {}
private:
- bool mReclaimed;
+ bool mWasReclaimResourceCalled = false;
int mPid;
std::shared_ptr<ResourceManagerService> mService;
DISALLOW_EVIL_CONSTRUCTORS(TestClient);
@@ -166,14 +164,30 @@
return lhs.type == rhs.type && lhs.arg == rhs.arg;
}
-#define CHECK_STATUS_TRUE(condition) \
- EXPECT_TRUE((condition).isOk() && (result))
+// The condition is expected to return a status but also update the local
+// result variable.
+#define CHECK_STATUS_TRUE(conditionThatUpdatesResult) \
+ do { \
+ bool result = false; \
+ EXPECT_TRUE((conditionThatUpdatesResult).isOk()); \
+ EXPECT_TRUE(result); \
+ } while(false)
-#define CHECK_STATUS_FALSE(condition) \
- EXPECT_TRUE((condition).isOk() && !(result))
+// The condition is expected to return a status but also update the local
+// result variable.
+#define CHECK_STATUS_FALSE(conditionThatUpdatesResult) \
+ do { \
+ bool result = true; \
+ EXPECT_TRUE((conditionThatUpdatesResult).isOk()); \
+ EXPECT_FALSE(result); \
+ } while(false)
class ResourceManagerServiceTestBase : public ::testing::Test {
public:
+ static TestClient* toTestClient(std::shared_ptr<IResourceManagerClient> testClient) {
+ return static_cast<TestClient*>(testClient.get());
+ }
+
ResourceManagerServiceTestBase()
: mSystemCB(new TestSystemCallback()),
mService(::ndk::SharedRefBase::make<ResourceManagerService>(
@@ -183,6 +197,10 @@
mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
}
+ std::shared_ptr<IResourceManagerClient> createTestClient(int pid) {
+ return ::ndk::SharedRefBase::make<TestClient>(pid, mService);
+ }
+
sp<TestSystemCallback> mSystemCB;
std::shared_ptr<ResourceManagerService> mService;
std::shared_ptr<IResourceManagerClient> mTestClient1;
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index a029d45..8739c3b 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -25,22 +25,60 @@
namespace android {
class ResourceManagerServiceTest : public ResourceManagerServiceTestBase {
+private:
+ static MediaResource createSecureVideoCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kSecureCodec,
+ MediaResource::SubType::kVideoCodec, amount);
+ }
+
+ static MediaResource createNonSecureVideoCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kNonSecureCodec,
+ MediaResource::SubType::kVideoCodec, amount);
+ }
+
+ static MediaResource createSecureAudioCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kSecureCodec,
+ MediaResource::SubType::kAudioCodec, amount);
+ }
+
+ static MediaResource createNonSecureAudioCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kNonSecureCodec,
+ MediaResource::SubType::kAudioCodec, amount);
+ }
+
+ static MediaResource createSecureImageCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kSecureCodec,
+ MediaResource::SubType::kImageCodec, amount);
+ }
+
+ static MediaResource createNonSecureImageCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kNonSecureCodec,
+ MediaResource::SubType::kImageCodec, amount);
+ }
+
+ static MediaResource createGraphicMemoryResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kGraphicMemory,
+ MediaResource::SubType::kUnspecifiedSubType, amount);
+ }
+
+ static MediaResource createDrmSessionResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kDrmSession,
+ MediaResource::SubType::kUnspecifiedSubType, amount);
+ }
+
+ static MediaResource createBatteryResource() {
+ return MediaResource(MediaResource::Type::kBattery,
+ MediaResource::SubType::kUnspecifiedSubType, 1);
+ }
+
+ static MediaResource createCpuBoostResource() {
+ return MediaResource(MediaResource::Type::kCpuBoost,
+ MediaResource::SubType::kUnspecifiedSubType, 1);
+ }
+
public:
ResourceManagerServiceTest() : ResourceManagerServiceTestBase() {}
- void verifyClients(bool c1, bool c2, bool c3) {
- TestClient *client1 = static_cast<TestClient*>(mTestClient1.get());
- TestClient *client2 = static_cast<TestClient*>(mTestClient2.get());
- TestClient *client3 = static_cast<TestClient*>(mTestClient3.get());
-
- EXPECT_EQ(c1, client1->reclaimed());
- EXPECT_EQ(c2, client2->reclaimed());
- EXPECT_EQ(c3, client3->reclaimed());
-
- client1->reset();
- client2->reset();
- client3->reset();
- }
// test set up
// ---------------------------------------------------------------------------------
@@ -268,7 +306,6 @@
void testOverridePid() {
- bool result;
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
@@ -293,8 +330,6 @@
}
void testMarkClientForPendingRemoval() {
- bool result;
-
{
addResource();
mService->mSupportsSecureWithNonSecureCodec = true;
@@ -307,13 +342,17 @@
// no lower priority client
CHECK_STATUS_FALSE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
// client marked for pending removal from the same process got reclaimed
CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 3 which still left
mService->removeClient(kTestPid2, getId(mTestClient3));
@@ -331,11 +370,15 @@
// client marked for pending removal from the same process got reclaimed
// first, even though there are lower priority process
CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// lower priority client got reclaimed
CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
- verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_EQ(true, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 3 which still left
mService->removeClient(kTestPid2, getId(mTestClient3));
@@ -349,17 +392,23 @@
// client marked for pending removal got reclaimed
EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// No more clients marked for removal
EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
- verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient3));
// client marked for pending removal got reclaimed
EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
- verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
+ EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_EQ(true, toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 1 which still left
mService->removeClient(kTestPid1, getId(mTestClient1));
@@ -384,14 +433,15 @@
void testGetAllClients() {
addResource();
-
MediaResource::Type type = MediaResource::Type::kSecureCodec;
+ MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
+
Vector<std::shared_ptr<IResourceManagerClient> > clients;
- EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
+ EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, subType, &clients));
// some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
// will fail.
- EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients));
- EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients));
+ EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, subType, &clients));
+ EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, subType, &clients));
EXPECT_EQ(2u, clients.size());
// (OK to require ordering in clients[], as the pid map is sorted)
@@ -400,7 +450,6 @@
}
void testReclaimResourceSecure() {
- bool result;
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
@@ -417,11 +466,15 @@
// reclaim all secure codecs
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim one largest graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
@@ -439,7 +492,9 @@
// reclaim all secure and non-secure codecs
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
@@ -458,15 +513,21 @@
// reclaim all non-secure codecs
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim one largest graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another largest graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
@@ -483,15 +544,21 @@
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
// one largest graphic memory from lowest process got reclaimed
- verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
@@ -508,20 +575,25 @@
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
// secure codec from lowest process got reclaimed
- verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another secure codec from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// no more secure codec, non-secure codec will be reclaimed.
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
}
}
void testReclaimResourceNonSecure() {
- bool result;
std::vector<MediaResourceParcel> resources;
resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
@@ -537,11 +609,15 @@
// reclaim all secure codecs
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim one graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
@@ -558,15 +634,21 @@
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
// one largest graphic memory from lowest process got reclaimed
- verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// call again should reclaim another graphic memory from lowest process
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// nothing left
CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
@@ -582,11 +664,15 @@
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
// one non secure codec from lowest process got reclaimed
- verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// no more non-secure codec, secure codec from lowest priority process will be reclaimed
CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
- verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
+ EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset());
// clean up client 3 which still left
mService->removeClient(kTestPid2, getId(mTestClient3));
@@ -595,13 +681,17 @@
void testGetLowestPriorityBiggestClient() {
MediaResource::Type type = MediaResource::Type::kGraphicMemory;
+ MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
std::shared_ptr<IResourceManagerClient> client;
- EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
+ EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, subType,
+ &client));
addResource();
- EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
- EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
+ EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, subType,
+ &client));
+ EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, subType,
+ &client));
// kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
// mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
@@ -614,35 +704,25 @@
TestProcessInfo processInfo;
MediaResource::Type type = MediaResource::Type::kGraphicMemory;
- EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
+ MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType;
+ EXPECT_FALSE(mService->getLowestPriorityPid_l(type, subType, &pid, &priority));
addResource();
- EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
+ EXPECT_TRUE(mService->getLowestPriorityPid_l(type, subType, &pid, &priority));
EXPECT_EQ(kTestPid1, pid);
int priority1;
processInfo.getPriority(kTestPid1, &priority1);
EXPECT_EQ(priority1, priority);
type = MediaResource::Type::kNonSecureCodec;
- EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
+ EXPECT_TRUE(mService->getLowestPriorityPid_l(type, subType, &pid, &priority));
EXPECT_EQ(kTestPid2, pid);
int priority2;
processInfo.getPriority(kTestPid2, &priority2);
EXPECT_EQ(priority2, priority);
}
- void testGetBiggestClient() {
- MediaResource::Type type = MediaResource::Type::kGraphicMemory;
- std::shared_ptr<IResourceManagerClient> client;
- EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
-
- addResource();
-
- EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
- EXPECT_EQ(mTestClient2, client);
- }
-
void testIsCallingPriorityHigher() {
EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
@@ -725,6 +805,361 @@
EXPECT_EQ(4u, mSystemCB->eventCount());
EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType());
}
+
+ void testReclaimResources_withVideoCodec_reclaimsOnlyVideoCodec() {
+ const std::shared_ptr<IResourceManagerClient>& audioImageTestClient = mTestClient1;
+ const std::shared_ptr<IResourceManagerClient>& videoTestClient = mTestClient2;
+
+ // Create an audio and image codec resource
+ std::vector<MediaResourceParcel> audioImageResources;
+ audioImageResources.push_back(createNonSecureAudioCodecResource());
+ audioImageResources.push_back(createNonSecureImageCodecResource());
+ mService->addResource(kLowPriorityPid, kTestUid1, getId(audioImageTestClient),
+ audioImageTestClient, audioImageResources);
+
+ // Fail to reclaim a video codec resource
+ std::vector<MediaResourceParcel> reclaimResources;
+ reclaimResources.push_back(createNonSecureVideoCodecResource());
+ CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+
+ // Now add a video codec resource
+ std::vector<MediaResourceParcel> videoResources;
+ videoResources.push_back(createNonSecureVideoCodecResource());
+ mService->addResource(kLowPriorityPid, kTestUid1, getId(videoTestClient), videoTestClient,
+ videoResources);
+
+ // Verify that the newly-created video codec resource can be reclaimed
+ CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+
+ // Verify that the audio and image resources are untouched
+ EXPECT_FALSE(toTestClient(audioImageTestClient)->checkIfReclaimedAndReset());
+ // But the video resource was reclaimed
+ EXPECT_TRUE(toTestClient(videoTestClient)->checkIfReclaimedAndReset());
+ }
+
+ void testReclaimResources_withAudioCodec_reclaimsOnlyAudioCodec() {
+ const auto & videoImageTestClient = mTestClient1;
+ const auto & audioTestClient = mTestClient2;
+
+ // Create a video and audio codec resource
+ std::vector<MediaResourceParcel> videoImageResources;
+ videoImageResources.push_back(createNonSecureVideoCodecResource());
+ videoImageResources.push_back(createNonSecureImageCodecResource());
+ mService->addResource(kLowPriorityPid, kTestUid1, getId(videoImageTestClient),
+ videoImageTestClient, videoImageResources);
+
+ // Fail to reclaim an audio codec resource
+ std::vector<MediaResourceParcel> reclaimResources;
+ reclaimResources.push_back(createNonSecureAudioCodecResource());
+ CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+
+ // Now add an audio codec resource
+ std::vector<MediaResourceParcel> audioResources;
+ audioResources.push_back(createNonSecureAudioCodecResource());
+ mService->addResource(kLowPriorityPid, kTestUid2, getId(audioTestClient), audioTestClient,
+ audioResources);
+
+ // Verify that the newly-created audio codec resource can be reclaimed
+ CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+
+ // Verify that the video and image resources are untouched
+ EXPECT_FALSE(toTestClient(videoImageTestClient)->checkIfReclaimedAndReset());
+ // But the audio resource was reclaimed
+ EXPECT_TRUE(toTestClient(audioTestClient)->checkIfReclaimedAndReset());
+ }
+
+ void testReclaimResources_withImageCodec_reclaimsOnlyImageCodec() {
+ const auto & videoAudioTestClient = mTestClient1;
+ const auto & imageTestClient = mTestClient2;
+
+ // Create a video and audio codec resource
+ std::vector<MediaResourceParcel> videoAudioResources;
+ videoAudioResources.push_back(createNonSecureVideoCodecResource());
+ videoAudioResources.push_back(createNonSecureAudioCodecResource());
+ mService->addResource(kLowPriorityPid, kTestUid1, getId(videoAudioTestClient),
+ videoAudioTestClient, videoAudioResources);
+
+ // Fail to reclaim an image codec resource
+ std::vector<MediaResourceParcel> reclaimResources;
+ reclaimResources.push_back(createNonSecureImageCodecResource());
+ CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+
+ // Now add an image codec resource
+ std::vector<MediaResourceParcel> imageResources;
+ imageResources.push_back(createNonSecureImageCodecResource());
+ mService->addResource(kLowPriorityPid, kTestUid2, getId(imageTestClient), imageTestClient,
+ imageResources);
+
+ // Verify that the newly-created image codec resource can be reclaimed
+ CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+
+ // Verify that the video and audio resources are untouched
+ EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset());
+ // But the image resource was reclaimed
+ EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset());
+ }
+
+ void testReclaimResources_whenPartialResourceMatch_reclaims() {
+ const int onlyUid = kTestUid1;
+ const auto onlyClient = createTestClient(kLowPriorityPid);
+
+ std::vector<MediaResourceParcel> ownedResources;
+ ownedResources.push_back(createNonSecureVideoCodecResource());
+ ownedResources.push_back(createGraphicMemoryResource(100));
+ mService->addResource(kLowPriorityPid, onlyUid, getId(onlyClient), onlyClient,
+ ownedResources);
+
+ // Reclaim an image codec instead of the video codec that is owned, but also reclaim
+ // graphics memory, which will trigger the reclaim.
+ std::vector<MediaResourceParcel> reclaimResources;
+ reclaimResources.push_back(createNonSecureImageCodecResource());
+ reclaimResources.push_back(createGraphicMemoryResource(100));
+ CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result));
+
+ // Verify that the video codec resources (including the needed graphic memory) is reclaimed
+ EXPECT_TRUE(toTestClient(onlyClient)->checkIfReclaimedAndReset());
+ }
+
+ void testReclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources() {
+ // this test only uses one pid and one uid
+ const int onlyPid = kTestPid1;
+ const int onlyUid = kTestUid1;
+
+ // secure video codec
+ const auto smallSecureVideoMarkedClient = createTestClient(onlyPid);
+ const auto largeSecureVideoMarkedClient = createTestClient(onlyPid);
+ const auto largestSecureVideoActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createSecureVideoCodecResource(1));
+ mService->addResource(onlyPid, onlyUid, getId(smallSecureVideoMarkedClient),
+ smallSecureVideoMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createSecureVideoCodecResource(2));
+ mService->addResource(onlyPid, onlyUid, getId(largeSecureVideoMarkedClient),
+ largeSecureVideoMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createSecureVideoCodecResource(3));
+ mService->addResource(onlyPid, onlyUid, getId(largestSecureVideoActiveClient),
+ largestSecureVideoActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallSecureVideoMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeSecureVideoMarkedClient));
+ // don't mark the largest client
+
+ // non-secure video codec
+ const auto smallNonSecureVideoMarkedClient = createTestClient(onlyPid);
+ const auto largeNonSecureVideoMarkedClient = createTestClient(onlyPid);
+ const auto largestNonSecureVideoActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createNonSecureVideoCodecResource(1));
+ mService->addResource(onlyPid, onlyUid, getId(smallNonSecureVideoMarkedClient),
+ smallNonSecureVideoMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createNonSecureVideoCodecResource(2));
+ mService->addResource(onlyPid, onlyUid, getId(largeNonSecureVideoMarkedClient),
+ largeNonSecureVideoMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createNonSecureVideoCodecResource(3));
+ mService->addResource(onlyPid, onlyUid, getId(largestNonSecureVideoActiveClient),
+ largestNonSecureVideoActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureVideoMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureVideoMarkedClient));
+ // don't mark the largest client
+
+ // secure audio codec
+ const auto smallSecureAudioMarkedClient = createTestClient(onlyPid);
+ const auto largeSecureAudioMarkedClient = createTestClient(onlyPid);
+ const auto largestSecureAudioActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createSecureAudioCodecResource(1));
+ mService->addResource(onlyPid, onlyUid, getId(smallSecureAudioMarkedClient),
+ smallSecureAudioMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createSecureAudioCodecResource(2));
+ mService->addResource(onlyPid, onlyUid, getId(largeSecureAudioMarkedClient),
+ largeSecureAudioMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createSecureAudioCodecResource(3));
+ mService->addResource(onlyPid, onlyUid, getId(largestSecureVideoActiveClient),
+ largestSecureVideoActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallSecureAudioMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeSecureAudioMarkedClient));
+ // don't mark the largest client
+
+ // non-secure audio codec
+ const auto smallNonSecureAudioMarkedClient = createTestClient(onlyPid);
+ const auto largeNonSecureAudioMarkedClient = createTestClient(onlyPid);
+ const auto largestNonSecureAudioActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createNonSecureAudioCodecResource(1));
+ mService->addResource(onlyPid, onlyUid, getId(smallNonSecureAudioMarkedClient),
+ smallNonSecureAudioMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createNonSecureAudioCodecResource(2));
+ mService->addResource(onlyPid, onlyUid, getId(largeNonSecureAudioMarkedClient),
+ largeNonSecureAudioMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createNonSecureAudioCodecResource(3));
+ mService->addResource(onlyPid, onlyUid, getId(largestNonSecureAudioActiveClient),
+ largestNonSecureAudioActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureAudioMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureAudioMarkedClient));
+ // don't mark the largest client
+
+ // secure image codec
+ const auto smallSecureImageMarkedClient = createTestClient(onlyPid);
+ const auto largeSecureImageMarkedClient = createTestClient(onlyPid);
+ const auto largestSecureImageActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createSecureImageCodecResource(1));
+ mService->addResource(onlyPid, onlyUid, getId(smallSecureImageMarkedClient),
+ smallSecureImageMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createSecureImageCodecResource(2));
+ mService->addResource(onlyPid, onlyUid, getId(largeSecureImageMarkedClient),
+ largeSecureImageMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createSecureImageCodecResource(3));
+ mService->addResource(onlyPid, onlyUid, getId(largestSecureImageActiveClient),
+ largestSecureImageActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallSecureImageMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeSecureImageMarkedClient));
+ // don't mark the largest client
+
+ // non-secure image codec
+ const auto smallNonSecureImageMarkedClient = createTestClient(onlyPid);
+ const auto largeNonSecureImageMarkedClient = createTestClient(onlyPid);
+ const auto largestNonSecureImageActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createNonSecureImageCodecResource(1));
+ mService->addResource(onlyPid, onlyUid, getId(smallNonSecureImageMarkedClient),
+ smallNonSecureImageMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createNonSecureImageCodecResource(2));
+ mService->addResource(onlyPid, onlyUid, getId(largeNonSecureImageMarkedClient),
+ largeNonSecureImageMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createNonSecureImageCodecResource(3));
+ mService->addResource(onlyPid, onlyUid, getId(largestNonSecureImageActiveClient),
+ largestNonSecureImageActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureImageMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureImageMarkedClient));
+ // don't mark the largest client
+
+ // graphic memory
+ const auto smallGraphicMemoryMarkedClient = createTestClient(onlyPid);
+ const auto largeGraphicMemoryMarkedClient = createTestClient(onlyPid);
+ const auto largestGraphicMemoryActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createGraphicMemoryResource(100));
+ mService->addResource(onlyPid, onlyUid, getId(smallGraphicMemoryMarkedClient),
+ smallGraphicMemoryMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createGraphicMemoryResource(200));
+ mService->addResource(onlyPid, onlyUid, getId(largeGraphicMemoryMarkedClient),
+ largeGraphicMemoryMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createGraphicMemoryResource(300));
+ mService->addResource(onlyPid, onlyUid, getId(largestGraphicMemoryActiveClient),
+ largestGraphicMemoryActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallGraphicMemoryMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeGraphicMemoryMarkedClient));
+ // don't mark the largest client
+
+ // DRM session
+ const auto smallDrmSessionMarkedClient = createTestClient(onlyPid);
+ const auto largeDrmSessionMarkedClient = createTestClient(onlyPid);
+ const auto largestDrmSessionActiveClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createDrmSessionResource(1));
+ mService->addResource(onlyPid, onlyUid, getId(smallDrmSessionMarkedClient),
+ smallDrmSessionMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createDrmSessionResource(2));
+ mService->addResource(onlyPid, onlyUid, getId(largeDrmSessionMarkedClient),
+ largeDrmSessionMarkedClient, resources);
+ resources.clear();
+ resources.push_back(createDrmSessionResource(3));
+ mService->addResource(onlyPid, onlyUid, getId(largestDrmSessionActiveClient),
+ largestDrmSessionActiveClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(smallDrmSessionMarkedClient));
+ mService->markClientForPendingRemoval(onlyPid, getId(largeDrmSessionMarkedClient));
+ // don't mark the largest client
+
+ // battery
+ const auto batteryMarkedClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createBatteryResource());
+ mService->addResource(onlyPid, onlyUid, getId(batteryMarkedClient),
+ batteryMarkedClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(batteryMarkedClient));
+
+ // CPU boost
+ const auto cpuBoostMarkedClient = createTestClient(onlyPid);
+ {
+ std::vector<MediaResourceParcel> resources;
+ resources.push_back(createCpuBoostResource());
+ mService->addResource(onlyPid, onlyUid, getId(cpuBoostMarkedClient),
+ cpuBoostMarkedClient, resources);
+ }
+ mService->markClientForPendingRemoval(onlyPid, getId(cpuBoostMarkedClient));
+
+ // now we expect that we only reclaim resources from the biggest marked client
+ EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(onlyPid).isOk());
+ // secure video codec
+ EXPECT_FALSE(toTestClient(smallSecureVideoMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeSecureVideoMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestSecureVideoActiveClient)->checkIfReclaimedAndReset());
+ // non-secure video codec
+ EXPECT_FALSE(toTestClient(smallNonSecureVideoMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeNonSecureVideoMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestNonSecureVideoActiveClient)->checkIfReclaimedAndReset());
+ // secure audio codec
+ EXPECT_FALSE(toTestClient(smallSecureAudioMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeSecureAudioMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestSecureAudioActiveClient)->checkIfReclaimedAndReset());
+ // non-secure audio codec
+ EXPECT_FALSE(toTestClient(smallNonSecureAudioMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeNonSecureAudioMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestNonSecureAudioActiveClient)->checkIfReclaimedAndReset());
+ // secure image codec
+ EXPECT_FALSE(toTestClient(smallSecureImageMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeSecureImageMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestSecureImageActiveClient)->checkIfReclaimedAndReset());
+ // non-secure image codec
+ EXPECT_FALSE(toTestClient(smallNonSecureImageMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeNonSecureImageMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestNonSecureImageActiveClient)->checkIfReclaimedAndReset());
+ // graphic memory
+ EXPECT_FALSE(toTestClient(smallGraphicMemoryMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeGraphicMemoryMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestGraphicMemoryActiveClient)->checkIfReclaimedAndReset());
+ // DRM session
+ EXPECT_FALSE(toTestClient(smallDrmSessionMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_TRUE(toTestClient(largeDrmSessionMarkedClient)->checkIfReclaimedAndReset());
+ EXPECT_FALSE(toTestClient(largestDrmSessionActiveClient)->checkIfReclaimedAndReset());
+ // battery is not expected to be reclaimed when marked as pending removal
+ EXPECT_FALSE(toTestClient(batteryMarkedClient)->checkIfReclaimedAndReset());
+ // CPU boost is not expected to be reclaimed when marked as pending removal
+ EXPECT_FALSE(toTestClient(cpuBoostMarkedClient)->checkIfReclaimedAndReset());
+ }
};
TEST_F(ResourceManagerServiceTest, config) {
@@ -768,19 +1203,15 @@
testGetLowestPriorityPid();
}
-TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
- testGetBiggestClient();
-}
-
TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
testIsCallingPriorityHigher();
}
-TEST_F(ResourceManagerServiceTest, testBatteryStats) {
+TEST_F(ResourceManagerServiceTest, batteryStats) {
testBatteryStats();
}
-TEST_F(ResourceManagerServiceTest, testCpusetBoost) {
+TEST_F(ResourceManagerServiceTest, cpusetBoost) {
testCpusetBoost();
}
@@ -792,4 +1223,25 @@
testMarkClientForPendingRemoval();
}
+TEST_F(ResourceManagerServiceTest, reclaimResources_withVideoCodec_reclaimsOnlyVideoCodec) {
+ testReclaimResources_withVideoCodec_reclaimsOnlyVideoCodec();
+}
+
+TEST_F(ResourceManagerServiceTest, reclaimResources_withAudioCodec_reclaimsOnlyAudioCodec) {
+ testReclaimResources_withAudioCodec_reclaimsOnlyAudioCodec();
+}
+
+TEST_F(ResourceManagerServiceTest, reclaimResources_withImageCodec_reclaimsOnlyImageCodec) {
+ testReclaimResources_withImageCodec_reclaimsOnlyImageCodec();
+}
+
+TEST_F(ResourceManagerServiceTest, reclaimResources_whenPartialResourceMatch_reclaims) {
+ testReclaimResources_whenPartialResourceMatch_reclaims();
+}
+
+TEST_F(ResourceManagerServiceTest,
+ reclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources) {
+ testReclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources();
+}
+
} // namespace android
diff --git a/services/mediaresourcemanager/test/ResourceObserverService_test.cpp b/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
index acd9df1..003569d 100644
--- a/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceObserverService_test.cpp
@@ -116,6 +116,26 @@
const EventTracker::Event EventTracker::NoEvent;
+static MediaResource createSecureVideoCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kSecureCodec,
+ MediaResource::SubType::kVideoCodec, amount);
+}
+
+static MediaResource createNonSecureVideoCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kNonSecureCodec,
+ MediaResource::SubType::kVideoCodec, amount);
+}
+
+static MediaResource createSecureAudioCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kSecureCodec,
+ MediaResource::SubType::kAudioCodec, amount);
+}
+
+static MediaResource createNonSecureAudioCodecResource(int amount = 1) {
+ return MediaResource(MediaResource::Type::kNonSecureCodec,
+ MediaResource::SubType::kAudioCodec, amount);
+}
+
// Operators for GTest macros.
bool operator==(const EventTracker::Event& lhs, const EventTracker::Event& rhs) {
return lhs.type == rhs.type && lhs.uid == rhs.uid && lhs.pid == rhs.pid &&
@@ -233,30 +253,30 @@
std::vector<MediaResourceParcel> resources;
// Add secure video codec.
- resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
+ resources = {createSecureVideoCodecResource()};
mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
// Add non-secure video codec.
- resources = {MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
+ resources = {createNonSecureVideoCodecResource()};
mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
// Add secure & non-secure video codecs.
- resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
+ resources = {createSecureVideoCodecResource(),
+ createNonSecureVideoCodecResource()};
mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
// Add additional audio codecs, should be ignored.
- resources.push_back(MediaResource::CodecResource(1 /*secure*/, 0 /*video*/));
- resources.push_back(MediaResource::CodecResource(0 /*secure*/, 0 /*video*/));
+ resources.push_back(createSecureAudioCodecResource());
+ resources.push_back(createNonSecureAudioCodecResource());
mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables2));
@@ -276,9 +296,9 @@
// Add multiple secure & non-secure video codecs.
// Multiple entries of the same type should be merged, count should be propagated correctly.
- resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 3 /*count*/)};
+ resources = {createSecureVideoCodecResource(),
+ createSecureVideoCodecResource(),
+ createNonSecureVideoCodecResource(3)};
observables1 = {{MediaObservableType::kVideoSecureCodec, 2}};
observables2 = {{MediaObservableType::kVideoNonSecureCodec, 3}};
observables3 = {{MediaObservableType::kVideoSecureCodec, 2},
@@ -300,7 +320,7 @@
std::vector<MediaResourceParcel> resources;
// Add secure video codec to client1.
- resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
+ resources = {createSecureVideoCodecResource()};
mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
@@ -322,7 +342,7 @@
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
// Add non-secure video codec to client2.
- resources = {MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
+ resources = {createNonSecureVideoCodecResource()};
mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
@@ -344,24 +364,24 @@
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
// Add secure & non-secure video codecs, plus audio codecs (that's ignored).
- resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(1 /*secure*/, 0 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 0 /*video*/)};
+ resources = {createSecureVideoCodecResource(),
+ createNonSecureVideoCodecResource(),
+ createSecureAudioCodecResource(),
+ createNonSecureAudioCodecResource()};
mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
// Remove one audio codec, should have no event.
- resources = {MediaResource::CodecResource(1 /*secure*/, 0 /*video*/)};
+ resources = {createSecureAudioCodecResource()};
mService->removeResource(kTestPid2, getId(mTestClient3), resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
// Remove the other audio codec and the secure video codec, only secure video codec
// removal should be reported.
- resources = {MediaResource::CodecResource(0 /*secure*/, 0 /*video*/),
- MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
+ resources = {createNonSecureAudioCodecResource(),
+ createSecureVideoCodecResource()};
mService->removeResource(kTestPid2, getId(mTestClient3), resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
@@ -386,10 +406,10 @@
// Add multiple secure & non-secure video codecs, plus audio codecs (that's ignored).
// (ResourceManager will merge these internally.)
- resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 4 /*count*/),
- MediaResource::CodecResource(1 /*secure*/, 0 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 0 /*video*/)};
+ resources = {createSecureVideoCodecResource(),
+ createNonSecureVideoCodecResource(4),
+ createSecureAudioCodecResource(),
+ createNonSecureAudioCodecResource()};
mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
observables2 = {{MediaObservableType::kVideoNonSecureCodec, 4}};
@@ -400,10 +420,10 @@
EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
// Remove one audio codec, 2 secure video codecs and 2 non-secure video codecs.
// 1 secure video codec removal and 2 non-secure video codec removals should be reported.
- resources = {MediaResource::CodecResource(0 /*secure*/, 0 /*video*/),
- MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 2 /*count*/)};
+ resources = {createNonSecureAudioCodecResource(),
+ createSecureVideoCodecResource(),
+ createSecureVideoCodecResource(),
+ createNonSecureVideoCodecResource(2)};
mService->removeResource(kTestPid2, getId(mTestClient3), resources);
observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
observables2 = {{MediaObservableType::kVideoNonSecureCodec, 2}};
@@ -443,8 +463,8 @@
std::vector<MediaResourceParcel> resources;
// Add secure & non-secure video codecs.
- resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
- MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
+ resources = {createSecureVideoCodecResource(),
+ createNonSecureVideoCodecResource()};
mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);