Merge "AudioFlinger: Prevent FastMixer for A2DP sink"
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 4ef1f47..73dc93b 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -201,9 +201,12 @@
sp<IDrmFactory> factory = IDrmFactory::getService("drm");
if (factory == NULL) {
ALOGE("Failed to make drm factory");
+ return NULL;
}
+
ALOGD("makeDrmFactory: service is %s",
factory->isRemote() ? "Remote" : "Not Remote");
+
return factory;
}
diff --git a/media/libaaudio/examples/write_sine/src/write_sine.cpp b/media/libaaudio/examples/write_sine/src/write_sine.cpp
index 090f371..a16dfdc 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine.cpp
@@ -32,15 +32,9 @@
case AAUDIO_SHARING_MODE_EXCLUSIVE:
modeText = "EXCLUSIVE";
break;
- case AAUDIO_SHARING_MODE_LEGACY:
- modeText = "LEGACY";
- break;
case AAUDIO_SHARING_MODE_SHARED:
modeText = "SHARED";
break;
- case AAUDIO_SHARING_MODE_PUBLIC_MIX:
- modeText = "PUBLIC_MIX";
- break;
default:
break;
}
@@ -61,8 +55,7 @@
aaudio_audio_format_t actualDataFormat = AAUDIO_FORMAT_PCM16;
const aaudio_sharing_mode_t requestedSharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE;
- //const aaudio_sharing_mode_t requestedSharingMode = AAUDIO_SHARING_MODE_LEGACY;
- aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_LEGACY;
+ aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
AAudioStreamBuilder aaudioBuilder = AAUDIO_STREAM_BUILDER_NONE;
AAudioStream aaudioStream = AAUDIO_STREAM_NONE;
diff --git a/media/libaaudio/examples/write_sine/src/write_sine_threaded.cpp b/media/libaaudio/examples/write_sine/src/write_sine_threaded.cpp
index 4ea2807..7cb14f9 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine_threaded.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine_threaded.cpp
@@ -29,7 +29,7 @@
#define NUM_SECONDS 10
#define SHARING_MODE AAUDIO_SHARING_MODE_EXCLUSIVE
-//#define SHARING_MODE AAUDIO_SHARING_MODE_LEGACY
+//#define SHARING_MODE AAUDIO_SHARING_MODE_SHARED
// Prototype for a callback.
typedef int audio_callback_proc_t(float *outputBuffer,
diff --git a/media/libaaudio/include/aaudio/AAudioDefinitions.h b/media/libaaudio/include/aaudio/AAudioDefinitions.h
index 979b8c9..5b72b94 100644
--- a/media/libaaudio/include/aaudio/AAudioDefinitions.h
+++ b/media/libaaudio/include/aaudio/AAudioDefinitions.h
@@ -124,14 +124,8 @@
AAUDIO_STREAM_STATE_CLOSED,
} aaudio_stream_state_t;
-// TODO review API
typedef enum {
/**
- * This will use an AudioTrack object for playing audio
- * and an AudioRecord for recording data.
- */
- AAUDIO_SHARING_MODE_LEGACY,
- /**
* This will be the only stream using a particular source or sink.
* This mode will provide the lowest possible latency.
* You should close EXCLUSIVE streams immediately when you are not using them.
@@ -142,12 +136,7 @@
* This will have higher latency than the EXCLUSIVE mode.
*/
AAUDIO_SHARING_MODE_SHARED,
- /**
- * Multiple applications will do their own mixing into a memory mapped buffer.
- * It may be possible for malicious applications to read the data produced by
- * other apps. So do not use this for private data such as telephony or messaging.
- */
- AAUDIO_SHARING_MODE_PUBLIC_MIX,
+
AAUDIO_SHARING_MODE_COUNT // This should always be last.
} aaudio_sharing_mode_t;
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 8e4aa05..acfed97 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -257,7 +257,7 @@
aaudio_sample_rate_t mSampleRate = AAUDIO_UNSPECIFIED;
aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
aaudio_device_id_t mDeviceId = AAUDIO_UNSPECIFIED;
- aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_LEGACY;
+ aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
aaudio_audio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED;
aaudio_direction_t mDirection = AAUDIO_DIRECTION_OUTPUT;
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index decd53c..5a54e62 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -42,13 +42,12 @@
}
aaudio_result_t AudioStreamBuilder::build(AudioStream** streamPtr) {
- // TODO Is there a better place to put the code that decides which class to use?
AudioStream* audioStream = nullptr;
const aaudio_sharing_mode_t sharingMode = getSharingMode();
switch (getDirection()) {
case AAUDIO_DIRECTION_INPUT:
switch (sharingMode) {
- case AAUDIO_SHARING_MODE_LEGACY:
+ case AAUDIO_SHARING_MODE_SHARED:
audioStream = new(std::nothrow) AudioStreamRecord();
break;
default:
@@ -59,7 +58,7 @@
break;
case AAUDIO_DIRECTION_OUTPUT:
switch (sharingMode) {
- case AAUDIO_SHARING_MODE_LEGACY:
+ case AAUDIO_SHARING_MODE_SHARED:
audioStream = new(std::nothrow) AudioStreamTrack();
break;
case AAUDIO_SHARING_MODE_EXCLUSIVE:
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.h b/media/libaaudio/src/core/AudioStreamBuilder.h
index e72633d..f366688 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.h
+++ b/media/libaaudio/src/core/AudioStreamBuilder.h
@@ -107,7 +107,7 @@
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
aaudio_sample_rate_t mSampleRate = AAUDIO_UNSPECIFIED;
aaudio_device_id_t mDeviceId = AAUDIO_DEVICE_UNSPECIFIED;
- aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_LEGACY;
+ aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
aaudio_audio_format_t mFormat = AAUDIO_FORMAT_UNSPECIFIED;
aaudio_direction_t mDirection = AAUDIO_DIRECTION_OUTPUT;
aaudio_size_frames_t mBufferCapacity = AAUDIO_UNSPECIFIED;
diff --git a/media/libaaudio/tests/Android.mk b/media/libaaudio/tests/Android.mk
index 24dad4a..7899cf5 100644
--- a/media/libaaudio/tests/Android.mk
+++ b/media/libaaudio/tests/Android.mk
@@ -6,19 +6,6 @@
frameworks/av/media/libaaudio/include \
frameworks/av/media/libaaudio/src/core \
frameworks/av/media/libaaudio/src/utility
-LOCAL_SRC_FILES := test_aaudio_api.cpp
-LOCAL_SHARED_LIBRARIES := libaudioclient libaudioutils libbinder \
- libcutils liblog libmedia libutils
-LOCAL_STATIC_LIBRARIES := libaaudio
-LOCAL_MODULE := test_aaudio_api
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src/core \
- frameworks/av/media/libaaudio/src/utility
LOCAL_SRC_FILES:= test_handle_tracker.cpp
LOCAL_SHARED_LIBRARIES := libaudioclient libaudioutils libbinder \
libcutils liblog libmedia libutils
diff --git a/media/libaaudio/tests/test_aaudio_api.cpp b/media/libaaudio/tests/test_aaudio_api.cpp
deleted file mode 100644
index 7db3688..0000000
--- a/media/libaaudio/tests/test_aaudio_api.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Unit tests for AAudio 'C' API.
-
-#include <stdlib.h>
-#include <math.h>
-
-#include <gtest/gtest.h>
-
-#include <aaudio/AAudioDefinitions.h>
-#include <aaudio/AAudio.h>
-#include "AAudioUtilities.h"
-
-#define DEFAULT_STATE_TIMEOUT (500 * AAUDIO_NANOS_PER_MILLISECOND)
-
-// Test AAudioStreamBuilder
-TEST(test_aaudio_api, aaudio_stream_builder) {
- const aaudio_sample_rate_t requestedSampleRate1 = 48000;
- const aaudio_sample_rate_t requestedSampleRate2 = 44100;
- const int32_t requestedSamplesPerFrame = 2;
- const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM16;
-
- aaudio_sample_rate_t sampleRate = 0;
- int32_t samplesPerFrame = 0;
- aaudio_audio_format_t actualDataFormat;
- AAudioStreamBuilder aaudioBuilder1;
- AAudioStreamBuilder aaudioBuilder2;
-
- aaudio_result_t result = AAUDIO_OK;
-
- // Use an AAudioStreamBuilder to define the stream.
- result = AAudio_createStreamBuilder(&aaudioBuilder1);
- ASSERT_EQ(AAUDIO_OK, result);
-
- // Request stream properties.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSampleRate(aaudioBuilder1, requestedSampleRate1));
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSamplesPerFrame(aaudioBuilder1, requestedSamplesPerFrame));
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setFormat(aaudioBuilder1, requestedDataFormat));
-
- // Check to make sure builder saved the properties.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder1, &sampleRate));
- EXPECT_EQ(requestedSampleRate1, sampleRate);
-
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSamplesPerFrame(aaudioBuilder1, &samplesPerFrame));
- EXPECT_EQ(requestedSamplesPerFrame, samplesPerFrame);
-
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getFormat(aaudioBuilder1, &actualDataFormat));
- EXPECT_EQ(requestedDataFormat, actualDataFormat);
-
- result = AAudioStreamBuilder_getSampleRate(0x0BADCAFE, &sampleRate); // ridiculous token
- EXPECT_EQ(AAUDIO_ERROR_INVALID_HANDLE, result);
-
- // Create a second builder and make sure they do not collide.
- ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder2));
- ASSERT_NE(aaudioBuilder1, aaudioBuilder2);
-
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSampleRate(aaudioBuilder2, requestedSampleRate2));
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder1, &sampleRate));
- EXPECT_EQ(requestedSampleRate1, sampleRate);
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder2, &sampleRate));
- EXPECT_EQ(requestedSampleRate2, sampleRate);
-
- // Delete the builder.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder1));
-
- // Now it should no longer be valid.
- // Note that test assumes we are using the HandleTracker. If we use plain pointers
- // then it will be difficult to detect this kind of error.
- result = AAudioStreamBuilder_getSampleRate(aaudioBuilder1, &sampleRate); // stale token
- EXPECT_EQ(AAUDIO_ERROR_INVALID_HANDLE, result);
-
- // Second builder should still be valid.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_getSampleRate(aaudioBuilder2, &sampleRate));
- EXPECT_EQ(requestedSampleRate2, sampleRate);
-
- // Delete the second builder.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder2));
-
- // Now it should no longer be valid. Assumes HandlerTracker used.
- EXPECT_EQ(AAUDIO_ERROR_INVALID_HANDLE, AAudioStreamBuilder_getSampleRate(aaudioBuilder2, &sampleRate));
-}
-
-// Test creating a default stream with everything unspecified.
-TEST(test_aaudio_api, aaudio_stream_unspecified) {
- AAudioStreamBuilder aaudioBuilder;
- AAudioStream aaudioStream;
- aaudio_result_t result = AAUDIO_OK;
-
- // Use an AAudioStreamBuilder to define the stream.
- result = AAudio_createStreamBuilder(&aaudioBuilder);
- ASSERT_EQ(AAUDIO_OK, result);
-
- // Create an AAudioStream using the Builder.
- ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
-
- // Cleanup
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
- EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
-}
-
-// Test Writing to an AAudioStream
-void runtest_aaudio_stream(aaudio_sharing_mode_t requestedSharingMode) {
- const aaudio_sample_rate_t requestedSampleRate = 48000;
- const aaudio_sample_rate_t requestedSamplesPerFrame = 2;
- const aaudio_audio_format_t requestedDataFormat = AAUDIO_FORMAT_PCM16;
-
- aaudio_sample_rate_t actualSampleRate = -1;
- int32_t actualSamplesPerFrame = -1;
- aaudio_audio_format_t actualDataFormat = AAUDIO_FORMAT_INVALID;
- aaudio_sharing_mode_t actualSharingMode;
- aaudio_size_frames_t framesPerBurst = -1;
- int writeLoops = 0;
-
- aaudio_size_frames_t framesWritten = 0;
- aaudio_size_frames_t framesPrimed = 0;
- aaudio_position_frames_t framesTotal = 0;
- aaudio_position_frames_t aaudioFramesRead = 0;
- aaudio_position_frames_t aaudioFramesRead1 = 0;
- aaudio_position_frames_t aaudioFramesRead2 = 0;
- aaudio_position_frames_t aaudioFramesWritten = 0;
-
- aaudio_nanoseconds_t timeoutNanos;
-
- aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNINITIALIZED;
- AAudioStreamBuilder aaudioBuilder;
- AAudioStream aaudioStream;
-
- aaudio_result_t result = AAUDIO_OK;
-
- // Use an AAudioStreamBuilder to define the stream.
- result = AAudio_createStreamBuilder(&aaudioBuilder);
- ASSERT_EQ(AAUDIO_OK, result);
-
- // Request stream properties.
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSampleRate(aaudioBuilder, requestedSampleRate));
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSamplesPerFrame(aaudioBuilder, requestedSamplesPerFrame));
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setFormat(aaudioBuilder, requestedDataFormat));
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_setSharingMode(aaudioBuilder, requestedSharingMode));
-
- // Create an AAudioStream using the Builder.
- ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
-
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getState(aaudioStream, &state));
- EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);
-
- // Check to see what kind of stream we actually got.
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getSampleRate(aaudioStream, &actualSampleRate));
- ASSERT_TRUE(actualSampleRate >= 44100 && actualSampleRate <= 96000); // TODO what is range?
-
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getSamplesPerFrame(aaudioStream, &actualSamplesPerFrame));
- ASSERT_TRUE(actualSamplesPerFrame >= 1 && actualSamplesPerFrame <= 16); // TODO what is max?
-
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getSharingMode(aaudioStream, &actualSharingMode));
- ASSERT_TRUE(actualSharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE
- || actualSharingMode == AAUDIO_SHARING_MODE_LEGACY);
-
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getFormat(aaudioStream, &actualDataFormat));
- EXPECT_NE(AAUDIO_FORMAT_INVALID, actualDataFormat);
-
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesPerBurst(aaudioStream, &framesPerBurst));
- ASSERT_TRUE(framesPerBurst >= 16 && framesPerBurst <= 1024); // TODO what is min/max?
-
- // Allocate a buffer for the audio data.
- // TODO handle possibility of other data formats
- ASSERT_TRUE(actualDataFormat == AAUDIO_FORMAT_PCM16);
- size_t dataSizeSamples = framesPerBurst * actualSamplesPerFrame;
- int16_t *data = new int16_t[dataSizeSamples];
- ASSERT_TRUE(nullptr != data);
- memset(data, 0, sizeof(int16_t) * dataSizeSamples);
-
- // Prime the buffer.
- timeoutNanos = 0;
- do {
- framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
- // There should be some room for priming the buffer.
- framesTotal += framesWritten;
- ASSERT_GE(framesWritten, 0);
- ASSERT_LE(framesWritten, framesPerBurst);
- } while (framesWritten > 0);
- ASSERT_TRUE(framesTotal > 0);
-
- // Start/write/pause more than once to see if it fails after the first time.
- // Write some data and measure the rate to see if the timing is OK.
- for (int numLoops = 0; numLoops < 2; numLoops++) {
- // Start and wait for server to respond.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_requestStart(aaudioStream));
- ASSERT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
- AAUDIO_STREAM_STATE_STARTING,
- &state,
- DEFAULT_STATE_TIMEOUT));
- EXPECT_EQ(AAUDIO_STREAM_STATE_STARTED, state);
-
- // Write some data while we are running. Read counter should be advancing.
- writeLoops = 1 * actualSampleRate / framesPerBurst; // 1 second
- ASSERT_LT(2, writeLoops); // detect absurdly high framesPerBurst
- timeoutNanos = 10 * AAUDIO_NANOS_PER_SECOND * framesPerBurst / actualSampleRate; // bursts
- framesWritten = 1;
- ASSERT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
- aaudioFramesRead1 = aaudioFramesRead;
- aaudio_nanoseconds_t beginTime = AAudio_getNanoseconds(AAUDIO_CLOCK_MONOTONIC);
- do {
- framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
- ASSERT_GE(framesWritten, 0);
- ASSERT_LE(framesWritten, framesPerBurst);
-
- framesTotal += framesWritten;
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesWritten(aaudioStream, &aaudioFramesWritten));
- EXPECT_EQ(framesTotal, aaudioFramesWritten);
-
- // Try to get a more accurate measure of the sample rate.
- if (beginTime == 0) {
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
- if (aaudioFramesRead > aaudioFramesRead1) { // is read pointer advancing
- beginTime = AAudio_getNanoseconds(AAUDIO_CLOCK_MONOTONIC);
- aaudioFramesRead1 = aaudioFramesRead;
- }
- }
- } while (framesWritten > 0 && writeLoops-- > 0);
-
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead2));
- aaudio_nanoseconds_t endTime = AAudio_getNanoseconds(AAUDIO_CLOCK_MONOTONIC);
- ASSERT_GT(aaudioFramesRead2, 0);
- ASSERT_GT(aaudioFramesRead2, aaudioFramesRead1);
- ASSERT_LE(aaudioFramesRead2, aaudioFramesWritten);
-
- // TODO why is legacy so inaccurate?
- const double rateTolerance = 200.0; // arbitrary tolerance for sample rate
- if (requestedSharingMode != AAUDIO_SHARING_MODE_LEGACY) {
- // Calculate approximate sample rate and compare with stream rate.
- double seconds = (endTime - beginTime) / (double) AAUDIO_NANOS_PER_SECOND;
- double measuredRate = (aaudioFramesRead2 - aaudioFramesRead1) / seconds;
- ASSERT_NEAR(actualSampleRate, measuredRate, rateTolerance);
- }
-
- // Request async pause and wait for server to say that it has completed the pause.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_requestPause(aaudioStream));
- EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
- AAUDIO_STREAM_STATE_PAUSING,
- &state,
- DEFAULT_STATE_TIMEOUT));
- EXPECT_EQ(AAUDIO_STREAM_STATE_PAUSED, state);
- }
-
- // Make sure the read counter is not advancing when we are paused.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
- ASSERT_GE(aaudioFramesRead, aaudioFramesRead2); // monotonic increase
-
- // Use this to sleep by waiting for something that won't happen.
- AAudioStream_waitForStateChange(aaudioStream, AAUDIO_STREAM_STATE_PAUSED, &state, timeoutNanos);
- ASSERT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead2));
- EXPECT_EQ(aaudioFramesRead, aaudioFramesRead2);
-
- // ------------------- TEST FLUSH -----------------
- // Prime the buffer.
- timeoutNanos = 0;
- writeLoops = 100;
- do {
- framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
- framesTotal += framesWritten;
- } while (framesWritten > 0 && writeLoops-- > 0);
- EXPECT_EQ(0, framesWritten);
-
- // Flush and wait for server to respond.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_requestFlush(aaudioStream));
- EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
- AAUDIO_STREAM_STATE_FLUSHING,
- &state,
- DEFAULT_STATE_TIMEOUT));
- EXPECT_EQ(AAUDIO_STREAM_STATE_FLUSHED, state);
-
- // After a flush, the read counter should be caught up with the write counter.
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesWritten(aaudioStream, &aaudioFramesWritten));
- EXPECT_EQ(framesTotal, aaudioFramesWritten);
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getFramesRead(aaudioStream, &aaudioFramesRead));
- EXPECT_EQ(aaudioFramesRead, aaudioFramesWritten);
-
- // The buffer should be empty after a flush so we should be able to write.
- framesWritten = AAudioStream_write(aaudioStream, data, framesPerBurst, timeoutNanos);
- // There should be some room for priming the buffer.
- ASSERT_TRUE(framesWritten > 0 && framesWritten <= framesPerBurst);
-
- EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
-}
-
-// Test Writing to an AAudioStream using LEGACY sharing mode.
-TEST(test_aaudio_api, aaudio_stream_legacy) {
- runtest_aaudio_stream(AAUDIO_SHARING_MODE_LEGACY);
-}
-
-// Test Writing to an AAudioStream using EXCLUSIVE sharing mode.
-TEST(test_aaudio_api, aaudio_stream_exclusive) {
- runtest_aaudio_stream(AAUDIO_SHARING_MODE_EXCLUSIVE);
-}
-
-#define AAUDIO_THREAD_ANSWER 1826375
-#define AAUDIO_THREAD_DURATION_MSEC 500
-
-static void *TestAAudioStreamThreadProc(void *arg) {
- AAudioStream aaudioStream = (AAudioStream) reinterpret_cast<size_t>(arg);
- aaudio_stream_state_t state;
-
- // Use this to sleep by waiting for something that won't happen.
- EXPECT_EQ(AAUDIO_OK, AAudioStream_getState(aaudioStream, &state));
- AAudioStream_waitForStateChange(aaudioStream, AAUDIO_STREAM_STATE_PAUSED, &state,
- AAUDIO_THREAD_DURATION_MSEC * AAUDIO_NANOS_PER_MILLISECOND);
- return reinterpret_cast<void *>(AAUDIO_THREAD_ANSWER);
-}
-
-// Test creating a stream related thread.
-TEST(test_aaudio_api, aaudio_stream_thread_basic) {
- AAudioStreamBuilder aaudioBuilder;
- AAudioStream aaudioStream;
- aaudio_result_t result = AAUDIO_OK;
- void *threadResult;
-
- // Use an AAudioStreamBuilder to define the stream.
- result = AAudio_createStreamBuilder(&aaudioBuilder);
- ASSERT_EQ(AAUDIO_OK, result);
-
- // Create an AAudioStream using the Builder.
- ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
-
- // Start a thread.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_createThread(aaudioStream,
- 10 * AAUDIO_NANOS_PER_MILLISECOND,
- TestAAudioStreamThreadProc,
- reinterpret_cast<void *>(aaudioStream)));
- // Thread already started.
- ASSERT_NE(AAUDIO_OK, AAudioStream_createThread(aaudioStream, // should fail!
- 10 * AAUDIO_NANOS_PER_MILLISECOND,
- TestAAudioStreamThreadProc,
- reinterpret_cast<void *>(aaudioStream)));
-
- // Wait for the thread to finish.
- ASSERT_EQ(AAUDIO_OK, AAudioStream_joinThread(aaudioStream,
- &threadResult, 2 * AAUDIO_THREAD_DURATION_MSEC * AAUDIO_NANOS_PER_MILLISECOND));
- // The thread returns a special answer.
- ASSERT_EQ(AAUDIO_THREAD_ANSWER, (int)reinterpret_cast<size_t>(threadResult));
-
- // Thread should already be joined.
- ASSERT_NE(AAUDIO_OK, AAudioStream_joinThread(aaudioStream, // should fail!
- &threadResult, 2 * AAUDIO_THREAD_DURATION_MSEC * AAUDIO_NANOS_PER_MILLISECOND));
-
- // Cleanup
- EXPECT_EQ(AAUDIO_OK, AAudioStreamBuilder_delete(aaudioBuilder));
- EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
-}
diff --git a/media/libaudiohal/EffectHalHidl.cpp b/media/libaudiohal/EffectHalHidl.cpp
index d74ef8a..a9d737a 100644
--- a/media/libaudiohal/EffectHalHidl.cpp
+++ b/media/libaudiohal/EffectHalHidl.cpp
@@ -135,7 +135,7 @@
uint32_t efState = 0;
retry:
status_t ret = mEfGroup->wait(
- static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING), &efState, NS_PER_SEC);
+ static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING), &efState);
if (efState & static_cast<uint32_t>(MessageQueueFlagBits::DONE_PROCESSING)) {
Result retval = Result::NOT_INITIALIZED;
mStatusMQ->read(&retval);
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 4054aaa..b66ba2b 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -338,8 +338,7 @@
// TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
uint32_t efState = 0;
retry:
- status_t ret = mEfGroup->wait(
- static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState, NS_PER_SEC);
+ status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL), &efState);
if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL)) {
WriteStatus writeStatus;
writeStatus.retval = Result::NOT_INITIALIZED;
@@ -597,8 +596,7 @@
// TODO: Remove manual event flag handling once blocking MQ is implemented. b/33815422
uint32_t efState = 0;
retry:
- status_t ret = mEfGroup->wait(
- static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState, NS_PER_SEC);
+ status_t ret = mEfGroup->wait(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY), &efState);
if (efState & static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY)) {
ReadStatus readStatus;
readStatus.retval = Result::NOT_INITIALIZED;
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 616fb9c..0d8142d 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -1463,17 +1463,25 @@
// horizontal plane, +90 is directly above the user, -90 below
//
//----------------------------------------------------------------------------
-void VirtualizerGetSpeakerAngles(audio_channel_mask_t channelMask __unused,
+void VirtualizerGetSpeakerAngles(audio_channel_mask_t channelMask,
audio_devices_t deviceType __unused, int32_t *pSpeakerAngles) {
// the channel count is guaranteed to be 1 or 2
// the device is guaranteed to be of type headphone
- // this virtualizer is always 2in with speakers at -90 and 90deg of azimuth, 0deg of elevation
- *pSpeakerAngles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_LEFT;
- *pSpeakerAngles++ = -90; // azimuth
- *pSpeakerAngles++ = 0; // elevation
- *pSpeakerAngles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_RIGHT;
- *pSpeakerAngles++ = 90; // azimuth
- *pSpeakerAngles = 0; // elevation
+ // this virtualizer is always using 2 virtual speakers at -90 and 90deg of azimuth, 0deg of
+ // elevation but the return information is sized for nbChannels * 3, so we have to consider
+ // the (false here) case of a single channel, and return only 3 fields.
+ if (audio_channel_count_from_out_mask(channelMask) == 1) {
+ *pSpeakerAngles++ = (int32_t) AUDIO_CHANNEL_OUT_MONO; // same as FRONT_LEFT
+ *pSpeakerAngles++ = 0; // azimuth
+ *pSpeakerAngles = 0; // elevation
+ } else {
+ *pSpeakerAngles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_LEFT;
+ *pSpeakerAngles++ = -90; // azimuth
+ *pSpeakerAngles++ = 0; // elevation
+ *pSpeakerAngles++ = (int32_t) AUDIO_CHANNEL_OUT_FRONT_RIGHT;
+ *pSpeakerAngles++ = 90; // azimuth
+ *pSpeakerAngles = 0; // elevation
+ }
}
//----------------------------------------------------------------------------
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 0dd3e88..a7926cd 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1395,6 +1395,28 @@
}
break;
}
+ case FOURCC('m', 'e', 't', 't'):
+ {
+ *offset += chunk_size;
+
+ if (mLastTrack == NULL)
+ return ERROR_MALFORMED;
+
+ sp<ABuffer> buffer = new ABuffer(chunk_data_size);
+ if (buffer->data() == NULL) {
+ return NO_MEMORY;
+ }
+
+ if (mDataSource->readAt(
+ data_offset, buffer->data(), chunk_data_size) < chunk_data_size) {
+ return ERROR_IO;
+ }
+
+ String8 mimeFormat((const char *)(buffer->data()), chunk_data_size);
+ mLastTrack->meta->setCString(kKeyMIMEType, mimeFormat.string());
+
+ break;
+ }
case FOURCC('m', 'p', '4', 'a'):
case FOURCC('e', 'n', 'c', 'a'):
diff --git a/media/libstagefright/omx/hal/1.0/impl/Conversion.h b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
index 68a3ed2..3433bb4 100644
--- a/media/libstagefright/omx/hal/1.0/impl/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/impl/Conversion.h
@@ -1497,9 +1497,10 @@
*/
inline size_t getFlattenedSize(
IOmxBufferProducer::FrameEventHistoryDelta const& t) {
- size_t size = 4;
- for (size_t i = 0; i < t.size(); ++i) {
- size += getFlattenedSize(t[i]);
+ size_t size = 4 + // mDeltas.size()
+ sizeof(t.compositorTiming);
+ for (size_t i = 0; i < t.deltas.size(); ++i) {
+ size += getFlattenedSize(t.deltas[i]);
}
return size;
}
@@ -1514,8 +1515,8 @@
inline size_t getFdCount(
IOmxBufferProducer::FrameEventHistoryDelta const& t) {
size_t numFds = 0;
- for (size_t i = 0; i < t.size(); ++i) {
- numFds += getFdCount(t[i]);
+ for (size_t i = 0; i < t.deltas.size(); ++i) {
+ numFds += getFdCount(t.deltas[i]);
}
return numFds;
}
@@ -1543,17 +1544,19 @@
return NO_MEMORY;
}
+ FlattenableUtils::read(buffer, size, t->compositorTiming);
+
uint32_t deltaCount = 0;
FlattenableUtils::read(buffer, size, deltaCount);
if (static_cast<size_t>(deltaCount) >
::android::FrameEventHistory::MAX_FRAME_HISTORY) {
return BAD_VALUE;
}
- t->resize(deltaCount);
+ t->deltas.resize(deltaCount);
nh->resize(deltaCount);
for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
status_t status = unflatten(
- &((*t)[deltaIndex]), &((*nh)[deltaIndex]),
+ &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
buffer, size, fds, numFds);
if (status != NO_ERROR) {
return status;
@@ -1577,16 +1580,18 @@
inline status_t flatten(
IOmxBufferProducer::FrameEventHistoryDelta const& t,
void*& buffer, size_t& size, int*& fds, size_t& numFds) {
- if (t.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
return BAD_VALUE;
}
if (size < getFlattenedSize(t)) {
return NO_MEMORY;
}
- FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
- for (size_t deltaIndex = 0; deltaIndex < t.size(); ++deltaIndex) {
- status_t status = flatten(t[deltaIndex], buffer, size, fds, numFds);
+ FlattenableUtils::write(buffer, size, t.compositorTiming);
+
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
+ for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
+ status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
if (status != NO_ERROR) {
return status;
}
diff --git a/media/libstagefright/omx/hal/1.0/utils/Conversion.h b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
index 05f0c78..2319cd9 100644
--- a/media/libstagefright/omx/hal/1.0/utils/Conversion.h
+++ b/media/libstagefright/omx/hal/1.0/utils/Conversion.h
@@ -1497,9 +1497,10 @@
*/
inline size_t getFlattenedSize(
IOmxBufferProducer::FrameEventHistoryDelta const& t) {
- size_t size = 4;
- for (size_t i = 0; i < t.size(); ++i) {
- size += getFlattenedSize(t[i]);
+ size_t size = 4 + // mDeltas.size()
+ sizeof(t.compositorTiming);
+ for (size_t i = 0; i < t.deltas.size(); ++i) {
+ size += getFlattenedSize(t.deltas[i]);
}
return size;
}
@@ -1514,8 +1515,8 @@
inline size_t getFdCount(
IOmxBufferProducer::FrameEventHistoryDelta const& t) {
size_t numFds = 0;
- for (size_t i = 0; i < t.size(); ++i) {
- numFds += getFdCount(t[i]);
+ for (size_t i = 0; i < t.deltas.size(); ++i) {
+ numFds += getFdCount(t.deltas[i]);
}
return numFds;
}
@@ -1543,17 +1544,19 @@
return NO_MEMORY;
}
+ FlattenableUtils::read(buffer, size, t->compositorTiming);
+
uint32_t deltaCount = 0;
FlattenableUtils::read(buffer, size, deltaCount);
if (static_cast<size_t>(deltaCount) >
::android::FrameEventHistory::MAX_FRAME_HISTORY) {
return BAD_VALUE;
}
- t->resize(deltaCount);
+ t->deltas.resize(deltaCount);
nh->resize(deltaCount);
for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) {
status_t status = unflatten(
- &((*t)[deltaIndex]), &((*nh)[deltaIndex]),
+ &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]),
buffer, size, fds, numFds);
if (status != NO_ERROR) {
return status;
@@ -1577,16 +1580,18 @@
inline status_t flatten(
IOmxBufferProducer::FrameEventHistoryDelta const& t,
void*& buffer, size_t& size, int*& fds, size_t& numFds) {
- if (t.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
+ if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
return BAD_VALUE;
}
if (size < getFlattenedSize(t)) {
return NO_MEMORY;
}
- FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size()));
- for (size_t deltaIndex = 0; deltaIndex < t.size(); ++deltaIndex) {
- status_t status = flatten(t[deltaIndex], buffer, size, fds, numFds);
+ FlattenableUtils::write(buffer, size, t.compositorTiming);
+
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
+ for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
+ status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds);
if (status != NO_ERROR) {
return status;
}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9e4f1a2..3989f95 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3981,9 +3981,11 @@
FastMixerState *state = NULL;
bool didModify = false;
FastMixerStateQueue::block_t block = FastMixerStateQueue::BLOCK_UNTIL_PUSHED;
+ bool coldIdle = false;
if (mFastMixer != 0) {
sq = mFastMixer->sq();
state = sq->begin();
+ coldIdle = state->mCommand == FastMixerState::COLD_IDLE;
}
mMixerBufferValid = false; // mMixerBuffer has no valid data until appropriate tracks found.
@@ -4479,7 +4481,15 @@
}
if (sq != NULL) {
sq->end(didModify);
- sq->push(block);
+ // No need to block if the FastMixer is in COLD_IDLE as the FastThread
+ // is not active. (We BLOCK_UNTIL_ACKED when entering COLD_IDLE
+ // when bringing the output sink into standby.)
+ //
+ // We will get the latest FastMixer state when we come out of COLD_IDLE.
+ //
+ // This occurs with BT suspend when we idle the FastMixer with
+ // active tracks, which may be added or removed.
+ sq->push(coldIdle ? FastMixerStateQueue::BLOCK_NEVER : block);
}
#ifdef AUDIO_WATCHDOG
if (pauseAudioWatchdog && mAudioWatchdog != 0) {
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 1abfbbc..edf41fd 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -112,9 +112,24 @@
mUid = clientUid;
// ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
+
+ size_t bufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
+ // check overflow when computing bufferSize due to multiplication by mFrameSize.
+ if (bufferSize < frameCount // roundup rounds down for values above UINT_MAX / 2
+ || mFrameSize == 0 // format needs to be correct
+ || bufferSize > SIZE_MAX / mFrameSize) {
+ android_errorWriteLog(0x534e4554, "34749571");
+ return;
+ }
+ bufferSize *= mFrameSize;
+
size_t size = sizeof(audio_track_cblk_t);
- size_t bufferSize = (buffer == NULL ? roundup(frameCount) : frameCount) * mFrameSize;
if (buffer == NULL && alloc == ALLOC_CBLK) {
+ // check overflow when computing allocation size for streaming tracks.
+ if (size > SIZE_MAX - bufferSize) {
+ android_errorWriteLog(0x534e4554, "34749571");
+ return;
+ }
size += bufferSize;
}
@@ -128,9 +143,11 @@
return;
}
} else {
- // this syntax avoids calling the audio_track_cblk_t constructor twice
- mCblk = (audio_track_cblk_t *) new uint8_t[size];
- // assume mCblk != NULL
+ mCblk = (audio_track_cblk_t *) malloc(size);
+ if (mCblk == NULL) {
+ ALOGE("not enough memory for AudioTrack size=%zu", size);
+ return;
+ }
}
// construct the shared structure in-place.
@@ -222,10 +239,9 @@
// delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
mServerProxy.clear();
if (mCblk != NULL) {
+ mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
if (mClient == 0) {
- delete mCblk;
- } else {
- mCblk->~audio_track_cblk_t(); // destroy our shared-structure.
+ free(mCblk);
}
}
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index 4cbf737..e8a8264 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -15,17 +15,16 @@
# service executable
include $(CLEAR_VARS)
LOCAL_REQUIRED_MODULES_arm := mediacodec-seccomp.policy
-LOCAL_SRC_FILES := main_codecservice.cpp minijail/minijail.cpp
+LOCAL_SRC_FILES := main_codecservice.cpp
LOCAL_SHARED_LIBRARIES := libmedia libmediacodecservice libbinder libutils \
- liblog libminijail libcutils \
+ libbase libavservices_minijail libcutils \
android.hardware.media.omx@1.0
LOCAL_C_INCLUDES := \
$(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax
-LOCAL_MODULE:= mediacodec
+LOCAL_MODULE := mediacodec
LOCAL_32_BIT_ONLY := true
LOCAL_INIT_RC := mediacodec.rc
include $(BUILD_EXECUTABLE)
include $(call all-makefiles-under, $(LOCAL_PATH))
-
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index f6cde85..6cbb368 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -15,31 +15,34 @@
** limitations under the License.
*/
-#define LOG_TAG "mediacodec"
-//#define LOG_NDEBUG 0
-
#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
-#include <utils/Log.h>
#include <cutils/properties.h>
+#include <string>
+
+#include <android-base/logging.h>
+
// from LOCAL_C_INCLUDES
#include "MediaCodecService.h"
-#include "minijail/minijail.h"
+#include "minijail.h"
#include <android/hardware/media/omx/1.0/IOmx.h>
using namespace android;
+// Must match location in Android.mk.
+static const char kSeccompPolicyPath[] = "/system/etc/seccomp_policy/mediacodec-seccomp.policy";
+
int main(int argc __unused, char** argv)
{
- ALOGI("@@@ mediacodecservice starting");
+ LOG(INFO) << "mediacodecservice starting";
signal(SIGPIPE, SIG_IGN);
- MiniJail();
+ SetUpMinijail(kSeccompPolicyPath, std::string());
strcpy(argv[0], "media.codec");
sp<ProcessState> proc(ProcessState::self());
@@ -52,11 +55,11 @@
using namespace ::android::hardware::media::omx::V1_0;
sp<IOmx> omx = IOmx::getService(true);
if (omx == nullptr) {
- ALOGE("Cannot create a Treble IOmx service.");
+ LOG(ERROR) << "Cannot create a Treble IOmx service.";
} else if (omx->registerAsService("default") != OK) {
- ALOGE("Cannot register a Treble IOmx service.");
+ LOG(ERROR) << "Cannot register a Treble IOmx service.";
} else {
- ALOGV("Treble IOmx service created.");
+ LOG(VERBOSE) << "Treble IOmx service created.";
}
}
diff --git a/services/mediacodec/minijail/minijail.cpp b/services/mediacodec/minijail/minijail.cpp
deleted file mode 100644
index 463f161..0000000
--- a/services/mediacodec/minijail/minijail.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-**
-** Copyright 2016, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "minijail"
-
-#include <unistd.h>
-
-#include <log/log.h>
-
-#include <libminijail.h>
-
-#include "minijail.h"
-
-namespace android {
-
-/* Must match location in Android.mk */
-static const char kSeccompFilePath[] = "/system/etc/seccomp_policy/mediacodec-seccomp.policy";
-
-int MiniJail()
-{
- /* no seccomp policy for this architecture */
- if (access(kSeccompFilePath, R_OK) == -1) {
- ALOGW("No seccomp filter defined for this architecture.");
- return 0;
- }
-
- struct minijail *jail = minijail_new();
- if (jail == NULL) {
- ALOGW("Failed to create minijail.");
- return -1;
- }
-
- minijail_no_new_privs(jail);
- minijail_log_seccomp_filter_failures(jail);
- minijail_use_seccomp_filter(jail);
- minijail_parse_seccomp_filters(jail, kSeccompFilePath);
- minijail_enter(jail);
- minijail_destroy(jail);
- return 0;
-}
-}
diff --git a/services/mediacodec/minijail/minijail.h b/services/mediacodec/minijail/minijail.h
deleted file mode 100644
index ae01470..0000000
--- a/services/mediacodec/minijail/minijail.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-**
-** Copyright 2016, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-namespace android {
-int MiniJail();
-}
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index b5831ae..e72236d 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -24,7 +24,6 @@
libbinder \
liblog \
libmediadrm \
- libhidltransport \
libutils
ifneq ($(DISABLE_TREBLE_DRM), true)
LOCAL_SHARED_LIBRARIES += \
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index 4e337a0..169c770 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -15,8 +15,9 @@
LOCAL_REQUIRED_MODULES_arm64 := mediaextractor-seccomp.policy
LOCAL_REQUIRED_MODULES_x86 := mediaextractor-seccomp.policy
# TODO add seccomp filter for x86_64.
-LOCAL_SRC_FILES := main_extractorservice.cpp minijail/minijail.cpp
-LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils liblog libicuuc libminijail
+LOCAL_SRC_FILES := main_extractorservice.cpp
+LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils \
+ liblog libbase libicuuc libavservices_minijail
LOCAL_STATIC_LIBRARIES := libicuandroid_utils
LOCAL_MODULE:= mediaextractor
LOCAL_INIT_RC := mediaextractor.rc
diff --git a/services/mediaextractor/main_extractorservice.cpp b/services/mediaextractor/main_extractorservice.cpp
index 245489e..752b7e4 100644
--- a/services/mediaextractor/main_extractorservice.cpp
+++ b/services/mediaextractor/main_extractorservice.cpp
@@ -15,25 +15,26 @@
** limitations under the License.
*/
-#define LOG_TAG "mediaextractor"
-//#define LOG_NDEBUG 0
-
#include <fcntl.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
-#include <utils/Log.h>
+
+#include <string>
// from LOCAL_C_INCLUDES
#include "IcuUtils.h"
#include "MediaExtractorService.h"
#include "MediaUtils.h"
-#include "minijail/minijail.h"
+#include "minijail.h"
using namespace android;
+// Must match location in Android.mk.
+static const char kSeccompPolicyPath[] = "/system/etc/seccomp_policy/mediaextractor-seccomp.policy";
+
int main(int argc __unused, char** argv)
{
limitProcessMemory(
@@ -42,7 +43,7 @@
20 /* upper limit as percentage of physical RAM */);
signal(SIGPIPE, SIG_IGN);
- MiniJail();
+ SetUpMinijail(kSeccompPolicyPath, std::string());
InitializeIcuOrDie();
diff --git a/services/mediaextractor/minijail/minijail.cpp b/services/mediaextractor/minijail/minijail.cpp
deleted file mode 100644
index c44d00d..0000000
--- a/services/mediaextractor/minijail/minijail.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#define LOG_TAG "minijail"
-
-#include <unistd.h>
-
-#include <log/log.h>
-
-#include <libminijail.h>
-
-#include "minijail.h"
-
-namespace android {
-
-/* Must match location in Android.mk */
-static const char kSeccompFilePath[] = "/system/etc/seccomp_policy/mediaextractor-seccomp.policy";
-
-int MiniJail()
-{
- /* no seccomp policy for this architecture */
- if (access(kSeccompFilePath, R_OK) == -1) {
- ALOGW("No seccomp filter defined for this architecture.");
- return 0;
- }
-
- struct minijail *jail = minijail_new();
- if (jail == NULL) {
- ALOGW("Failed to create minijail.");
- return -1;
- }
-
- minijail_no_new_privs(jail);
- minijail_log_seccomp_filter_failures(jail);
- minijail_use_seccomp_filter(jail);
- minijail_parse_seccomp_filters(jail, kSeccompFilePath);
- minijail_enter(jail);
- minijail_destroy(jail);
- return 0;
-}
-}
diff --git a/services/mediaextractor/minijail/minijail.h b/services/mediaextractor/minijail/minijail.h
deleted file mode 100644
index 6ea4487..0000000
--- a/services/mediaextractor/minijail/minijail.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-**
-** Copyright 2015, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-namespace android {
-int MiniJail();
-}
diff --git a/services/minijail/Android.mk b/services/minijail/Android.mk
new file mode 100644
index 0000000..3e63f97
--- /dev/null
+++ b/services/minijail/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH := $(call my-dir)
+
+# Small library for media.extractor and media.codec sandboxing.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libavservices_minijail
+LOCAL_SRC_FILES := minijail.cpp
+LOCAL_SHARED_LIBRARIES := libbase libminijail
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+include $(BUILD_SHARED_LIBRARY)
+
+
+# Unit tests.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libavservices_minijail_unittest
+LOCAL_SRC_FILES := minijail.cpp av_services_minijail_unittest.cpp
+LOCAL_SHARED_LIBRARIES := libbase libminijail
+include $(BUILD_NATIVE_TEST)
diff --git a/services/minijail/av_services_minijail_unittest.cpp b/services/minijail/av_services_minijail_unittest.cpp
new file mode 100644
index 0000000..31313f8
--- /dev/null
+++ b/services/minijail/av_services_minijail_unittest.cpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/unique_fd.h>
+
+#include <gtest/gtest.h>
+
+#include "minijail.h"
+
+class WritePolicyTest : public ::testing::Test
+{
+ protected:
+ const std::string base_policy_ =
+ "read: 1\n"
+ "write: 1\n"
+ "rt_sigreturn: 1\n"
+ "exit: 1\n";
+
+ const std::string additional_policy_ =
+ "mmap: 1\n"
+ "munmap: 1\n";
+
+ const std::string full_policy_ = base_policy_ + std::string("\n") + additional_policy_;
+};
+
+TEST_F(WritePolicyTest, OneFile)
+{
+ std::string final_string;
+ 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, TwoFiles)
+{
+ std::string final_string;
+ 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_);
+}
diff --git a/services/minijail/minijail.cpp b/services/minijail/minijail.cpp
new file mode 100644
index 0000000..7b61ae8
--- /dev/null
+++ b/services/minijail/minijail.cpp
@@ -0,0 +1,99 @@
+// Copyright 2015, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+
+#include <libminijail.h>
+#include <scoped_minijail.h>
+
+#include "minijail.h"
+
+namespace android {
+
+int WritePolicyToPipe(const std::string& base_policy_content,
+ const std::string& additional_policy_content)
+{
+ int pipefd[2];
+ if (pipe(pipefd) == -1) {
+ PLOG(ERROR) << "pipe() failed";
+ return -1;
+ }
+
+ 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;
+ }
+
+ if (!base::WriteStringToFd(content, write_end.get())) {
+ LOG(ERROR) << "Could not write policy to fd";
+ return -1;
+ }
+
+ return pipefd[0];
+}
+
+int 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 0;
+ }
+
+ std::string base_policy_content;
+ std::string additional_policy_content;
+ if (!base::ReadFileToString(base_policy_path, &base_policy_content,
+ false /* follow_symlinks */)) {
+ LOG(ERROR) << "Could not read base policy file '" << base_policy_path << "'";
+ return -1;
+ }
+
+ 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();
+ }
+
+ base::unique_fd policy_fd(WritePolicyToPipe(base_policy_content, additional_policy_content));
+ if (policy_fd.get() == -1) {
+ LOG(ERROR) << "Could not write seccomp policy to fd";
+ return -1;
+ }
+
+ ScopedMinijail jail{minijail_new()};
+ if (!jail) {
+ LOG(ERROR) << "Failed to create minijail.";
+ return -1;
+ }
+
+ minijail_no_new_privs(jail.get());
+ minijail_log_seccomp_filter_failures(jail.get());
+ minijail_use_seccomp_filter(jail.get());
+ // Transfer ownership of |policy_fd|.
+ minijail_parse_seccomp_filters_from_fd(jail.get(), policy_fd.release());
+ minijail_enter(jail.get());
+ return 0;
+}
+}
diff --git a/services/minijail/minijail.h b/services/minijail/minijail.h
new file mode 100644
index 0000000..3d6db37
--- /dev/null
+++ b/services/minijail/minijail.h
@@ -0,0 +1,27 @@
+// Copyright 2015, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef AV_SERVICES_MINIJAIL_MINIJAIL
+#define AV_SERVICES_MINIJAIL_MINIJAIL
+
+#include <string>
+
+namespace android {
+int WritePolicyToPipe(const std::string& base_policy_content,
+ const std::string& additional_policy_content);
+int SetUpMinijail(const std::string& base_policy_path,
+ const std::string& additional_policy_path);
+}
+
+#endif // AV_SERVICES_MINIJAIL_MINIJAIL