Merge "AudioClient: Fix clang-tidy warnings" into rvc-dev
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index aea28c0..54f1fa2 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -113,6 +113,7 @@
const Trex *mTrex;
off64_t mFirstMoofOffset;
off64_t mCurrentMoofOffset;
+ off64_t mCurrentMoofSize;
off64_t mNextMoofOffset;
uint32_t mCurrentTime; // in media timescale ticks
int32_t mLastParsedTrackId;
@@ -165,8 +166,9 @@
status_t parseTrackFragmentRun(off64_t offset, off64_t size);
status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
- status_t parseClearEncryptedSizes(off64_t offset, bool isSubsampleEncryption, uint32_t flags);
- status_t parseSampleEncryption(off64_t offset);
+ status_t parseClearEncryptedSizes(off64_t offset, bool isSampleEncryption,
+ uint32_t flags, off64_t size);
+ status_t parseSampleEncryption(off64_t offset, off64_t size);
// returns -1 for invalid layer ID
int32_t parseHEVCLayerId(const uint8_t *data, size_t size);
@@ -4859,6 +4861,7 @@
mTrex(trex),
mFirstMoofOffset(firstMoofOffset),
mCurrentMoofOffset(firstMoofOffset),
+ mCurrentMoofSize(0),
mNextMoofOffset(-1),
mCurrentTime(0),
mDefaultEncryptedByteBlock(0),
@@ -5109,6 +5112,9 @@
case FOURCC("moof"): {
off64_t stop_offset = *offset + chunk_size;
*offset = data_offset;
+ if (chunk_type == FOURCC("moof")) {
+ mCurrentMoofSize = chunk_data_size;
+ }
while (*offset < stop_offset) {
status_t err = parseChunk(offset);
if (err != OK) {
@@ -5197,7 +5203,7 @@
case FOURCC("senc"): {
status_t err;
- if ((err = parseSampleEncryption(data_offset)) != OK) {
+ if ((err = parseSampleEncryption(data_offset, chunk_data_size)) != OK) {
return err;
}
*offset += chunk_size;
@@ -5390,11 +5396,11 @@
drmoffset += mCurrentMoofOffset;
- return parseClearEncryptedSizes(drmoffset, false, 0);
+ return parseClearEncryptedSizes(drmoffset, false, 0, mCurrentMoofSize);
}
status_t MPEG4Source::parseClearEncryptedSizes(
- off64_t offset, bool isSubsampleEncryption, uint32_t flags) {
+ off64_t offset, bool isSampleEncryption, uint32_t flags, off64_t size) {
int32_t ivlength;
if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength)) {
@@ -5408,11 +5414,15 @@
}
uint32_t sampleCount = mCurrentSampleInfoCount;
- if (isSubsampleEncryption) {
+ if (isSampleEncryption) {
+ if (size < 4) {
+ return ERROR_MALFORMED;
+ }
if (!mDataSource->getUInt32(offset, &sampleCount)) {
return ERROR_IO;
}
offset += 4;
+ size -= 4;
}
// read CencSampleAuxiliaryDataFormats
@@ -5427,14 +5437,18 @@
}
memset(smpl->iv, 0, 16);
+ if (size < ivlength) {
+ return ERROR_MALFORMED;
+ }
if (mDataSource->readAt(offset, smpl->iv, ivlength) != ivlength) {
return ERROR_IO;
}
offset += ivlength;
+ size -= ivlength;
bool readSubsamples;
- if (isSubsampleEncryption) {
+ if (isSampleEncryption) {
readSubsamples = flags & 2;
} else {
int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
@@ -5446,13 +5460,20 @@
if (readSubsamples) {
uint16_t numsubsamples;
+ if (size < 2) {
+ return ERROR_MALFORMED;
+ }
if (!mDataSource->getUInt16(offset, &numsubsamples)) {
return ERROR_IO;
}
offset += 2;
+ size -= 2;
for (size_t j = 0; j < numsubsamples; j++) {
uint16_t numclear;
uint32_t numencrypted;
+ if (size < 6) {
+ return ERROR_MALFORMED;
+ }
if (!mDataSource->getUInt16(offset, &numclear)) {
return ERROR_IO;
}
@@ -5461,6 +5482,7 @@
return ERROR_IO;
}
offset += 4;
+ size -= 6;
smpl->clearsizes.add(numclear);
smpl->encryptedsizes.add(numencrypted);
}
@@ -5473,12 +5495,15 @@
return OK;
}
-status_t MPEG4Source::parseSampleEncryption(off64_t offset) {
+status_t MPEG4Source::parseSampleEncryption(off64_t offset, off64_t chunk_data_size) {
uint32_t flags;
+ if (chunk_data_size < 4) {
+ return ERROR_MALFORMED;
+ }
if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
return ERROR_MALFORMED;
}
- return parseClearEncryptedSizes(offset + 4, true, flags);
+ return parseClearEncryptedSizes(offset + 4, true, flags, chunk_data_size - 4);
}
status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index fcccf03..6723ec9 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -714,12 +714,8 @@
aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) {
int32_t adjustedFrames = requestedFrames;
const int32_t maximumSize = getBufferCapacity() - mFramesPerBurst;
- // The buffer size can be set to zero.
- // This means that the callback may be called when the internal buffer becomes empty.
- // This will be fine on some devices in ideal circumstances and will result in the
- // lowest possible latency.
- // If there are glitches then they should be detected as XRuns and the size can be increased.
- static const int32_t minimumSize = 0;
+ // Minimum size should be a multiple number of bursts.
+ const int32_t minimumSize = 1 * mFramesPerBurst;
// Clip to minimum size so that rounding up will work better.
adjustedFrames = std::max(minimumSize, adjustedFrames);
@@ -731,12 +727,14 @@
// Round to the next highest burst size.
int32_t numBursts = (adjustedFrames + mFramesPerBurst - 1) / mFramesPerBurst;
adjustedFrames = numBursts * mFramesPerBurst;
+ // Clip just in case maximumSize is not a multiple of mFramesPerBurst.
+ adjustedFrames = std::min(maximumSize, adjustedFrames);
}
// Clip against the actual size from the endpoint.
int32_t actualFrames = 0;
mAudioEndpoint.setBufferSizeInFrames(maximumSize, &actualFrames);
- // actualFrames should be <= maximumSize
+ // actualFrames should be <= actual maximum size of endpoint
adjustedFrames = std::min(actualFrames, adjustedFrames);
mBufferSizeInFrames = adjustedFrames;
diff --git a/media/libaaudio/src/client/IsochronousClockModel.cpp b/media/libaaudio/src/client/IsochronousClockModel.cpp
index bd46d05..f0dcd44 100644
--- a/media/libaaudio/src/client/IsochronousClockModel.cpp
+++ b/media/libaaudio/src/client/IsochronousClockModel.cpp
@@ -47,6 +47,7 @@
, mMarkerNanoTime(0)
, mSampleRate(48000)
, mFramesPerBurst(48)
+ , mBurstPeriodNanos(0) // this will be updated before use
, mMaxMeasuredLatenessNanos(0)
, mLatenessForDriftNanos(kInitialLatenessForDriftNanos)
, mState(STATE_STOPPED)
@@ -57,9 +58,6 @@
}
}
-IsochronousClockModel::~IsochronousClockModel() {
-}
-
void IsochronousClockModel::setPositionAndTime(int64_t framePosition, int64_t nanoTime) {
ALOGV("setPositionAndTime, %lld, %lld", (long long) framePosition, (long long) nanoTime);
mMarkerFramePosition = framePosition;
@@ -186,7 +184,7 @@
// Calculate upper region that will trigger a drift forwards.
mLatenessForDriftNanos = mMaxMeasuredLatenessNanos - (mMaxMeasuredLatenessNanos >> 4);
} else { // decrease
- // If these is an outlier in lateness then mMaxMeasuredLatenessNanos can go high
+ // If this is an outlier in lateness then mMaxMeasuredLatenessNanos can go high
// and stay there. So we slowly reduce mMaxMeasuredLatenessNanos for better
// long term stability. The two opposing forces will keep mMaxMeasuredLatenessNanos
// within a reasonable range.
diff --git a/media/libaaudio/src/client/IsochronousClockModel.h b/media/libaaudio/src/client/IsochronousClockModel.h
index 40f066b..6280013 100644
--- a/media/libaaudio/src/client/IsochronousClockModel.h
+++ b/media/libaaudio/src/client/IsochronousClockModel.h
@@ -35,7 +35,7 @@
public:
IsochronousClockModel();
- virtual ~IsochronousClockModel();
+ virtual ~IsochronousClockModel() = default;
void start(int64_t nanoTime);
void stop(int64_t nanoTime);
@@ -130,6 +130,7 @@
private:
int32_t getLateTimeOffsetNanos() const;
+ void update();
enum clock_model_state_t {
STATE_STOPPED,
@@ -164,7 +165,6 @@
// distribution of timestamps relative to earliest
std::unique_ptr<android::audio_utils::Histogram> mHistogramMicros;
- void update();
};
} /* namespace aaudio */
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 74fa343..6357da4 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -55,6 +55,7 @@
{
sp<IAudioFlinger> af;
sp<AudioFlingerClient> afc;
+ bool reportNoError = false;
{
Mutex::Autolock _l(gLock);
if (gAudioFlinger == 0) {
@@ -70,7 +71,7 @@
if (gAudioFlingerClient == NULL) {
gAudioFlingerClient = new AudioFlingerClient();
} else {
- reportError(NO_ERROR);
+ reportNoError = true;
}
binder->linkToDeath(gAudioFlingerClient);
gAudioFlinger = interface_cast<IAudioFlinger>(binder);
@@ -86,6 +87,7 @@
af->registerClient(afc);
IPCThreadState::self()->restoreCallingIdentity(token);
}
+ if (reportNoError) reportError(NO_ERROR);
return af;
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 5c891e2..03c16f3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1185,15 +1185,21 @@
}
AutoMutex lock(mHardwareLock);
+ sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
+ if (primaryDev == nullptr) {
+ ALOGW("%s: no primary HAL device", __func__);
+ return INVALID_OPERATION;
+ }
mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
+ ret = primaryDev->setMicMute(state);
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
- status_t result = dev->setMicMute(state);
- if (result != NO_ERROR) {
- ret = result;
+ if (dev != primaryDev) {
+ (void)dev->setMicMute(state);
}
}
mHardwareStatus = AUDIO_HW_IDLE;
+ ALOGW_IF(ret != NO_ERROR, "%s: error %d setting state to HAL", __func__, ret);
return ret;
}
@@ -1203,20 +1209,18 @@
if (ret != NO_ERROR) {
return false;
}
- bool mute = true;
- bool state = AUDIO_MODE_INVALID;
AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
- for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
- sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
- status_t result = dev->getMicMute(&state);
- if (result == NO_ERROR) {
- mute = mute && state;
- }
+ sp<DeviceHalInterface> primaryDev = mPrimaryHardwareDev->hwDevice();
+ if (primaryDev == nullptr) {
+ ALOGW("%s: no primary HAL device", __func__);
+ return false;
}
+ bool state;
+ mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
+ ret = primaryDev->getMicMute(&state);
mHardwareStatus = AUDIO_HW_IDLE;
-
- return mute;
+ ALOGE_IF(ret != NO_ERROR, "%s: error %d getting state from HAL", __func__, ret);
+ return (ret == NO_ERROR) && state;
}
void AudioFlinger::setRecordSilenced(audio_port_handle_t portId, bool silenced)
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index cc369fa..10b653e 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -841,13 +841,6 @@
itDuration++; itSize++;
}
- c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
- dynamicDepthEntries.data(), dynamicDepthEntries.size());
- c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
- dynamicDepthMinDurationEntries.data(), dynamicDepthMinDurationEntries.size());
- c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
- dynamicDepthStallDurationEntries.data(), dynamicDepthStallDurationEntries.size());
-
std::vector<int32_t> supportedChTags;
supportedChTags.reserve(chTags.count + 3);
supportedChTags.insert(supportedChTags.end(), chTags.data.i32,
@@ -855,6 +848,12 @@
supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS);
supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS);
supportedChTags.push_back(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS);
+ c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS,
+ dynamicDepthEntries.data(), dynamicDepthEntries.size());
+ c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS,
+ dynamicDepthMinDurationEntries.data(), dynamicDepthMinDurationEntries.size());
+ c.update(ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS,
+ dynamicDepthStallDurationEntries.data(), dynamicDepthStallDurationEntries.size());
c.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, supportedChTags.data(),
supportedChTags.size());
diff --git a/services/camera/libcameraservice/tests/Android.mk b/services/camera/libcameraservice/tests/Android.mk
index fa5d69e..3ead715 100644
--- a/services/camera/libcameraservice/tests/Android.mk
+++ b/services/camera/libcameraservice/tests/Android.mk
@@ -48,6 +48,8 @@
LOCAL_CFLAGS += -Wall -Wextra -Werror
+LOCAL_SANITIZE := address
+
LOCAL_MODULE:= cameraservice_test
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_MODULE_TAGS := tests
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index a8f6889..855b5ab 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -40,8 +40,15 @@
*/
struct TestDeviceInterface : public device::V3_2::ICameraDevice {
std::vector<hardware::hidl_string> mDeviceNames;
+ android::hardware::hidl_vec<uint8_t> mCharacteristics;
+
+ TestDeviceInterface(std::vector<hardware::hidl_string> deviceNames,
+ android::hardware::hidl_vec<uint8_t> chars) :
+ mDeviceNames(deviceNames), mCharacteristics(chars) {}
+
TestDeviceInterface(std::vector<hardware::hidl_string> deviceNames) :
mDeviceNames(deviceNames) {}
+
using getResourceCost_cb = std::function<void(
hardware::camera::common::V1_0::Status status,
const hardware::camera::common::V1_0::CameraResourceCost& resourceCost)>;
@@ -58,8 +65,7 @@
const hardware::hidl_vec<uint8_t>& cameraCharacteristics)>;
hardware::Return<void> getCameraCharacteristics(
getCameraCharacteristics_cb _hidl_cb) override {
- hardware::hidl_vec<uint8_t> cameraCharacteristics;
- _hidl_cb(Status::OK, cameraCharacteristics);
+ _hidl_cb(Status::OK, mCharacteristics);
return hardware::Void();
}
@@ -100,6 +106,13 @@
mDeviceInterface(new TestDeviceInterface(devices)),
mVendorTagSections (vendorSection) {}
+ TestICameraProvider(const std::vector<hardware::hidl_string> &devices,
+ const hardware::hidl_vec<common::V1_0::VendorTagSection> &vendorSection,
+ android::hardware::hidl_vec<uint8_t> chars) :
+ mDeviceNames(devices),
+ mDeviceInterface(new TestDeviceInterface(devices, chars)),
+ mVendorTagSections (vendorSection) {}
+
virtual hardware::Return<Status> setCallback(
const sp<provider::V2_4::ICameraProviderCallback>& callbacks) override {
mCalledCounter[SET_CALLBACK]++;
@@ -243,6 +256,52 @@
void onNewProviderRegistered() override {}
};
+TEST(CameraProviderManagerTest, InitializeDynamicDepthTest) {
+ std::vector<hardware::hidl_string> deviceNames;
+ deviceNames.push_back("device@3.2/test/0");
+ hardware::hidl_vec<common::V1_0::VendorTagSection> vendorSection;
+ status_t res;
+ sp<CameraProviderManager> providerManager = new CameraProviderManager();
+ sp<TestStatusListener> statusListener = new TestStatusListener();
+ TestInteractionProxy serviceProxy;
+
+ android::hardware::hidl_vec<uint8_t> chars;
+ CameraMetadata meta;
+ int32_t charKeys[] = { ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS };
+ meta.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, charKeys,
+ sizeof(charKeys) / sizeof(charKeys[0]));
+ uint8_t depthIsExclusive = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE;
+ meta.update(ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, &depthIsExclusive, 1);
+ int32_t sizes[] = { HAL_PIXEL_FORMAT_BLOB,
+ 640, 480, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT };
+ meta.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, sizes,
+ sizeof(sizes) / sizeof(sizes[0]));
+ sizes[0] = HAL_PIXEL_FORMAT_Y16;
+ meta.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, sizes,
+ sizeof(sizes) / sizeof(sizes[0]));
+ int64_t durations[] = { HAL_PIXEL_FORMAT_BLOB, 640, 480, 0 };
+ meta.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, durations,
+ sizeof(durations) / sizeof(durations[0]));
+ meta.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, durations,
+ sizeof(durations) / sizeof(durations[0]));
+ durations[0]= HAL_PIXEL_FORMAT_Y16;
+ meta.update(ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS, durations,
+ sizeof(durations) / sizeof(durations[0]));
+ meta.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS, durations,
+ sizeof(durations) / sizeof(durations[0]));
+ camera_metadata_t* metaBuffer = const_cast<camera_metadata_t*>(meta.getAndLock());
+ chars.setToExternal(reinterpret_cast<uint8_t*>(metaBuffer),
+ get_camera_metadata_size(metaBuffer));
+
+ sp<TestICameraProvider> provider = new TestICameraProvider(deviceNames,
+ vendorSection, chars);
+ serviceProxy.setProvider(provider);
+
+ res = providerManager->initialize(statusListener, &serviceProxy);
+ ASSERT_EQ(res, OK) << "Unable to initialize provider manager";
+}
+
TEST(CameraProviderManagerTest, InitializeTest) {
std::vector<hardware::hidl_string> deviceNames;
deviceNames.push_back("device@3.2/test/0");
diff --git a/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp b/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp
index c638d40..3c187cd 100644
--- a/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp
+++ b/services/camera/libcameraservice/tests/RotateAndCropMapperTest.cpp
@@ -38,10 +38,9 @@
#define EXPECT_EQUAL_WITHIN_N(vec, array, N, msg) \
{ \
- std::vector<int32_t> vec_diff; \
- std::transform(vec.begin(), vec.end(), array, \
- std::back_inserter(vec_diff), std::minus()); \
- EXPECT_THAT(vec_diff, Each(AllOf(Ge(-N), Le(N)))) << msg; \
+ for (size_t i = 0; i < vec.size(); i++) { \
+ EXPECT_THAT(vec[i] - array[i], AllOf(Ge(-N), Le(N))) << msg " failed at index:" << i; \
+ } \
}
int32_t testActiveArray[] = {100, 100, 4000, 3000};
diff --git a/services/minijail/Android.bp b/services/minijail/Android.bp
index 0713a87..5ea6d1e 100644
--- a/services/minijail/Android.bp
+++ b/services/minijail/Android.bp
@@ -39,4 +39,5 @@
srcs: [
"av_services_minijail_unittest.cpp",
],
+ test_suites: ["device-tests"],
}
diff --git a/services/minijail/TEST_MAPPING b/services/minijail/TEST_MAPPING
new file mode 100644
index 0000000..0d89760
--- /dev/null
+++ b/services/minijail/TEST_MAPPING
@@ -0,0 +1,5 @@
+{
+ "presubmit": [
+ { "name": "libavservices_minijail_unittest" }
+ ]
+}
diff --git a/services/minijail/av_services_minijail_unittest.cpp b/services/minijail/av_services_minijail_unittest.cpp
index 31313f8..896a764 100644
--- a/services/minijail/av_services_minijail_unittest.cpp
+++ b/services/minijail/av_services_minijail_unittest.cpp
@@ -34,13 +34,32 @@
"mmap: 1\n"
"munmap: 1\n";
+ const std::string third_policy_ =
+ "open: 1\n"
+ "close: 1\n";
+
const std::string full_policy_ = base_policy_ + std::string("\n") + additional_policy_;
+ const std::string triple_policy_ = base_policy_ +
+ std::string("\n") + additional_policy_ +
+ std::string("\n") + third_policy_;
};
TEST_F(WritePolicyTest, OneFile)
{
std::string final_string;
- android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, std::string()));
+ // vector with an empty pathname
+ android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {std::string()}));
+ EXPECT_LE(0, fd.get());
+ bool success = android::base::ReadFdToString(fd.get(), &final_string);
+ EXPECT_TRUE(success);
+ EXPECT_EQ(final_string, base_policy_);
+}
+
+TEST_F(WritePolicyTest, OneFileAlternate)
+{
+ std::string final_string;
+ // empty vector
+ android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {}));
EXPECT_LE(0, fd.get());
bool success = android::base::ReadFdToString(fd.get(), &final_string);
EXPECT_TRUE(success);
@@ -50,9 +69,19 @@
TEST_F(WritePolicyTest, TwoFiles)
{
std::string final_string;
- android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, additional_policy_));
+ android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {additional_policy_}));
EXPECT_LE(0, fd.get());
bool success = android::base::ReadFdToString(fd.get(), &final_string);
EXPECT_TRUE(success);
EXPECT_EQ(final_string, full_policy_);
}
+
+TEST_F(WritePolicyTest, ThreeFiles)
+{
+ std::string final_string;
+ android::base::unique_fd fd(android::WritePolicyToPipe(base_policy_, {additional_policy_, third_policy_}));
+ EXPECT_LE(0, fd.get());
+ bool success = android::base::ReadFdToString(fd.get(), &final_string);
+ EXPECT_TRUE(success);
+ EXPECT_EQ(final_string, triple_policy_);
+}
diff --git a/services/minijail/minijail.cpp b/services/minijail/minijail.cpp
index f213287..c7832b9 100644
--- a/services/minijail/minijail.cpp
+++ b/services/minijail/minijail.cpp
@@ -29,7 +29,7 @@
namespace android {
int WritePolicyToPipe(const std::string& base_policy_content,
- const std::string& additional_policy_content)
+ const std::vector<std::string>& additional_policy_contents)
{
int pipefd[2];
if (pipe(pipefd) == -1) {
@@ -40,9 +40,11 @@
base::unique_fd write_end(pipefd[1]);
std::string content = base_policy_content;
- if (additional_policy_content.length() > 0) {
- content += "\n";
- content += additional_policy_content;
+ for (auto one_content : additional_policy_contents) {
+ if (one_content.length() > 0) {
+ content += "\n";
+ content += one_content;
+ }
}
if (!base::WriteStringToFd(content, write_end.get())) {
@@ -53,29 +55,34 @@
return pipefd[0];
}
-void SetUpMinijail(const std::string& base_policy_path, const std::string& additional_policy_path)
+void SetUpMinijail(const std::string& base_policy_path,
+ const std::string& additional_policy_path)
{
- // No seccomp policy defined for this architecture.
- if (access(base_policy_path.c_str(), R_OK) == -1) {
- LOG(WARNING) << "No seccomp policy defined for this architecture.";
- return;
- }
+ SetUpMinijailList(base_policy_path, {additional_policy_path});
+}
+void SetUpMinijailList(const std::string& base_policy_path,
+ const std::vector<std::string>& additional_policy_paths)
+{
std::string base_policy_content;
- std::string additional_policy_content;
+ std::vector<std::string> additional_policy_contents;
if (!base::ReadFileToString(base_policy_path, &base_policy_content,
false /* follow_symlinks */)) {
LOG(FATAL) << "Could not read base policy file '" << base_policy_path << "'";
}
- if (additional_policy_path.length() > 0 &&
- !base::ReadFileToString(additional_policy_path, &additional_policy_content,
- false /* follow_symlinks */)) {
- LOG(WARNING) << "Could not read additional policy file '" << additional_policy_path << "'";
- additional_policy_content = std::string();
+ for (auto one_policy_path : additional_policy_paths) {
+ std::string one_policy_content;
+ if (one_policy_path.length() > 0 &&
+ !base::ReadFileToString(one_policy_path, &one_policy_content,
+ false /* follow_symlinks */)) {
+ // TODO: harder failure (fatal unless ENOENT?)
+ LOG(WARNING) << "Could not read additional policy file '" << one_policy_path << "'";
+ }
+ additional_policy_contents.push_back(one_policy_content);
}
- base::unique_fd policy_fd(WritePolicyToPipe(base_policy_content, additional_policy_content));
+ base::unique_fd policy_fd(WritePolicyToPipe(base_policy_content, additional_policy_contents));
if (policy_fd.get() == -1) {
LOG(FATAL) << "Could not write seccomp policy to fd";
}
diff --git a/services/minijail/minijail.h b/services/minijail/minijail.h
index c8a2149..298af86 100644
--- a/services/minijail/minijail.h
+++ b/services/minijail/minijail.h
@@ -16,11 +16,15 @@
#define AV_SERVICES_MINIJAIL_MINIJAIL
#include <string>
+#include <vector>
namespace android {
int WritePolicyToPipe(const std::string& base_policy_content,
- const std::string& additional_policy_content);
-void SetUpMinijail(const std::string& base_policy_path, const std::string& additional_policy_path);
+ const std::vector<std::string>& additional_policy_contents);
+void SetUpMinijail(const std::string& base_policy_path,
+ const std::string& additional_policy_path);
+void SetUpMinijailList(const std::string& base_policy_path,
+ const std::vector<std::string>& additional_policy_paths);
}
#endif // AV_SERVICES_MINIJAIL_MINIJAIL