Merge "Move system services into correct cpusets." into nyc-dev
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
index ab57db5..755ec8e 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -37,4 +37,11 @@
oneway void onResultReceived(in CameraMetadataNative result,
in CaptureResultExtras resultExtras);
oneway void onPrepared(int streamId);
+
+ /**
+ * Repeating request encountered an error and was stopped.
+ *
+ * @param lastFrameNumber Frame number of the last frame of the streaming request.
+ */
+ oneway void onRepeatingRequestError(in long lastFrameNumber);
}
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 250f15e..1e8744b 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -36,7 +36,10 @@
* Cancel the repeating request specified by requestId
* Returns the frame number of the last frame that will be produced from this
* repeating request, or NO_IN_FLIGHT_REPEATING_FRAMES if no frames were produced
- * by this repeating request
+ * by this repeating request.
+ *
+ * Repeating request may be stopped by camera device due to an error. Canceling a stopped
+ * repeating request will trigger ERROR_ILLEGAL_ARGUMENT.
*/
long cancelRequest(int requestId);
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 0b758b6..bff5547 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -380,7 +380,11 @@
int64_t lastFrameNumber;
binder::Status remoteRet = mRemote->cancelRequest(repeatingSequenceId, &lastFrameNumber);
- if (!remoteRet.isOk()) {
+ if (remoteRet.serviceSpecificErrorCode() ==
+ hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT) {
+ ALOGV("Repeating request is already stopped.");
+ return ACAMERA_OK;
+ } else if (!remoteRet.isOk()) {
ALOGE("Stop repeating request fails in remote: %s", remoteRet.toString8().string());
return ACAMERA_ERROR_UNKNOWN;
}
@@ -1342,4 +1346,24 @@
return binder::Status::ok();
}
+binder::Status
+CameraDevice::ServiceCallback::onRepeatingRequestError(int64_t lastFrameNumber) {
+ binder::Status ret = binder::Status::ok();
+
+ sp<CameraDevice> dev = mDevice.promote();
+ if (dev == nullptr) {
+ return ret; // device has been closed
+ }
+
+ Mutex::Autolock _l(dev->mDeviceLock);
+
+ int repeatingSequenceId = dev->mRepeatingSequenceId;
+ dev->mRepeatingSequenceId = REQUEST_ID_NONE;
+
+ dev->checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
+
+ return ret;
+}
+
+
} // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 3ccf95a..71e364d 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -74,6 +74,7 @@
binder::Status onResultReceived(const CameraMetadata& metadata,
const CaptureResultExtras& resultExtras) override;
binder::Status onPrepared(int streamId) override;
+ binder::Status onRepeatingRequestError(int64_t lastFrameNumber) override;
private:
const wp<CameraDevice> mDevice;
};
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 0b687b4..828a758 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -149,7 +149,8 @@
PREPARED,
RUNNING,
SENT_RESULT,
- UNINITIALIZED
+ UNINITIALIZED,
+ REPEATING_REQUEST_ERROR,
};
protected:
@@ -215,6 +216,15 @@
return binder::Status::ok();
}
+ virtual binder::Status onRepeatingRequestError(int64_t lastFrameNumber) {
+ (void) lastFrameNumber;
+ Mutex::Autolock l(mLock);
+ mLastStatus = REPEATING_REQUEST_ERROR;
+ mStatusesHit.push_back(mLastStatus);
+ mStatusCondition.broadcast();
+ return binder::Status::ok();
+ }
+
// Test helper functions:
bool hadError() const {
diff --git a/drm/libmediadrm/Android.mk b/drm/libmediadrm/Android.mk
new file mode 100644
index 0000000..6a2ed31
--- /dev/null
+++ b/drm/libmediadrm/Android.mk
@@ -0,0 +1,36 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# libmediadrm
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ Crypto.cpp \
+ Drm.cpp \
+ DrmSessionManager.cpp \
+ SharedLibrary.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libcrypto \
+ libcutils \
+ libdl \
+ liblog \
+ libmedia \
+ libstagefright \
+ libstagefright_foundation \
+ libutils
+
+LOCAL_C_INCLUDES := \
+ libcore/include
+
+LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
+LOCAL_CLANG := true
+
+LOCAL_MODULE:= libmediadrm
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libmediaplayerservice/Crypto.cpp b/drm/libmediadrm/Crypto.cpp
similarity index 99%
rename from media/libmediaplayerservice/Crypto.cpp
rename to drm/libmediadrm/Crypto.cpp
index 9165b9d..79633cb 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/drm/libmediadrm/Crypto.cpp
@@ -20,9 +20,8 @@
#include <dirent.h>
#include <dlfcn.h>
-#include "Crypto.h"
-
#include <binder/IMemory.h>
+#include <media/Crypto.h>
#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AString.h>
diff --git a/media/libmediaplayerservice/Drm.cpp b/drm/libmediadrm/Drm.cpp
similarity index 98%
rename from media/libmediaplayerservice/Drm.cpp
rename to drm/libmediadrm/Drm.cpp
index 321ccbf..7c1f5c8 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/drm/libmediadrm/Drm.cpp
@@ -21,10 +21,9 @@
#include <dirent.h>
#include <dlfcn.h>
-#include "Drm.h"
-
-#include "DrmSessionClientInterface.h"
-#include "DrmSessionManager.h"
+#include <media/DrmSessionClientInterface.h>
+#include <media/DrmSessionManager.h>
+#include <media/Drm.h>
#include <media/drm/DrmAPI.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AString.h>
diff --git a/media/libmediaplayerservice/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
similarity index 98%
rename from media/libmediaplayerservice/DrmSessionManager.cpp
rename to drm/libmediadrm/DrmSessionManager.cpp
index 641f881..a87fb9d 100644
--- a/media/libmediaplayerservice/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -18,12 +18,11 @@
#define LOG_TAG "DrmSessionManager"
#include <utils/Log.h>
-#include "DrmSessionManager.h"
-
-#include "DrmSessionClientInterface.h"
#include <binder/IPCThreadState.h>
#include <binder/IProcessInfoService.h>
#include <binder/IServiceManager.h>
+#include <media/DrmSessionManager.h>
+#include <media/DrmSessionClientInterface.h>
#include <media/stagefright/ProcessInfo.h>
#include <unistd.h>
#include <utils/String8.h>
diff --git a/media/libmediaplayerservice/SharedLibrary.cpp b/drm/libmediadrm/SharedLibrary.cpp
similarity index 97%
rename from media/libmediaplayerservice/SharedLibrary.cpp
rename to drm/libmediadrm/SharedLibrary.cpp
index 34db761..74b3a71 100644
--- a/media/libmediaplayerservice/SharedLibrary.cpp
+++ b/drm/libmediadrm/SharedLibrary.cpp
@@ -16,12 +16,11 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "Drm"
-#include <utils/Log.h>
-#include <media/stagefright/foundation/ADebug.h>
#include <dlfcn.h>
-
-#include "SharedLibrary.h"
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/SharedLibrary.h>
+#include <utils/Log.h>
namespace android {
diff --git a/include/camera/ndk/NdkCameraMetadataTags.h b/include/camera/ndk/NdkCameraMetadataTags.h
index 155f221..ec2e159 100644
--- a/include/camera/ndk/NdkCameraMetadataTags.h
+++ b/include/camera/ndk/NdkCameraMetadataTags.h
@@ -4140,7 +4140,7 @@
* color channel listed in the CFA.</p>
* <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is
* available or the camera device advertises this key via
- * {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureRequestKeys}.</p>
+ * {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureResultKeys}.</p>
*
* @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
* @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
@@ -4655,16 +4655,26 @@
ACAMERA_STATISTICS_START + 10,
/**
* <p>The shading map is a low-resolution floating-point map
- * that lists the coefficients used to correct for vignetting, for each
- * Bayer color channel of RAW image data.</p>
+ * that lists the coefficients used to correct for vignetting and color shading,
+ * for each Bayer color channel of RAW image data.</p>
*
* <p>This tag may appear in:</p>
* <ul>
* <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
* </ul>
*
- * <p>The least shaded section of the image should have a gain factor
- * of 1; all other sections should have gains above 1.</p>
+ * <p>The lens shading correction is defined as a full shading correction that
+ * corrects both color shading for the output non-RAW images. After the
+ * shading map is applied, the output non-RAW images will be flat-field images
+ * for flat scenes under uniform illumination.</p>
+ * <p>When there is no lens shading correction applied to RAW output images
+ * (ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED <code>==</code> false), this map is a full lens
+ * shading correction map; when there is some lens shading correction applied
+ * to the RAW output image (ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED <code>==</code> true),
+ * this map reports the remaining lens shading correction map that needs to be
+ * applied to get fully shading corrected images.</p>
+ * <p>For a full shading correction map, the least shaded section of the image
+ * should have a gain factor of 1; all other sections should have gains above 1.</p>
* <p>When ACAMERA_COLOR_CORRECTION_MODE = TRANSFORM_MATRIX, the map
* must take into account the colorCorrection settings.</p>
* <p>The shading map is for the entire active pixel array, and is not
diff --git a/include/media/AudioIoDescriptor.h b/include/media/AudioIoDescriptor.h
index a4907cc..fed86c9 100644
--- a/include/media/AudioIoDescriptor.h
+++ b/include/media/AudioIoDescriptor.h
@@ -35,7 +35,7 @@
AudioIoDescriptor() :
mIoHandle(AUDIO_IO_HANDLE_NONE),
mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE),
- mFrameCount(0), mLatency(0)
+ mFrameCount(0), mFrameCountHAL(0), mLatency(0)
{
memset(&mPatch, 0, sizeof(struct audio_patch));
}
@@ -62,6 +62,7 @@
audio_format_t mFormat;
audio_channel_mask_t mChannelMask;
size_t mFrameCount;
+ size_t mFrameCountHAL;
uint32_t mLatency; // only valid for output
};
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index c9eac2e..585ef59 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -43,6 +43,8 @@
{
public:
+ // FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp
+
/* These are static methods to control the system-wide AudioFlinger
* only privileged processes can have access to them
*/
@@ -117,8 +119,8 @@
// returns the audio HAL sample rate
static status_t getSamplingRate(audio_io_handle_t ioHandle,
uint32_t* samplingRate);
- // returns the number of frames per audio HAL buffer. Corresponds to
- // audio_stream->get_buffer_size()/audio_stream_out/in_frame_size()
+ // For output threads with a fast mixer, returns the number of frames per normal mixer buffer.
+ // For output threads without a fast mixer, or for input, this is same as getFrameCountHAL().
static status_t getFrameCount(audio_io_handle_t ioHandle,
size_t* frameCount);
// returns the audio output latency in ms. Corresponds to
@@ -166,6 +168,12 @@
// Indicate JAVA services are ready (scheduling, power management ...)
static status_t systemReady();
+ // Returns the number of frames per audio HAL buffer.
+ // Corresponds to audio_stream->get_buffer_size()/audio_stream_in_frame_size() for input.
+ // See also getFrameCount().
+ static status_t getFrameCountHAL(audio_io_handle_t ioHandle,
+ size_t* frameCount);
+
// Events used to synchronize actions between audio sessions.
// For instance SYNC_EVENT_PRESENTATION_COMPLETE can be used to delay recording start until
// playback is complete on another audio session.
diff --git a/media/libmediaplayerservice/Crypto.h b/include/media/Crypto.h
similarity index 100%
rename from media/libmediaplayerservice/Crypto.h
rename to include/media/Crypto.h
diff --git a/media/libmediaplayerservice/Drm.h b/include/media/Drm.h
similarity index 100%
rename from media/libmediaplayerservice/Drm.h
rename to include/media/Drm.h
diff --git a/services/mediadrm/DrmSessionClientInterface.h b/include/media/DrmSessionClientInterface.h
similarity index 100%
rename from services/mediadrm/DrmSessionClientInterface.h
rename to include/media/DrmSessionClientInterface.h
diff --git a/media/libmediaplayerservice/DrmSessionManager.h b/include/media/DrmSessionManager.h
similarity index 100%
rename from media/libmediaplayerservice/DrmSessionManager.h
rename to include/media/DrmSessionManager.h
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index e48aa1c..1ade4ba 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -103,6 +103,9 @@
* and therefore can be cached.
*/
virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const = 0;
+
+ // reserved; formerly channelCount()
+
virtual audio_format_t format(audio_io_handle_t output) const = 0;
virtual size_t frameCount(audio_io_handle_t ioHandle) const = 0;
@@ -247,6 +250,9 @@
/* Indicate JAVA services are ready (scheduling, power management ...) */
virtual status_t systemReady() = 0;
+
+ // Returns the number of frames per audio HAL buffer.
+ virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const = 0;
};
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index e5d3cda..8266b0b 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -31,8 +31,6 @@
namespace android {
-struct ICrypto;
-struct IDrm;
struct IHDCP;
struct IMediaCodecList;
struct IMediaHTTPService;
@@ -52,8 +50,6 @@
virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client,
audio_session_t audioSessionId = AUDIO_SESSION_ALLOCATE) = 0;
virtual sp<IOMX> getOMX() = 0;
- virtual sp<ICrypto> makeCrypto() = 0;
- virtual sp<IDrm> makeDrm() = 0;
virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) = 0;
virtual sp<IMediaCodecList> getCodecList() const = 0;
diff --git a/media/libmediaplayerservice/SharedLibrary.h b/include/media/SharedLibrary.h
similarity index 100%
rename from media/libmediaplayerservice/SharedLibrary.h
rename to include/media/SharedLibrary.h
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index 8406ed6..c41c686 100644
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -193,12 +193,15 @@
TONE_JAPAN_DIAL, // Dial tone: 400Hz, continuous
TONE_JAPAN_BUSY, // Busy tone: 400Hz, 500ms ON, 500ms OFF...
TONE_JAPAN_RADIO_ACK, // Radio path acknowlegment: 400Hz, 1s ON, 2s OFF...
+ // UK Supervisory tones
+ TONE_UK_RINGTONE, // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
NUM_ALTERNATE_TONES
};
enum region {
ANSI,
JAPAN,
+ UK,
CEPT,
NUM_REGIONS
};
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index b22e0b4..f6d5f12 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -425,10 +425,10 @@
// gets index or sets it to 0 on error. Returns error from codec.
status_t initDescribeHDRStaticInfoIndex();
- // sets HDR static information for the decoder based on |configFormat|, and
- // set resulting HDRStaticInfo config into |outputFormat|. Returns error from the codec.
- status_t setHDRStaticInfoForVideoDecoder(
- const sp<AMessage> &configFormat, sp<AMessage> &outputFormat);
+ // sets HDR static metadata for the video encoder/decoder based on |configFormat|, and
+ // sets resulting HDRStaticInfo config into |outputFormat|. Returns error from the codec.
+ status_t setHDRStaticInfoForVideoCodec(
+ OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat);
// sets |params|. Returns the codec error.
status_t setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms);
@@ -436,8 +436,8 @@
// gets |params|. Returns the codec error.
status_t getHDRStaticInfo(DescribeHDRStaticInfoParams ¶ms);
- // gets HDR static information for the video decoder port and sets them into |format|.
- status_t getHDRStaticInfoForVideoDecoder(sp<AMessage> &format);
+ // gets HDR static information for the video encoder/decoder port and sets them into |format|.
+ status_t getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format);
typedef struct drcParams {
int32_t drcCut;
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index c5df1f6..0254545 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -19,7 +19,7 @@
#define DATA_SOURCE_H_
#include <sys/types.h>
-
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
@@ -71,6 +71,20 @@
bool getUInt32(off64_t offset, uint32_t *x);
bool getUInt64(off64_t offset, uint64_t *x);
+ // Reads in "count" entries of type T into vector *x.
+ // Returns true if "count" entries can be read.
+ // If fewer than "count" entries can be read, return false. In this case,
+ // the output vector *x will still have those entries that were read. Call
+ // x->size() to obtain the number of entries read.
+ // The optional parameter chunkSize specifies how many entries should be
+ // read from the data source at one time into a temporary buffer. Increasing
+ // chunkSize can improve the performance at the cost of extra memory usage.
+ // The default value for chunkSize is set to read at least 4k bytes at a
+ // time, depending on sizeof(T).
+ template <typename T>
+ bool getVector(off64_t offset, Vector<T>* x, size_t count,
+ size_t chunkSize = (4095 / sizeof(T)) + 1);
+
// May return ERROR_UNSUPPORTED.
virtual status_t getSize(off64_t *size);
@@ -127,6 +141,51 @@
DataSource &operator=(const DataSource &);
};
+template <typename T>
+bool DataSource::getVector(off64_t offset, Vector<T>* x, size_t count,
+ size_t chunkSize)
+{
+ x->clear();
+ if (chunkSize == 0) {
+ return false;
+ }
+ if (count == 0) {
+ return true;
+ }
+
+ T tmp[chunkSize];
+ ssize_t numBytesRead;
+ size_t numBytesPerChunk = chunkSize * sizeof(T);
+ size_t i;
+
+ for (i = 0; i + chunkSize < count; i += chunkSize) {
+ // This loops is executed when more than chunkSize records need to be
+ // read.
+ numBytesRead = this->readAt(offset, (void*)&tmp, numBytesPerChunk);
+ if (numBytesRead == -1) { // If readAt() returns -1, there is an error.
+ return false;
+ }
+ if (numBytesRead < numBytesPerChunk) {
+ // This case is triggered when the stream ends before the whole
+ // chunk is read.
+ x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+ return false;
+ }
+ x->appendArray(tmp, chunkSize);
+ offset += numBytesPerChunk;
+ }
+
+ // There are (count - i) more records to read.
+ // Right now, (count - i) <= chunkSize.
+ // We do the same thing as above, but with chunkSize replaced by count - i.
+ numBytesRead = this->readAt(offset, (void*)&tmp, (count - i) * sizeof(T));
+ if (numBytesRead == -1) {
+ return false;
+ }
+ x->appendArray(tmp, (size_t)numBytesRead / sizeof(T));
+ return x->size() == count;
+}
+
} // namespace android
#endif // DATA_SOURCE_H_
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 3a5dee6..bbdf65e 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -104,6 +104,8 @@
return DEAD_OBJECT;
}
+// FIXME Declare in binder opcode order, similarly to IAudioFlinger.h and IAudioFlinger.cpp
+
status_t AudioSystem::muteMicrophone(bool state)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
@@ -429,6 +431,27 @@
return af->systemReady();
}
+status_t AudioSystem::getFrameCountHAL(audio_io_handle_t ioHandle,
+ size_t* frameCount)
+{
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == 0) return PERMISSION_DENIED;
+ sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
+ if (desc == 0) {
+ *frameCount = af->frameCountHAL(ioHandle);
+ } else {
+ *frameCount = desc->mFrameCountHAL;
+ }
+ if (*frameCount == 0) {
+ ALOGE("AudioSystem::getFrameCountHAL failed for ioHandle %d", ioHandle);
+ return BAD_VALUE;
+ }
+
+ ALOGV("getFrameCountHAL() ioHandle %d, frameCount %zu", ioHandle, *frameCount);
+
+ return NO_ERROR;
+}
+
// ---------------------------------------------------------------------------
@@ -528,10 +551,10 @@
}
}
ALOGV("ioConfigChanged() new config for %s %d samplingRate %u, format %#x "
- "channel mask %#x frameCount %zu deviceId %d",
+ "channel mask %#x frameCount %zu frameCountHAL %zu deviceId %d",
event == AUDIO_OUTPUT_CONFIG_CHANGED ? "output" : "input",
ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat,
- ioDesc->mChannelMask, ioDesc->mFrameCount, ioDesc->getDeviceId());
+ ioDesc->mChannelMask, ioDesc->mFrameCount, ioDesc->mFrameCountHAL, ioDesc->getDeviceId());
} break;
}
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 7543b60..aa75188 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -81,7 +81,8 @@
LIST_AUDIO_PATCHES,
SET_AUDIO_PORT_CONFIG,
GET_AUDIO_HW_SYNC,
- SYSTEM_READY
+ SYSTEM_READY,
+ FRAME_COUNT_HAL,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -274,6 +275,8 @@
return reply.readInt32();
}
+ // RESERVED for channelCount()
+
virtual audio_format_t format(audio_io_handle_t output) const
{
Parcel data, reply;
@@ -911,6 +914,18 @@
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
return remote()->transact(SYSTEM_READY, data, &reply, IBinder::FLAG_ONEWAY);
}
+ virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32((int32_t) ioHandle);
+ status_t status = remote()->transact(FRAME_COUNT_HAL, data, &reply);
+ if (status != NO_ERROR) {
+ return 0;
+ }
+ return reply.readInt64();
+ }
+
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -993,6 +1008,9 @@
reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
return NO_ERROR;
} break;
+
+ // RESERVED for channelCount()
+
case FORMAT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
@@ -1419,6 +1437,11 @@
systemReady();
return NO_ERROR;
} break;
+ case FRAME_COUNT_HAL: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ reply->writeInt64( frameCountHAL((audio_io_handle_t) data.readInt32()) );
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp
index 3429d36..8dca9e9 100644
--- a/media/libmedia/IAudioFlingerClient.cpp
+++ b/media/libmedia/IAudioFlingerClient.cpp
@@ -50,6 +50,7 @@
data.writeInt32(ioDesc->mFormat);
data.writeInt32(ioDesc->mChannelMask);
data.writeInt64(ioDesc->mFrameCount);
+ data.writeInt64(ioDesc->mFrameCountHAL);
data.writeInt32(ioDesc->mLatency);
remote()->transact(IO_CONFIG_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -73,6 +74,7 @@
ioDesc->mFormat = (audio_format_t) data.readInt32();
ioDesc->mChannelMask = (audio_channel_mask_t) data.readInt32();
ioDesc->mFrameCount = data.readInt64();
+ ioDesc->mFrameCountHAL = data.readInt64();
ioDesc->mLatency = data.readInt32();
ioConfigChanged(event, ioDesc);
return NO_ERROR;
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 27b9edd..7590c1b 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -20,8 +20,6 @@
#include <binder/Parcel.h>
#include <binder/IMemory.h>
-#include <media/ICrypto.h>
-#include <media/IDrm.h>
#include <media/IHDCP.h>
#include <media/IMediaCodecList.h>
#include <media/IMediaHTTPService.h>
@@ -42,8 +40,6 @@
CREATE_MEDIA_RECORDER,
CREATE_METADATA_RETRIEVER,
GET_OMX,
- MAKE_CRYPTO,
- MAKE_DRM,
MAKE_HDCP,
ADD_BATTERY_DATA,
PULL_BATTERY_DATA,
@@ -94,20 +90,6 @@
return interface_cast<IOMX>(reply.readStrongBinder());
}
- virtual sp<ICrypto> makeCrypto() {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
- remote()->transact(MAKE_CRYPTO, data, &reply);
- return interface_cast<ICrypto>(reply.readStrongBinder());
- }
-
- virtual sp<IDrm> makeDrm() {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
- remote()->transact(MAKE_DRM, data, &reply);
- return interface_cast<IDrm>(reply.readStrongBinder());
- }
-
virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) {
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
@@ -185,18 +167,6 @@
reply->writeStrongBinder(IInterface::asBinder(omx));
return NO_ERROR;
} break;
- case MAKE_CRYPTO: {
- CHECK_INTERFACE(IMediaPlayerService, data, reply);
- sp<ICrypto> crypto = makeCrypto();
- reply->writeStrongBinder(IInterface::asBinder(crypto));
- return NO_ERROR;
- } break;
- case MAKE_DRM: {
- CHECK_INTERFACE(IMediaPlayerService, data, reply);
- sp<IDrm> drm = makeDrm();
- reply->writeStrongBinder(IInterface::asBinder(drm));
- return NO_ERROR;
- } break;
case MAKE_HDCP: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
bool createEncryptionModule = data.readInt32();
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 9f4b4de..411519d 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -740,6 +740,13 @@
{ .duration = 0 , .waveFreq = { 0 }, 0, 0}},
.repeatCnt = ToneGenerator::TONEGEN_INF,
.repeatSegment = 0 }, // TONE_JAPAN_RADIO_ACK
+ { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+ { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+ { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+ { .duration = 2000, .waveFreq = { 0 }, 0, 0},
+ { .duration = 0, .waveFreq = { 0 }, 0, 0}},
+ .repeatCnt = ToneGenerator::TONEGEN_INF,
+ .repeatSegment = 0 }, // TONE_UK_RINGTONE
@@ -767,7 +774,18 @@
TONE_SUP_ERROR, // TONE_SUP_ERROR
TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING
TONE_SUP_RINGTONE // TONE_SUP_RINGTONE
+ },
+ { // UK
+ TONE_SUP_DIAL, // TONE_SUP_DIAL
+ TONE_SUP_BUSY, // TONE_SUP_BUSY
+ TONE_SUP_CONGESTION, // TONE_SUP_CONGESTION
+ TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK
+ TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL
+ TONE_SUP_ERROR, // TONE_SUP_ERROR
+ TONE_SUP_CALL_WAITING, // TONE_SUP_CALL_WAITING
+ TONE_UK_RINGTONE // TONE_SUP_RINGTONE
}
+
};
@@ -819,6 +837,9 @@
mRegion = ANSI;
} else if (strcmp(value,"jp") == 0) {
mRegion = JAPAN;
+ } else if (strcmp(value,"uk") == 0 ||
+ strcmp(value,"uk,uk") == 0) {
+ mRegion = UK;
} else {
mRegion = CEPT;
}
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index edad4be..68860d2 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -8,16 +8,12 @@
LOCAL_SRC_FILES:= \
ActivityManager.cpp \
- Crypto.cpp \
- Drm.cpp \
- DrmSessionManager.cpp \
HDCP.cpp \
MediaPlayerFactory.cpp \
MediaPlayerService.cpp \
MediaRecorderClient.cpp \
MetadataRetrieverClient.cpp \
RemoteDisplay.cpp \
- SharedLibrary.cpp \
StagefrightRecorder.cpp \
TestPlayerStub.cpp \
@@ -52,6 +48,7 @@
$(TOP)/frameworks/av/media/libstagefright/rtsp \
$(TOP)/frameworks/av/media/libstagefright/wifi-display \
$(TOP)/frameworks/av/media/libstagefright/webm \
+ $(TOP)/frameworks/av/include/media \
$(TOP)/frameworks/av/include/camera \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/tremolo/Tremolo \
diff --git a/media/libmediaplayerservice/DrmSessionClientInterface.h b/media/libmediaplayerservice/DrmSessionClientInterface.h
deleted file mode 100644
index 17faf08..0000000
--- a/media/libmediaplayerservice/DrmSessionClientInterface.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 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 DRM_PROXY_INTERFACE_H_
-#define DRM_PROXY_INTERFACE_H_
-
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-struct DrmSessionClientInterface : public RefBase {
- virtual bool reclaimSession(const Vector<uint8_t>& sessionId) = 0;
-
-protected:
- virtual ~DrmSessionClientInterface() {}
-};
-
-} // namespace android
-
-#endif // DRM_PROXY_INTERFACE_H_
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9b081e9..7d3c671 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -78,8 +78,6 @@
#include <OMX.h>
-#include "Crypto.h"
-#include "Drm.h"
#include "HDCP.h"
#include "HTTPBase.h"
#include "RemoteDisplay.h"
@@ -359,14 +357,6 @@
return mOMX;
}
-sp<ICrypto> MediaPlayerService::makeCrypto() {
- return new Crypto;
-}
-
-sp<IDrm> MediaPlayerService::makeDrm() {
- return new Drm;
-}
-
sp<IHDCP> MediaPlayerService::makeHDCP(bool createEncryptionModule) {
return new HDCP(createEncryptionModule);
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 80593b2..1cf648e 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -219,8 +219,6 @@
virtual sp<IMediaCodecList> getCodecList() const;
virtual sp<IOMX> getOMX();
- virtual sp<ICrypto> makeCrypto();
- virtual sp<IDrm> makeDrm();
virtual sp<IHDCP> makeHDCP(bool createEncryptionModule);
virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
@@ -410,7 +408,6 @@
SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
int32_t mNextConnId;
sp<IOMX> mOMX;
- sp<ICrypto> mCrypto;
};
// ----------------------------------------------------------------------------
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 7b97d0f..3f7367f 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1793,6 +1793,7 @@
mWriter.clear();
}
mTotalPausedDurationUs = 0;
+ mPauseStartTimeUs = 0;
mGraphicBufferProducer.clear();
mPersistentSurface.clear();
@@ -1873,7 +1874,6 @@
mTotalBitRate = 0;
mOutputFd = -1;
- mPauseStartTimeUs = 0;
return OK;
}
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 81aafbe..9e33cb5 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1620,14 +1620,13 @@
}
void NuPlayer::GenericSource::BufferingMonitor::startBufferingIfNecessary_l() {
- ALOGD("startBufferingIfNecessary_l: mPrepareBuffering=%d, mBuffering=%d",
- mPrepareBuffering, mBuffering);
-
if (mPrepareBuffering) {
return;
}
if (!mBuffering) {
+ ALOGD("startBufferingIfNecessary_l");
+
mBuffering = true;
ensureCacheIsFetching_l();
@@ -1640,10 +1639,9 @@
}
void NuPlayer::GenericSource::BufferingMonitor::stopBufferingIfNecessary_l() {
- ALOGD("stopBufferingIfNecessary_l: mPrepareBuffering=%d, mBuffering=%d",
- mPrepareBuffering, mBuffering);
-
if (mPrepareBuffering) {
+ ALOGD("stopBufferingIfNecessary_l, mBuffering=%d", mBuffering);
+
mPrepareBuffering = false;
sp<AMessage> notify = mNotify->dup();
@@ -1655,6 +1653,7 @@
}
if (mBuffering) {
+ ALOGD("stopBufferingIfNecessary_l");
mBuffering = false;
sendCacheStats_l();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 42a82ac..46a51ce 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -400,14 +400,20 @@
}
void NuPlayer::resetAsync() {
- if (mSource != NULL) {
+ sp<Source> source;
+ {
+ Mutex::Autolock autoLock(mSourceLock);
+ source = mSource;
+ }
+
+ if (source != NULL) {
// During a reset, the data source might be unresponsive already, we need to
// disconnect explicitly so that reads exit promptly.
// We can't queue the disconnect request to the looper, as it might be
// queued behind a stuck read and never gets processed.
// Doing a disconnect outside the looper to allows the pending reads to exit
// (either successfully or with error).
- mSource->disconnect();
+ source->disconnect();
}
(new AMessage(kWhatReset, this))->post();
@@ -484,6 +490,7 @@
sp<RefBase> obj;
CHECK(msg->findObject("source", &obj));
if (obj != NULL) {
+ Mutex::Autolock autoLock(mSourceLock);
mSource = static_cast<Source *>(obj.get());
} else {
err = UNKNOWN_ERROR;
@@ -1144,6 +1151,11 @@
int32_t reason;
CHECK(msg->findInt32("reason", &reason));
ALOGV("Tear down audio with reason %d.", reason);
+ if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
+ // TimeoutWhenPaused is only for offload mode.
+ ALOGW("Receive a stale message for teardown.");
+ break;
+ }
int64_t positionUs;
if (!msg->findInt64("positionUs", &positionUs)) {
positionUs = mPreviousSeekTimeUs;
@@ -1998,6 +2010,7 @@
if (mSource != NULL) {
mSource->stop();
+ Mutex::Autolock autoLock(mSourceLock);
mSource.clear();
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 369590b..f6eb49e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -140,6 +140,7 @@
bool mUIDValid;
uid_t mUID;
pid_t mPID;
+ Mutex mSourceLock; // guard |mSource|.
sp<Source> mSource;
uint32_t mSourceFlags;
sp<Surface> mSurface;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index c38a23b..4ae8e82 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1722,10 +1722,16 @@
}
void NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() {
- if (offloadingAudio()) {
- mWakeLock->release(true);
- ++mAudioOffloadPauseTimeoutGeneration;
- }
+ // We may have called startAudioOffloadPauseTimeout() without
+ // the AudioSink open and with offloadingAudio enabled.
+ //
+ // When we cancel, it may be that offloadingAudio is subsequently disabled, so regardless
+ // we always release the wakelock and increment the pause timeout generation.
+ //
+ // Note: The acquired wakelock prevents the device from suspending
+ // immediately after offload pause (in case a resume happens shortly thereafter).
+ mWakeLock->release(true);
+ ++mAudioOffloadPauseTimeoutGeneration;
}
status_t NuPlayer::Renderer::onOpenAudioSink(
diff --git a/media/libmediaplayerservice/tests/Android.mk b/media/libmediaplayerservice/tests/Android.mk
index 8cbf782..ea75a97 100644
--- a/media/libmediaplayerservice/tests/Android.mk
+++ b/media/libmediaplayerservice/tests/Android.mk
@@ -12,6 +12,7 @@
LOCAL_SHARED_LIBRARIES := \
liblog \
libmediaplayerservice \
+ libmediadrm \
libutils \
LOCAL_C_INCLUDES := \
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index ef4c833..c5212fc 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -20,9 +20,9 @@
#include <gtest/gtest.h>
-#include "Drm.h"
-#include "DrmSessionClientInterface.h"
-#include "DrmSessionManager.h"
+#include <media/Drm.h>
+#include <media/DrmSessionClientInterface.h>
+#include <media/DrmSessionManager.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/ProcessInfoInterface.h>
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 7c903ea..f159882 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3192,7 +3192,7 @@
return err;
}
- err = setHDRStaticInfoForVideoDecoder(msg, outputFormat);
+ err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
if (err == ERROR_UNSUPPORTED) { // support is optional
err = OK;
}
@@ -3392,6 +3392,25 @@
return OK;
}
+status_t ACodec::setHDRStaticInfoForVideoCodec(
+ OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
+ CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
+
+ DescribeHDRStaticInfoParams params;
+ InitOMXParams(¶ms);
+ params.nPortIndex = portIndex;
+
+ HDRStaticInfo *info = ¶ms.sInfo;
+ if (getHDRStaticInfoFromFormat(configFormat, info)) {
+ setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
+ }
+
+ (void)initDescribeHDRStaticInfoIndex();
+
+ // communicate HDR static Info to codec
+ return setHDRStaticInfo(params);
+}
+
// subsequent initial video encoder setup for surface mode
status_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
android_dataspace *dataSpace /* nonnull */) {
@@ -3444,10 +3463,11 @@
return err;
}
-status_t ACodec::getHDRStaticInfoForVideoDecoder(sp<AMessage> &format) {
+status_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
+ CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
DescribeHDRStaticInfoParams params;
InitOMXParams(¶ms);
- params.nPortIndex = kPortIndexOutput;
+ params.nPortIndex = portIndex;
status_t err = getHDRStaticInfo(params);
if (err == OK) {
@@ -3466,23 +3486,6 @@
return err;
}
-status_t ACodec::setHDRStaticInfoForVideoDecoder(
- const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
- DescribeHDRStaticInfoParams params;
- InitOMXParams(¶ms);
- params.nPortIndex = kPortIndexOutput;
-
- HDRStaticInfo *info = ¶ms.sInfo;
- if (getHDRStaticInfoFromFormat(configFormat, info)) {
- setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
- }
-
- (void)initDescribeHDRStaticInfoIndex();
-
- // communicate HDR static Info to codec
- return setHDRStaticInfo(params);
-}
-
status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms) {
status_t err = ERROR_UNSUPPORTED;
if (mDescribeHDRStaticInfoIndex) {
@@ -3697,6 +3700,16 @@
err = OK;
}
+ if (err != OK) {
+ return err;
+ }
+
+ err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
+ if (err == ERROR_UNSUPPORTED) { // support is optional
+ ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
+ err = OK;
+ }
+
if (err == OK) {
ALOGI("setupVideoEncoder succeeded");
}
@@ -4729,9 +4742,12 @@
if (mUsingNativeWindow) {
notify->setInt32("android._dataspace", dataSpace);
}
- (void)getHDRStaticInfoForVideoDecoder(notify);
+ (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
} else {
(void)getInputColorAspectsForVideoEncoder(notify);
+ if (mConfigFormat->contains("hdr-static-info")) {
+ (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
+ }
}
break;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 7a8f4c0..db20590 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -2261,6 +2261,7 @@
HevcParameterSets paramSets;
if (parseHEVCCodecSpecificData(data, size, paramSets) != OK) {
+ ALOGE("failed parsing codec specific data");
return ERROR_MALFORMED;
}
@@ -2271,8 +2272,9 @@
return NO_MEMORY;
}
status_t err = paramSets.makeHvcc((uint8_t *)mCodecSpecificData,
- &mCodecSpecificDataSize, mOwner->useNalLengthFour() ? 5 : 2);
+ &mCodecSpecificDataSize, mOwner->useNalLengthFour() ? 4 : 2);
if (err != OK) {
+ ALOGE("failed constructing HVCC atom");
return err;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 1bdd812..542a06d 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -121,8 +121,9 @@
mSampleSizeFieldSize(0),
mDefaultSampleSize(0),
mNumSampleSizes(0),
+ mHasTimeToSample(false),
mTimeToSampleCount(0),
- mTimeToSample(NULL),
+ mTimeToSample(),
mSampleTimeEntries(NULL),
mCompositionTimeDeltaEntries(NULL),
mNumCompositionTimeDeltaEntries(0),
@@ -151,9 +152,6 @@
delete[] mSampleTimeEntries;
mSampleTimeEntries = NULL;
- delete[] mTimeToSample;
- mTimeToSample = NULL;
-
delete mSampleIterator;
mSampleIterator = NULL;
}
@@ -162,7 +160,7 @@
return mChunkOffsetOffset >= 0
&& mSampleToChunkOffset >= 0
&& mSampleSizeOffset >= 0
- && mTimeToSample != NULL;
+ && mHasTimeToSample;
}
status_t SampleTable::setChunkOffsetParams(
@@ -336,7 +334,7 @@
status_t SampleTable::setTimeToSampleParams(
off64_t data_offset, size_t data_size) {
- if (mTimeToSample != NULL || data_size < 8) {
+ if (mHasTimeToSample || data_size < 8) {
return ERROR_MALFORMED;
}
@@ -352,24 +350,31 @@
}
mTimeToSampleCount = U32_AT(&header[4]);
- uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
- if (allocSize > UINT32_MAX) {
+ if ((uint64_t)mTimeToSampleCount >
+ (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) {
+ // Choose this bound because
+ // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
+ // time-to-sample entry in the time-to-sample table.
+ // 2) mTimeToSampleCount is the number of entries of the time-to-sample
+ // table.
+ // 3) We hope that the table size does not exceed UINT32_MAX.
+ ALOGE(" Error: Time-to-sample table size too large.");
return ERROR_OUT_OF_RANGE;
}
- mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2];
- if (!mTimeToSample)
- return ERROR_OUT_OF_RANGE;
- size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
- if (mDataSource->readAt(
- data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
+ // Note: At this point, we know that mTimeToSampleCount * 2 will not
+ // overflow because of the above condition.
+ if (!mDataSource->getVector(data_offset + 8, &mTimeToSample,
+ mTimeToSampleCount * 2)) {
+ ALOGE(" Error: Incomplete data read for time-to-sample table.");
return ERROR_IO;
}
- for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
- mTimeToSample[i] = ntohl(mTimeToSample[i]);
+ for (size_t i = 0; i < mTimeToSample.size(); ++i) {
+ mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]);
}
+ mHasTimeToSample = true;
return OK;
}
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index 958e7c4..9f7b590 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -240,6 +240,15 @@
mSignalledError = true;
}
+ if (inHeader->nFilledLen * sizeof(int16_t) > outHeader->nAllocLen) {
+ ALOGE("output buffer too small (%d).", outHeader->nAllocLen);
+ android_errorWriteLog(0x534e4554, "27793163");
+
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
const uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset;
if (mIsMLaw) {
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index 7916c45..04d5a33 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -228,6 +228,14 @@
mSignalledError = true;
}
+ if (outHeader->nAllocLen < (inHeader->nFilledLen / kMSGSMFrameSize) * 320) {
+ ALOGE("output buffer is not large enough (%d).", outHeader->nAllocLen);
+ android_errorWriteLog(0x534e4554, "27793367");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
uint8_t *inputptr = inHeader->pBuffer + inHeader->nOffset;
int n = mSignalledError ? 0 : DecodeGSM(mGsm,
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index ff2bb27..935f1dc 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -603,6 +603,18 @@
return ERROR_MALFORMED;
}
err = parseMetaDataDuration(line, &itemMeta, "durationUs");
+ } else if (line.startsWith("#EXT-X-DISCONTINUITY-SEQUENCE")) {
+ if (mIsVariantPlaylist) {
+ return ERROR_MALFORMED;
+ }
+ size_t seq;
+ err = parseDiscontinuitySequence(line, &seq);
+ if (err == OK) {
+ mDiscontinuitySeq = seq;
+ ALOGI("mDiscontinuitySeq %zu", mDiscontinuitySeq);
+ } else {
+ ALOGI("Failed to parseDiscontinuitySequence %d", err);
+ }
} else if (line.startsWith("#EXT-X-DISCONTINUITY")) {
if (mIsVariantPlaylist) {
return ERROR_MALFORMED;
@@ -638,15 +650,6 @@
}
} else if (line.startsWith("#EXT-X-MEDIA")) {
err = parseMedia(line);
- } else if (line.startsWith("#EXT-X-DISCONTINUITY-SEQUENCE")) {
- if (mIsVariantPlaylist) {
- return ERROR_MALFORMED;
- }
- size_t seq;
- err = parseDiscontinuitySequence(line, &seq);
- if (err == OK) {
- mDiscontinuitySeq = seq;
- }
}
if (err != OK) {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 0a1ed94..20d124c 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -368,11 +368,15 @@
AString iv;
if (itemMeta->findString("cipher-iv", &iv)) {
if ((!iv.startsWith("0x") && !iv.startsWith("0X"))
- || iv.size() != 16 * 2 + 2) {
+ || iv.size() > 16 * 2 + 2) {
ALOGE("malformed cipher IV '%s'.", iv.c_str());
return ERROR_MALFORMED;
}
+ while (iv.size() < 16 * 2 + 2) {
+ iv.insert("0", 1, 2);
+ }
+
memset(mAESInitVec, 0, sizeof(mAESInitVec));
for (size_t i = 0; i < 16; ++i) {
char c1 = tolower(iv.c_str()[2 + 2 * i]);
@@ -1180,8 +1184,7 @@
// Signal a format discontinuity to ATSParser to clear partial data
// from previous streams. Not doing this causes bitstream corruption.
if (mTSParser != NULL) {
- mTSParser->signalDiscontinuity(
- ATSParser::DISCONTINUITY_FORMATCHANGE, NULL /* extra */);
+ mTSParser.clear();
}
queueDiscontinuity(
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index 738f864..54da497 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -24,6 +24,7 @@
#include <media/stagefright/MediaErrors.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
+#include <utils/Vector.h>
namespace android {
@@ -110,8 +111,9 @@
uint32_t mDefaultSampleSize;
uint32_t mNumSampleSizes;
+ bool mHasTimeToSample;
uint32_t mTimeToSampleCount;
- uint32_t *mTimeToSample;
+ Vector<uint32_t> mTimeToSample;
struct SampleTimeEntry {
uint32_t mSampleIndex;
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index fb43a38..b8248c4 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -1438,8 +1438,8 @@
// The number of bytes received by this parser up to and
// including the final byte of this PCR_ext field.
- size_t byteOffsetFromStart =
- mNumTSPacketsParsed * 188 + byteOffsetFromStartOfTSPacket;
+ uint64_t byteOffsetFromStart =
+ uint64_t(mNumTSPacketsParsed) * 188 + byteOffsetFromStartOfTSPacket;
for (size_t i = 0; i < mPrograms.size(); ++i) {
updatePCR(PID, PCR, byteOffsetFromStart);
@@ -1558,8 +1558,8 @@
__attribute__((no_sanitize("integer")))
void ATSParser::updatePCR(
- unsigned /* PID */, uint64_t PCR, size_t byteOffsetFromStart) {
- ALOGV("PCR 0x%016" PRIx64 " @ %zu", PCR, byteOffsetFromStart);
+ unsigned /* PID */, uint64_t PCR, uint64_t byteOffsetFromStart) {
+ ALOGV("PCR 0x%016" PRIx64 " @ %" PRIx64, PCR, byteOffsetFromStart);
if (mNumPCRs == 2) {
mPCR[0] = mPCR[1];
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index fb03cd6..9d9102d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -182,10 +182,10 @@
// see feedTSPacket().
status_t parseTS(ABitReader *br, SyncEvent *event);
- void updatePCR(unsigned PID, uint64_t PCR, size_t byteOffsetFromStart);
+ void updatePCR(unsigned PID, uint64_t PCR, uint64_t byteOffsetFromStart);
uint64_t mPCR[2];
- size_t mPCRBytes[2];
+ uint64_t mPCRBytes[2];
int64_t mSystemTimeUs[2];
size_t mNumPCRs;
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index 72823e2..c3a481a 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -170,6 +170,11 @@
OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetPortParams(
const OMX_PARAM_PORTDEFINITIONTYPE *port) {
+
+ if (!isValidOMXParam(port)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (port->nPortIndex == kInputPortIndex) {
mWidth = port->format.video.nFrameWidth;
mHeight = port->format.video.nFrameHeight;
@@ -216,6 +221,10 @@
const OMX_PARAM_COMPONENTROLETYPE *roleParams =
(const OMX_PARAM_COMPONENTROLETYPE *)param;
+ if (!isValidOMXParam(roleParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (strncmp((const char *)roleParams->cRole,
mComponentRole,
OMX_MAX_STRINGNAME_SIZE - 1)) {
@@ -241,6 +250,10 @@
const OMX_VIDEO_PARAM_PORTFORMATTYPE* format =
(const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
+ if (!isValidOMXParam(format)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (format->nPortIndex == kInputPortIndex) {
if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar ||
@@ -270,6 +283,10 @@
const StoreMetaDataInBuffersParams *storeParam =
(const StoreMetaDataInBuffersParams *)param;
+ if (!isValidOMXParam(storeParam)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (storeParam->nPortIndex == kOutputPortIndex) {
return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
} else if (storeParam->nPortIndex != kInputPortIndex) {
@@ -304,6 +321,10 @@
OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
(OMX_VIDEO_PARAM_PORTFORMATTYPE *)param;
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (formatParams->nPortIndex == kInputPortIndex) {
if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) {
return OMX_ErrorNoMore;
@@ -329,6 +350,10 @@
OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
(OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param;
+ if (!isValidOMXParam(profileLevel)) {
+ return OMX_ErrorBadParameter;
+ }
+
if (profileLevel->nPortIndex != kOutputPortIndex) {
ALOGE("Invalid port index: %u", profileLevel->nPortIndex);
return OMX_ErrorUnsupportedIndex;
diff --git a/media/ndk/Android.mk b/media/ndk/Android.mk
index f287761..7f6b66b 100644
--- a/media/ndk/Android.mk
+++ b/media/ndk/Android.mk
@@ -45,6 +45,7 @@
LOCAL_SHARED_LIBRARIES := \
libbinder \
libmedia \
+ libmediadrm \
libstagefright \
libstagefright_foundation \
liblog \
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index 67d12a4..32aabdd 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -29,7 +29,6 @@
#include <binder/IServiceManager.h>
#include <media/ICrypto.h>
#include <media/IMediaDrmService.h>
-#include <media/IMediaPlayerService.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_util_Binder.h>
@@ -39,34 +38,17 @@
static sp<ICrypto> makeCrypto() {
sp<IServiceManager> sm = defaultServiceManager();
- sp<ICrypto> crypto;
+ sp<IBinder> binder = sm->getService(String16("media.drm"));
- char value[PROPERTY_VALUE_MAX];
- if (property_get("media.mediadrmservice.enable", value, NULL)
- && (!strcmp("1", value) || !strcasecmp("true", value))) {
- sp<IBinder> binder =
- sm->getService(String16("media.drm"));
- sp<IMediaDrmService> service =
- interface_cast<IMediaDrmService>(binder);
- if (service == NULL) {
- return NULL;
- }
- crypto = service->makeCrypto();
- } else {
- sp<IBinder> binder =
- sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service =
- interface_cast<IMediaPlayerService>(binder);
- if (service == NULL) {
- return NULL;
- }
- crypto = service->makeCrypto();
- }
-
- if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
+ sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
+ if (service == NULL) {
return NULL;
}
+ sp<ICrypto> crypto = service->makeCrypto();
+ if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
+ return NULL;
+ }
return crypto;
}
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index e98b124..be71f43 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -29,7 +29,6 @@
#include <media/stagefright/MediaErrors.h>
#include <binder/IServiceManager.h>
#include <media/IMediaDrmService.h>
-#include <media/IMediaPlayerService.h>
#include <ndk/NdkMediaCrypto.h>
@@ -150,34 +149,17 @@
static sp<IDrm> CreateDrm() {
sp<IServiceManager> sm = defaultServiceManager();
- sp<IDrm> drm;
+ sp<IBinder> binder = sm->getService(String16("media.drm"));
- char value[PROPERTY_VALUE_MAX];
- if (property_get("media.mediadrmservice.enable", value, NULL)
- && (!strcmp("1", value) || !strcasecmp("true", value))) {
- sp<IBinder> binder =
- sm->getService(String16("media.drm"));
- sp<IMediaDrmService> service =
- interface_cast<IMediaDrmService>(binder);
- if (service == NULL) {
- return NULL;
- }
- drm = service->makeDrm();
- } else {
- sp<IBinder> binder =
- sm->getService(String16("media.player"));
- sp<IMediaPlayerService> service =
- interface_cast<IMediaPlayerService>(binder);
- if (service == NULL) {
- return NULL;
- }
- drm = service->makeDrm();
- }
-
- if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
+ sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
+ if (service == NULL) {
return NULL;
}
+ sp<IDrm> drm = service->makeDrm();
+ if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
+ return NULL;
+ }
return drm;
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 1b69f8c..ca1a0b7 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -176,7 +176,7 @@
mHardwareStatus(AUDIO_HW_IDLE),
mMasterVolume(1.0f),
mMasterMute(false),
- mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX), // zero has a special meaning, so unavailable
+ // mNextUniqueId(AUDIO_UNIQUE_ID_USE_MAX),
mMode(AUDIO_MODE_INVALID),
mBtNrecIsOff(false),
mIsLowRamDevice(true),
@@ -184,6 +184,12 @@
mGlobalEffectEnableTime(0),
mSystemReady(false)
{
+ // unsigned instead of audio_unique_id_use_t, because ++ operator is unavailable for enum
+ for (unsigned use = AUDIO_UNIQUE_ID_USE_UNSPECIFIED; use < AUDIO_UNIQUE_ID_USE_MAX; use++) {
+ // zero ID has a special meaning, so unavailable
+ mNextUniqueIds[use] = AUDIO_UNIQUE_ID_USE_MAX;
+ }
+
getpid_cached = getpid();
const bool doLog = property_get_bool("ro.test_harness", false);
if (doLog) {
@@ -740,6 +746,17 @@
return thread->frameCount();
}
+size_t AudioFlinger::frameCountHAL(audio_io_handle_t ioHandle) const
+{
+ Mutex::Autolock _l(mLock);
+ ThreadBase *thread = checkThread_l(ioHandle);
+ if (thread == NULL) {
+ ALOGW("frameCountHAL() unknown thread %d", ioHandle);
+ return 0;
+ }
+ return thread->frameCountHAL();
+}
+
uint32_t AudioFlinger::latency(audio_io_handle_t output) const
{
Mutex::Autolock _l(mLock);
@@ -2440,13 +2457,23 @@
audio_unique_id_t AudioFlinger::nextUniqueId(audio_unique_id_use_t use)
{
- int32_t base = android_atomic_add(AUDIO_UNIQUE_ID_USE_MAX, &mNextUniqueId);
- // We have no way of recovering from wraparound
- LOG_ALWAYS_FATAL_IF(base == 0, "unique ID overflow");
// This is the internal API, so it is OK to assert on bad parameter.
LOG_ALWAYS_FATAL_IF((unsigned) use >= (unsigned) AUDIO_UNIQUE_ID_USE_MAX);
- ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
- return (audio_unique_id_t) (base | use);
+ const int maxRetries = use == AUDIO_UNIQUE_ID_USE_SESSION ? 3 : 1;
+ for (int retry = 0; retry < maxRetries; retry++) {
+ // The cast allows wraparound from max positive to min negative instead of abort
+ uint32_t base = (uint32_t) atomic_fetch_add_explicit(&mNextUniqueIds[use],
+ (uint_fast32_t) AUDIO_UNIQUE_ID_USE_MAX, memory_order_acq_rel);
+ ALOG_ASSERT(audio_unique_id_get_use(base) == AUDIO_UNIQUE_ID_USE_UNSPECIFIED);
+ // allow wrap by skipping 0 and -1 for session ids
+ if (!(base == 0 || base == (~0u & ~AUDIO_UNIQUE_ID_USE_MASK))) {
+ ALOGW_IF(retry != 0, "unique ID overflow for use %d", use);
+ return (audio_unique_id_t) (base | use);
+ }
+ }
+ // We have no way of recovering from wraparound
+ LOG_ALWAYS_FATAL("unique ID overflow for use %d", use);
+ // TODO Use a floor after wraparound. This may need a mutex.
}
AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 498c33e..96d38d0 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -131,6 +131,7 @@
virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const;
virtual audio_format_t format(audio_io_handle_t output) const;
virtual size_t frameCount(audio_io_handle_t ioHandle) const;
+ virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const;
virtual uint32_t latency(audio_io_handle_t output) const;
virtual status_t setMasterVolume(float value);
@@ -679,9 +680,8 @@
// protected by mClientLock
DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients;
- volatile int32_t mNextUniqueId; // updated by android_atomic_inc
- // nextUniqueId() returns uint32_t, but this is declared int32_t
- // because the atomic operations require an int32_t
+ // updated by atomic_fetch_add_explicit
+ volatile atomic_uint_fast32_t mNextUniqueIds[AUDIO_UNIQUE_ID_USE_MAX];
audio_mode_t mMode;
bool mBtNrecIsOff;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 21ce6b1..ff67fb2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2153,6 +2153,7 @@
desc->mFormat = mFormat;
desc->mFrameCount = mNormalFrameCount; // FIXME see
// AudioFlinger::frameCount(audio_io_handle_t)
+ desc->mFrameCountHAL = mFrameCount;
desc->mLatency = latency_l();
break;
@@ -7117,6 +7118,7 @@
desc->mSamplingRate = mSampleRate;
desc->mFormat = mFormat;
desc->mFrameCount = mFrameCount;
+ desc->mFrameCountHAL = mFrameCount;
desc->mLatency = 0;
break;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index cf896e0..e71840d 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -247,6 +247,10 @@
// Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
// and returns the [normal mix] buffer's frame count.
virtual size_t frameCount() const = 0;
+
+ // Return's the HAL's frame count i.e. fast mixer buffer size.
+ size_t frameCountHAL() const { return mFrameCount; }
+
size_t frameSize() const { return mFrameSize; }
// Should be "virtual status_t requestExitAndWait()" and override same
@@ -606,9 +610,6 @@
virtual size_t frameCount() const { return mNormalFrameCount; }
- // Return's the HAL's frame count i.e. fast mixer buffer size.
- size_t frameCountHAL() const { return mFrameCount; }
-
status_t getTimestamp_l(AudioTimestamp& timestamp);
void addPatchTrack(const sp<PatchTrack>& track);
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index b1347f4..a215b95 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -158,14 +158,14 @@
int indexMax) = 0;
// sets the new stream volume at a level corresponding to the supplied index for the
- // supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+ // supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME means
// setting volume for all devices
virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
int index,
audio_devices_t device) = 0;
// retrieve current volume index for the specified stream and the
- // specified device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
+ // specified device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME means
// querying the volume of the active device.
virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
int *index,
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index f73548d..55ee91f 100755
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -47,6 +47,23 @@
#define APM_AUDIO_DEVICE_IN_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_BUS)
/**
+ * Stub audio output device. Used in policy configuration file on platforms without audio outputs.
+ * This alias value to AUDIO_DEVICE_OUT_DEFAULT is only used in the audio policy context.
+ */
+#define AUDIO_DEVICE_OUT_STUB AUDIO_DEVICE_OUT_DEFAULT
+/**
+ * Stub audio input device. Used in policy configuration file on platforms without audio inputs.
+ * This alias value to AUDIO_DEVICE_IN_DEFAULT is only used in the audio policy context.
+ */
+#define AUDIO_DEVICE_IN_STUB AUDIO_DEVICE_IN_DEFAULT
+/**
+ * Alias to AUDIO_DEVICE_OUT_DEFAULT defined for clarification when this value is used by volume
+ * control APIs (e.g setStreamVolumeIndex().
+ */
+#define AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME AUDIO_DEVICE_OUT_DEFAULT
+
+
+/**
* Check if the state given correspond to an in call state.
* @TODO find a better name for widely call state
*
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 54fcd0b..ed2450c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -84,8 +84,6 @@
audio_devices_t getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
- audio_policy_dev_state_t getDeviceConnectionState(const sp<DeviceDescriptor> &devDesc) const;
-
status_t dump(int fd, const String8 &tag, int spaces = 0, bool verbose = true) const;
private:
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 93d03e6..dd2993d 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -106,7 +106,8 @@
sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t device,
const char *device_address,
- const char *device_name) const;
+ const char *device_name,
+ bool matchAdress = true) const;
status_t dump(int fd) const;
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
index 7c486c8..10f0766 100644
--- a/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
+++ b/services/audiopolicy/common/managerdefinitions/include/VolumeCurve.h
@@ -74,7 +74,7 @@
public:
VolumeCurvesForStream() : mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
{
- mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
+ mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, 0);
}
sp<VolumeCurve> getCurvesFor(device_category device) const
@@ -88,9 +88,9 @@
int getVolumeIndex(audio_devices_t device) const
{
device = Volume::getDeviceForVolume(device);
- // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
+ // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
if (mIndexCur.indexOfKey(device) < 0) {
- device = AUDIO_DEVICE_OUT_DEFAULT;
+ device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
}
return mIndexCur.valueFor(device);
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
index b8c0550..f382dec 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp
@@ -128,14 +128,35 @@
size_t patchesWritten = 0;
size_t patchesMax = *num_patches;
- for (size_t i = 0; i < size() && patchesWritten < patchesMax; i++) {
- const sp<AudioPatch> patch = valueAt(i);
- patches[patchesWritten] = patch->mPatch;
- patches[patchesWritten++].id = patch->mHandle;
+ *num_patches = 0;
+ for (size_t patchIndex = 0; patchIndex < size(); patchIndex++) {
+ // do not report patches with AUDIO_DEVICE_IN_STUB as source or
+ // AUDIO_DEVICE_OUT_STUB as sink as those devices are used by stub HALs by convention
+ const sp<AudioPatch> patch = valueAt(patchIndex);
+ bool skip = false;
+ for (size_t srcIndex = 0; srcIndex < patch->mPatch.num_sources && !skip; srcIndex++) {
+ if (patch->mPatch.sources[srcIndex].type == AUDIO_PORT_TYPE_DEVICE &&
+ patch->mPatch.sources[srcIndex].ext.device.type == AUDIO_DEVICE_IN_STUB) {
+ skip = true;
+ }
+ }
+ for (size_t sinkIndex = 0; sinkIndex < patch->mPatch.num_sinks && !skip; sinkIndex++) {
+ if (patch->mPatch.sinks[sinkIndex].type == AUDIO_PORT_TYPE_DEVICE &&
+ patch->mPatch.sinks[sinkIndex].ext.device.type == AUDIO_DEVICE_OUT_STUB) {
+ skip = true;
+ }
+ }
+ if (skip) {
+ continue; // to next audio patch
+ }
+ if (patchesWritten < patchesMax) {
+ patches[patchesWritten] = patch->mPatch;
+ patches[patchesWritten++].id = patch->mHandle;
+ }
+ (*num_patches)++;
ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d",
- i, patch->mPatch.num_sources, patch->mPatch.num_sinks);
+ patchIndex, patch->mPatch.num_sources, patch->mPatch.num_sinks);
}
- *num_patches = size();
ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches);
return NO_ERROR;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 44f380a..35f078e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -219,12 +219,6 @@
return NO_ERROR;
}
-audio_policy_dev_state_t DeviceVector::getDeviceConnectionState(const sp<DeviceDescriptor> &devDesc) const
-{
- ssize_t index = indexOf(devDesc);
- return index >= 0 ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
-}
-
void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 2d67bd2..a85c07f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -292,7 +292,8 @@
sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t device,
const char *device_address,
- const char *device_name) const
+ const char *device_name,
+ bool matchAdress) const
{
String8 address = (device_address == NULL) ? String8("") : String8(device_address);
// handle legacy remote submix case where the address was not always specified
@@ -305,11 +306,17 @@
if (hwModule->mHandle == 0) {
continue;
}
- DeviceVector deviceList =
- hwModule->getDeclaredDevices().getDevicesFromTypeAddr(device, address);
+ DeviceVector declaredDevices = hwModule->getDeclaredDevices();
+ DeviceVector deviceList = declaredDevices.getDevicesFromTypeAddr(device, address);
if (!deviceList.isEmpty()) {
return deviceList.itemAt(0);
}
+ if (!matchAdress) {
+ deviceList = declaredDevices.getDevicesFromType(device);
+ if (!deviceList.isEmpty()) {
+ return deviceList.itemAt(0);
+ }
+ }
}
sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
diff --git a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
index 8388a50..b3019e1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/StreamDescriptor.cpp
@@ -26,6 +26,7 @@
#include "StreamDescriptor.h"
#include "Gains.h"
+#include "policy.h"
#include <utils/Log.h>
#include <utils/String8.h>
@@ -39,15 +40,15 @@
// Initialize the current stream's index to mIndexMax so volume isn't 0 in
// cases where the Java layer doesn't call into the audio policy service to
// set the default volume.
- mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, mIndexMax);
+ mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, mIndexMax);
}
int StreamDescriptor::getVolumeIndex(audio_devices_t device) const
{
device = Volume::getDeviceForVolume(device);
- // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
+ // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME
if (mIndexCur.indexOfKey(device) < 0) {
- device = AUDIO_DEVICE_OUT_DEFAULT;
+ device = AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME;
}
return mIndexCur.valueFor(device);
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
index c6ed53e..f639551 100644
--- a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
@@ -51,6 +51,7 @@
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_IP),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BUS),
+ MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_STUB),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
@@ -74,6 +75,7 @@
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
+ MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
};
template<>
diff --git a/services/audiopolicy/config/audio_policy_configuration_stub.xml b/services/audiopolicy/config/audio_policy_configuration_stub.xml
new file mode 100644
index 0000000..a7747f8
--- /dev/null
+++ b/services/audiopolicy/config/audio_policy_configuration_stub.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- 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.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <modules>
+ <module name="stub" halVersion="2.0">
+ <attachedDevices>
+ <item>Default Out</item>
+ <item>Default In</item>
+ </attachedDevices>
+ <defaultOutputDevice>Default Out</defaultOutputDevice>
+ <mixPorts>
+ <mixPort name="stub output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+ </mixPort>
+
+ <mixPort name="stub input" role="sink">
+ <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+ samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
+ </mixPort>
+ </mixPorts>
+ <devicePorts>
+ <devicePort tagName="Default Out" type="AUDIO_DEVICE_OUT_STUB" role="sink">
+ </devicePort>
+
+ <devicePort tagName="Default In" type="AUDIO_DEVICE_IN_STUB" role="source">
+ </devicePort>
+ </devicePorts>
+ <routes>
+ <route type="mix" sink="Default Out" sources="stub output"/>
+
+ <route type="mix" sink="stub input" sources="Default In"/>
+ </routes>
+
+ </module>
+
+ <!-- Remote Submix Audio HAL -->
+ <xi:include href="r_submix_audio_policy_configuration.xml"/>
+
+ </modules>
+
+ <xi:include href="audio_policy_volumes.xml"/>
+ <xi:include href="default_volume_tables.xml"/>
+
+</audioPolicyConfiguration>
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index f2224fd..d31429c 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -254,10 +254,6 @@
case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
- if (!device) {
- ALOGE("getDeviceForStrategy() no device found for "\
- "STRATEGY_TRANSMITTED_THROUGH_SPEAKER");
- }
break;
case STRATEGY_SONIFICATION_RESPECTFUL:
@@ -373,11 +369,6 @@
if (device) break;
}
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
- if (device) break;
- device = mApmObserver->getDefaultOutputDevice()->type();
- if (device == AUDIO_DEVICE_NONE) {
- ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
- }
break;
case AUDIO_POLICY_FORCE_SPEAKER:
@@ -402,11 +393,6 @@
if (device) break;
}
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
- if (device) break;
- device = mApmObserver->getDefaultOutputDevice()->type();
- if (device == AUDIO_DEVICE_NONE) {
- ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
- }
break;
}
break;
@@ -431,9 +417,6 @@
if ((strategy == STRATEGY_SONIFICATION) ||
(mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
- if (device == AUDIO_DEVICE_NONE) {
- ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
- }
}
// The second device used for sonification is the same as the device used by media strategy
// FALL THROUGH
@@ -545,12 +528,6 @@
AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
device &= ~AUDIO_DEVICE_OUT_SPEAKER;
}
-
- if (device) break;
- device = mApmObserver->getDefaultOutputDevice()->type();
- if (device == AUDIO_DEVICE_NONE) {
- ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
- }
} break;
default:
@@ -558,6 +535,12 @@
break;
}
+ if (device == AUDIO_DEVICE_NONE) {
+ ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
+ device = mApmObserver->getDefaultOutputDevice()->type();
+ ALOGE_IF(device == AUDIO_DEVICE_NONE,
+ "getDeviceForStrategy() no default device defined");
+ }
ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
return device;
}
@@ -677,6 +660,14 @@
ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
break;
}
+ if (device == AUDIO_DEVICE_NONE) {
+ ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
+ if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
+ device = AUDIO_DEVICE_IN_STUB;
+ }
+ ALOGE_IF(device == AUDIO_DEVICE_NONE,
+ "getDeviceForInputSource() no default device defined");
+ }
ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
return device;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index fac2342..21ce8c9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -291,7 +291,15 @@
audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
const char *device_address)
{
- sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(device, device_address, "");
+ sp<DeviceDescriptor> devDesc =
+ mHwModules.getDeviceDescriptor(device, device_address, "",
+ (strlen(device_address) != 0)/*matchAddress*/);
+
+ if (devDesc == 0) {
+ ALOGW("getDeviceConnectionState() undeclared device, type %08x, address: %s",
+ device, device_address);
+ return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
+ }
DeviceVector *deviceVector;
@@ -303,7 +311,9 @@
ALOGW("getDeviceConnectionState() invalid device type %08x", device);
return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
- return deviceVector->getDeviceConnectionState(devDesc);
+
+ return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs)
@@ -1847,8 +1857,8 @@
// the requested device
// - For non default requested device, currently selected device on the output is either the
// requested device or one of the devices selected by the strategy
- // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT), apply volume only if no specific
- // device volume value exists for currently selected device.
+ // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
+ // no specific device volume value exists for currently selected device.
status_t status = NO_ERROR;
for (size_t i = 0; i < mOutputs.size(); i++) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
@@ -1857,7 +1867,8 @@
if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
continue;
}
- if (!desc->isStreamActive((audio_stream_type_t)curStream)) {
+ if (!(desc->isStreamActive((audio_stream_type_t)curStream) ||
+ (isInCall() && (curStream == AUDIO_STREAM_VOICE_CALL)))) {
continue;
}
routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
@@ -1866,7 +1877,7 @@
continue;
}
bool applyDefault = false;
- if (device != AUDIO_DEVICE_OUT_DEFAULT) {
+ if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
curStreamDevice |= device;
} else if (!mVolumeCurves->hasVolumeIndexForDevice(
stream, Volume::getDeviceForVolume(curStreamDevice))) {
@@ -1895,9 +1906,9 @@
if (!audio_is_output_device(device)) {
return BAD_VALUE;
}
- // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
+ // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
// the strategy the stream belongs to.
- if (device == AUDIO_DEVICE_OUT_DEFAULT) {
+ if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
}
device = Volume::getDeviceForVolume(device);
@@ -2331,19 +2342,29 @@
size_t portsMax = *num_ports;
*num_ports = 0;
if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
+ // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
+ // as they are used by stub HALs by convention
if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
- for (size_t i = 0;
- i < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) {
- mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
+ for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
+ if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
+ continue;
+ }
+ if (portsWritten < portsMax) {
+ mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
+ }
+ (*num_ports)++;
}
- *num_ports += mAvailableOutputDevices.size();
}
if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
- for (size_t i = 0;
- i < mAvailableInputDevices.size() && portsWritten < portsMax; i++) {
- mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
+ for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
+ if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
+ continue;
+ }
+ if (portsWritten < portsMax) {
+ mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
+ }
+ (*num_ports)++;
}
- *num_ports += mAvailableInputDevices.size();
}
}
if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
@@ -4880,7 +4901,9 @@
float volumeDb = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
// if a headset is connected, apply the following rules to ring tones and notifications
// to avoid sound level bursts in user's ears:
- // - always attenuate ring tones and notifications volume by 6dB
+ // - always attenuate notifications volume by 6dB
+ // - attenuate ring tones volume by 6dB unless music is not playing and
+ // speaker is part of the select devices
// - if music is playing, always limit the volume to current music volume,
// with a minimum threshold at -36dB so that notification is always perceived.
const routing_strategy stream_strategy = getStrategy(stream);
@@ -4894,12 +4917,12 @@
|| ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
(mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
mVolumeCurves->canBeMuted(stream)) {
- volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
// when the phone is ringing we must consider that music could have been paused just before
// by the music application and behave as if music was active if the last music track was
// just stopped
if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
mLimitRingtoneVolume) {
+ volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
@@ -4911,6 +4934,9 @@
volumeDb = minVolDB;
ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
}
+ } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
+ stream_strategy != STRATEGY_SONIFICATION) {
+ volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 94357b9..2d6a873 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -49,10 +49,8 @@
// ----------------------------------------------------------------------------
// Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
-#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
#define SONIFICATION_HEADSET_VOLUME_FACTOR_DB (-6)
// Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
-#define SONIFICATION_HEADSET_VOLUME_MIN 0.016
#define SONIFICATION_HEADSET_VOLUME_MIN_DB (-36)
// Time in milliseconds during which we consider that music is still active after a music
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index c011613..ebe65e4 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -66,7 +66,8 @@
libhardware \
libsync \
libcamera_metadata \
- libjpeg
+ libjpeg \
+ libmemunreachable
LOCAL_C_INCLUDES += \
system/media/private/camera/include \
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 0afd945..ad08a68 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -679,7 +679,8 @@
status_t res;
if (enabled) {
bool hasFlash = false;
- res = hasFlashUnitLocked(cameraId, &hasFlash);
+ // Check if it has a flash unit and leave camera device open.
+ res = hasFlashUnitLocked(cameraId, &hasFlash, /*keepDeviceOpen*/true);
// invalid camera?
if (res) {
// hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
@@ -688,6 +689,8 @@
}
// no flash unit?
if (!hasFlash) {
+ // Disconnect camera device if it has no flash.
+ disconnectCameraDevice();
return -ENOSYS;
}
} else if (mDevice == NULL || cameraId != mCameraId) {
@@ -716,21 +719,28 @@
status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
const String8& cameraId, bool *hasFlash) {
Mutex::Autolock l(mLock);
- return hasFlashUnitLocked(cameraId, hasFlash);
+ // Close device after checking if it has a flash unit.
+ return hasFlashUnitLocked(cameraId, hasFlash, /*keepDeviceOpen*/false);
}
status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
- const String8& cameraId, bool *hasFlash) {
+ const String8& cameraId, bool *hasFlash, bool keepDeviceOpen) {
+ bool closeCameraDevice = false;
+
if (!hasFlash) {
return BAD_VALUE;
}
status_t res;
if (mDevice == NULL) {
+ // Connect to camera device to query if it has a flash unit.
res = connectCameraDevice(cameraId);
if (res) {
return res;
}
+ // Close camera device only when it is just opened and the caller doesn't want to keep
+ // the camera device open.
+ closeCameraDevice = !keepDeviceOpen;
}
if (cameraId != mCameraId) {
@@ -745,6 +755,15 @@
*hasFlash = false;
}
+ if (closeCameraDevice) {
+ res = disconnectCameraDevice();
+ if (res != OK) {
+ ALOGE("%s: Failed to disconnect camera device. %s (%d)", __FUNCTION__,
+ strerror(-res), res);
+ return res;
+ }
+ }
+
return OK;
}
@@ -869,9 +888,13 @@
return OK;
}
- mParameters.set(CameraParameters::KEY_FLASH_MODE,
- CameraParameters::FLASH_MODE_OFF);
- mDevice->setParameters(mParameters);
+ if (mParameters.get(CameraParameters::KEY_FLASH_MODE)) {
+ // There is a flash, turn if off.
+ // (If there isn't one, leave the parameter null)
+ mParameters.set(CameraParameters::KEY_FLASH_MODE,
+ CameraParameters::FLASH_MODE_OFF);
+ mDevice->setParameters(mParameters);
+ }
mDevice->stopPreview();
status_t res = native_window_api_disconnect(mSurface.get(),
NATIVE_WINDOW_API_CAMERA);
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index 4d5fe8d..5cde372 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -203,7 +203,11 @@
status_t getSmallestSurfaceSize(int32_t *width, int32_t *height);
// protected by mLock
- status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash);
+ // If this function opens camera device in order to check if it has a flash unit, the
+ // camera device will remain open if keepDeviceOpen is true and the camera device will be
+ // closed if keepDeviceOpen is false. If camera device is already open when calling this
+ // function, keepDeviceOpen is ignored.
+ status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash, bool keepDeviceOpen);
CameraModule *mCameraModule;
const camera_module_callbacks_t *mCallbacks;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 0c88dad..13691e7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -41,6 +41,7 @@
#include <cutils/properties.h>
#include <gui/Surface.h>
#include <hardware/hardware.h>
+#include <memunreachable/memunreachable.h>
#include <media/AudioSystem.h>
#include <media/IMediaHTTPService.h>
#include <media/mediaplayer.h>
@@ -463,6 +464,12 @@
if (rc.isOk()) {
cameraInfo->facing = info.facing;
cameraInfo->orientation = info.orientation;
+ // CameraInfo is for android.hardware.Camera which does not
+ // support external camera facing. The closest approximation would be
+ // front camera.
+ if (cameraInfo->orientation == CAMERA_FACING_EXTERNAL) {
+ cameraInfo->orientation = CAMERA_FACING_FRONT;
+ }
}
return rc;
}
@@ -2595,16 +2602,32 @@
write(fd, "\n", 1);
camera3::CameraTraces::dump(fd, args);
- // change logging level
+ // Process dump arguments, if any
int n = args.size();
- for (int i = 0; i + 1 < n; i++) {
- String16 verboseOption("-v");
+ String16 verboseOption("-v");
+ String16 unreachableOption("--unreachable");
+ for (int i = 0; i < n; i++) {
if (args[i] == verboseOption) {
+ // change logging level
+ if (i + 1 >= n) continue;
String8 levelStr(args[i+1]);
int level = atoi(levelStr.string());
result = String8::format("\nSetting log level to %d.\n", level);
setLogLevel(level);
write(fd, result.string(), result.size());
+ } else if (args[i] == unreachableOption) {
+ // Dump memory analysis
+ // TODO - should limit be an argument parameter?
+ UnreachableMemoryInfo info;
+ bool success = GetUnreachableMemory(info, /*limit*/ 10000);
+ if (!success) {
+ dprintf(fd, "\nUnable to dump unreachable memory. "
+ "Try disabling SELinux enforcement.\n");
+ } else {
+ dprintf(fd, "\nDumping unreachable memory:\n");
+ std::string s = info.ToString(/*log_contents*/ true);
+ write(fd, s.c_str(), s.size());
+ }
}
}
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index b6c9900..dbec34e 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -75,6 +75,7 @@
Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mInputStream(),
+ mStreamingRequestId(REQUEST_ID_NONE),
mRequestIdCounter(0) {
ATRACE_CALL();
@@ -233,7 +234,8 @@
res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
msg.string());
} else {
- mStreamingRequestList.push_back(submitInfo->mRequestId);
+ Mutex::Autolock idLock(mStreamingRequestIdLock);
+ mStreamingRequestId = submitInfo->mRequestId;
}
} else {
err = mDevice->captureList(metadataRequestList, &(submitInfo->mLastFrameNumber));
@@ -270,17 +272,10 @@
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
- Vector<int>::iterator it, end;
- for (it = mStreamingRequestList.begin(), end = mStreamingRequestList.end();
- it != end; ++it) {
- if (*it == requestId) {
- break;
- }
- }
-
- if (it == end) {
- String8 msg = String8::format("Camera %d: Did not find request ID %d in list of "
- "streaming requests", mCameraId, requestId);
+ Mutex::Autolock idLock(mStreamingRequestIdLock);
+ if (mStreamingRequestId != requestId) {
+ String8 msg = String8::format("Camera %d: Canceling request ID %d doesn't match "
+ "current request ID %d", mCameraId, requestId, mStreamingRequestId);
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
@@ -290,7 +285,7 @@
if (err == OK) {
ALOGV("%s: Camera %d: Successfully cleared streaming request",
__FUNCTION__, mCameraId);
- mStreamingRequestList.erase(it);
+ mStreamingRequestId = REQUEST_ID_NONE;
} else {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %d: Error clearing streaming request: %s (%d)",
@@ -767,7 +762,8 @@
}
// FIXME: Also need check repeating burst.
- if (!mStreamingRequestList.isEmpty()) {
+ Mutex::Autolock idLock(mStreamingRequestIdLock);
+ if (mStreamingRequestId != REQUEST_ID_NONE) {
String8 msg = String8::format(
"Camera %d: Try to waitUntilIdle when there are active streaming requests",
mCameraId);
@@ -799,7 +795,8 @@
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
- mStreamingRequestList.clear();
+ Mutex::Autolock idLock(mStreamingRequestIdLock);
+ mStreamingRequestId = REQUEST_ID_NONE;
status_t err = mDevice->flush(lastFrameNumber);
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -982,6 +979,17 @@
}
}
+void CameraDeviceClient::notifyRepeatingRequestError(long lastFrameNumber) {
+ sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
+
+ if (remoteCb != 0) {
+ remoteCb->onRepeatingRequestError(lastFrameNumber);
+ }
+
+ Mutex::Autolock idLock(mStreamingRequestIdLock);
+ mStreamingRequestId = REQUEST_ID_NONE;
+}
+
void CameraDeviceClient::notifyIdle() {
// Thread safe. Don't bother locking.
sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 38137a2..d792b7d 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -160,6 +160,7 @@
const CaptureResultExtras& resultExtras);
virtual void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp);
virtual void notifyPrepared(int streamId);
+ virtual void notifyRepeatingRequestError(long lastFrameNumber);
/**
* Interface used by independent components of CameraDeviceClient.
@@ -205,8 +206,10 @@
int32_t id;
} mInputStream;
- // Request ID
- Vector<int> mStreamingRequestList;
+ // Streaming request ID
+ int32_t mStreamingRequestId;
+ Mutex mStreamingRequestIdLock;
+ static const int32_t REQUEST_ID_NONE = -1;
int32_t mRequestIdCounter;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 2cc150d..c0d6da6 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -306,6 +306,14 @@
}
template <typename TClientBase>
+void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameNumber) {
+ (void)lastFrameNumber;
+
+ ALOGV("%s: Repeating request was stopped. Last frame number is %ld",
+ __FUNCTION__, lastFrameNumber);
+}
+
+template <typename TClientBase>
int Camera2ClientBase<TClientBase>::getCameraId() const {
return TClientBase::mCameraId;
}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 6eea2f4..4f60034 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -73,6 +73,7 @@
virtual void notifyAutoWhitebalance(uint8_t newState,
int triggerId);
virtual void notifyPrepared(int streamId);
+ virtual void notifyRepeatingRequestError(long lastFrameNumber);
int getCameraId() const;
const sp<CameraDeviceBase>&
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index d570d4b..35ec531 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -209,6 +209,7 @@
virtual void notifyAutoExposure(uint8_t newState, int triggerId) = 0;
virtual void notifyAutoWhitebalance(uint8_t newState,
int triggerId) = 0;
+ virtual void notifyRepeatingRequestError(long lastFrameNumber) = 0;
protected:
virtual ~NotificationListener();
};
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index e395935..0e4e244 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1970,7 +1970,7 @@
if (mIsConstrainedHighSpeedConfiguration) {
pid_t requestThreadTid = mRequestThread->getTid();
res = requestPriority(getpid(), requestThreadTid,
- kConstrainedHighSpeedThreadPriority, true);
+ kConstrainedHighSpeedThreadPriority, /*asynchronous*/ false);
if (res != OK) {
ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
strerror(-res), res);
@@ -2807,6 +2807,11 @@
status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
Mutex::Autolock l(mRequestLock);
+ return clearRepeatingRequestsLocked(lastFrameNumber);
+
+}
+
+status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
mRepeatingRequests.clear();
if (lastFrameNumber != NULL) {
*lastFrameNumber = mRepeatingLastFrameNumber;
@@ -2961,6 +2966,22 @@
}
}
+void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
+ Mutex::Autolock l(mRequestLock);
+ // Check all streams needed by repeating requests are still valid. Otherwise, stop
+ // repeating requests.
+ for (const auto& request : mRepeatingRequests) {
+ for (const auto& s : request->mOutputStreams) {
+ if (s->isAbandoned()) {
+ int64_t lastFrameNumber = 0;
+ clearRepeatingRequestsLocked(&lastFrameNumber);
+ mListener->notifyRepeatingRequestError(lastFrameNumber);
+ return;
+ }
+ }
+ }
+}
+
bool Camera3Device::RequestThread::threadLoop() {
ATRACE_CALL();
status_t res;
@@ -2992,6 +3013,8 @@
if (res == TIMED_OUT) {
// Not a fatal error if getting output buffers time out.
cleanUpFailedRequests(/*sendRequestError*/ true);
+ // Check if any stream is abandoned.
+ checkAndStopRepeatingRequest();
return true;
} else if (res != OK) {
cleanUpFailedRequests(/*sendRequestError*/ false);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 349fb4c..0366ef6 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -565,6 +565,9 @@
// ERROR state to mark them as not having valid data. mNextRequests will be cleared.
void cleanUpFailedRequests(bool sendRequestError);
+ // Stop the repeating request if any of its output streams is abandoned.
+ void checkAndStopRepeatingRequest();
+
// Pause handling
bool waitIfPaused();
void unpauseForNewRequests();
@@ -578,6 +581,9 @@
// Handle AE precapture trigger cancel for devices <= CAMERA_DEVICE_API_VERSION_3_2.
void handleAePrecaptureCancelRequest(sp<CaptureRequest> request);
+ // Clear repeating requests. Must be called with mRequestLock held.
+ status_t clearRepeatingRequestsLocked(/*out*/ int64_t *lastFrameNumber = NULL);
+
wp<Camera3Device> mParent;
wp<camera3::StatusTracker> mStatusTracker;
camera3_device_t *mHal3Device;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 1e6452f..d2b98e6 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -157,6 +157,13 @@
if (res != OK) {
ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
__FUNCTION__, mId, strerror(-res), res);
+
+ // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
+ // let prepareNextBuffer handle the error.)
+ if (res == NO_INIT && mState == STATE_CONFIGURED) {
+ mState = STATE_ABANDONED;
+ }
+
return res;
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 80dce84..96d62d4 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -323,6 +323,11 @@
return mState == STATE_PREPARING;
}
+bool Camera3Stream::isAbandoned() const {
+ Mutex::Autolock l(mLock);
+ return mState == STATE_ABANDONED;
+}
+
status_t Camera3Stream::prepareNextBuffer() {
ATRACE_CALL();
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 810383d..0755700 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -95,6 +95,8 @@
* STATE_PREPARING => STATE_CONFIGURED:
* When sufficient prepareNextBuffer calls have been made to allocate
* all stream buffers, or cancelPrepare is called.
+ * STATE_CONFIGURED => STATE_ABANDONED:
+ * When the buffer queue of the stream is abandoned.
*
* Status Tracking:
* Each stream is tracked by StatusTracker as a separate component,
@@ -353,6 +355,11 @@
void removeBufferListener(
const sp<Camera3StreamBufferListener>& listener);
+ /**
+ * Return if the buffer queue of the stream is abandoned.
+ */
+ bool isAbandoned() const;
+
protected:
const int mId;
/**
@@ -380,7 +387,8 @@
STATE_IN_CONFIG,
STATE_IN_RECONFIG,
STATE_CONFIGURED,
- STATE_PREPARING
+ STATE_PREPARING,
+ STATE_ABANDONED
} mState;
mutable Mutex mLock;
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 3f7e7a7..6cb7a54 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -262,6 +262,11 @@
virtual status_t disconnect() = 0;
/**
+ * Return if the buffer queue of the stream is abandoned.
+ */
+ virtual bool isAbandoned() const = 0;
+
+ /**
* Debug dump of the stream's state.
*/
virtual void dump(int fd, const Vector<String16> &args) const = 0;
diff --git a/services/camera/libcameraservice/utils/AutoConditionLock.cpp b/services/camera/libcameraservice/utils/AutoConditionLock.cpp
index c8ee965..ed80a95 100644
--- a/services/camera/libcameraservice/utils/AutoConditionLock.cpp
+++ b/services/camera/libcameraservice/utils/AutoConditionLock.cpp
@@ -24,13 +24,15 @@
// Locks manager-owned mutex
AutoConditionLock::AutoConditionLock(const std::shared_ptr<WaitableMutexWrapper>& manager) :
- mManager{manager}, mAutoLock{manager->mMutex} {}
+ mManager{manager}, mAutoLock{manager->mMutex}, mAcquired(false) {}
// Unlocks manager-owned mutex
AutoConditionLock::~AutoConditionLock() {
// Unset the condition and wake everyone up before releasing lock
- mManager->mState = false;
- mManager->mCondition.broadcast();
+ if (mAcquired) {
+ mManager->mState = false;
+ mManager->mCondition.broadcast();
+ }
}
std::unique_ptr<AutoConditionLock> AutoConditionLock::waitAndAcquire(
@@ -59,6 +61,7 @@
// Set the condition and return
manager->mState = true;
+ scopedLock->mAcquired = true;
return scopedLock;
}
@@ -84,6 +87,7 @@
// Set the condition and return
manager->mState = true;
+ scopedLock->mAcquired = true;
return scopedLock;
}
diff --git a/services/camera/libcameraservice/utils/AutoConditionLock.h b/services/camera/libcameraservice/utils/AutoConditionLock.h
index 9a3eafc..b7f167b 100644
--- a/services/camera/libcameraservice/utils/AutoConditionLock.h
+++ b/services/camera/libcameraservice/utils/AutoConditionLock.h
@@ -92,6 +92,7 @@
std::shared_ptr<WaitableMutexWrapper> mManager;
Mutex::Autolock mAutoLock;
+ bool mAcquired;
};
}; // namespace android
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index f6ddf94..8baaf13 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -22,14 +22,15 @@
main_mediadrmserver.cpp
LOCAL_SHARED_LIBRARIES:= \
- libui \
- liblog \
- libutils \
libbinder \
libcutils \
- libstagefright \
- libmediaplayerservice \
+ liblog \
libmedia \
+ libmediadrm \
+ libmediaplayerservice \
+ libstagefright \
+ libui \
+ libutils \
LOCAL_C_INCLUDES := \
frameworks/av/media/libmediaplayerservice \
diff --git a/services/mediadrm/MediaDrmService.cpp b/services/mediadrm/MediaDrmService.cpp
index 36ab8fe..331c568 100644
--- a/services/mediadrm/MediaDrmService.cpp
+++ b/services/mediadrm/MediaDrmService.cpp
@@ -19,13 +19,13 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaDrmService"
-#include <utils/Log.h>
-#include <binder/IServiceManager.h>
#include "MediaDrmService.h"
-#include "Crypto.h"
-#include "Drm.h"
+#include <binder/IServiceManager.h>
+#include <media/Crypto.h>
+#include <media/Drm.h>
+#include <utils/Log.h>
namespace android {