Merge "audio hal: Fix multichannel playback"
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
index 96ecfa0..3512730 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -122,5 +122,5 @@
void prepare2(int maxCount, int streamId);
- void setDeferredConfiguration(int streamId, in OutputConfiguration outputConfiguration);
+ void finalizeOutputConfigurations(int streamId, in OutputConfiguration outputConfiguration);
}
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 9cd3a47..f570b7f 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -56,12 +56,22 @@
return mHeight;
}
+bool OutputConfiguration::isDeferred() const {
+ return mIsDeferred;
+}
+
+bool OutputConfiguration::isShared() const {
+ return mIsShared;
+}
+
OutputConfiguration::OutputConfiguration() :
mRotation(INVALID_ROTATION),
mSurfaceSetID(INVALID_SET_ID),
mSurfaceType(SURFACE_TYPE_UNKNOWN),
mWidth(0),
- mHeight(0) {
+ mHeight(0),
+ mIsDeferred(false),
+ mIsShared(false) {
}
OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
@@ -105,42 +115,28 @@
return err;
}
- // numSurfaces is the total number of surfaces for this OutputConfiguration,
- // regardless the surface is deferred or not.
- int numSurfaces = 0;
- if ((err = parcel->readInt32(&numSurfaces)) != OK) {
- ALOGE("%s: Failed to read maxSurfaces from parcel", __FUNCTION__);
+ int isDeferred = 0;
+ if ((err = parcel->readInt32(&isDeferred)) != OK) {
+ ALOGE("%s: Failed to read surface isDeferred flag from parcel", __FUNCTION__);
return err;
}
- if (numSurfaces < 1) {
- ALOGE("%s: there has to be at least 1 surface per"
- " outputConfiguration", __FUNCTION__);
+
+ int isShared = 0;
+ if ((err = parcel->readInt32(&isShared)) != OK) {
+ ALOGE("%s: Failed to read surface isShared flag from parcel", __FUNCTION__);
+ return err;
+ }
+
+ if (isDeferred && surfaceType != SURFACE_TYPE_SURFACE_VIEW &&
+ surfaceType != SURFACE_TYPE_SURFACE_TEXTURE) {
+ ALOGE("%s: Invalid surface type for deferred configuration", __FUNCTION__);
return BAD_VALUE;
}
- // Read all surfaces from parcel. If a surface is deferred, readFromPacel
- // returns error, and a null surface is put into the mGbps. We assume all
- // deferred surfaces are after non-deferred surfaces in the parcel.
- // TODO: Need better way to detect deferred surface than using error
- // return from readFromParcel.
- std::vector<sp<IGraphicBufferProducer>> gbps;
- for (int i = 0; i < numSurfaces; i++) {
- view::Surface surfaceShim;
- if ((err = surfaceShim.readFromParcel(parcel)) != OK) {
- // Read surface failure for deferred surface configuration is expected.
- if ((surfaceType == SURFACE_TYPE_SURFACE_VIEW ||
- surfaceType == SURFACE_TYPE_SURFACE_TEXTURE)) {
- ALOGV("%s: Get null surface from a deferred surface configuration (%dx%d)",
- __FUNCTION__, width, height);
- err = OK;
- } else {
- ALOGE("%s: Failed to read surface from parcel", __FUNCTION__);
- return err;
- }
- }
- gbps.push_back(surfaceShim.graphicBufferProducer);
- ALOGV("%s: OutputConfiguration: gbps[%d] : %p, name %s", __FUNCTION__,
- i, gbps[i].get(), String8(surfaceShim.name).string());
+ std::vector<view::Surface> surfaceShims;
+ if ((err = parcel->readParcelableVector(&surfaceShims)) != OK) {
+ ALOGE("%s: Failed to read surface(s) from parcel", __FUNCTION__);
+ return err;
}
mRotation = rotation;
@@ -148,7 +144,14 @@
mSurfaceType = surfaceType;
mWidth = width;
mHeight = height;
- mGbps = std::move(gbps);
+ mIsDeferred = isDeferred != 0;
+ mIsShared = isShared != 0;
+ for (auto& surface : surfaceShims) {
+ ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
+ surface.graphicBufferProducer.get(),
+ String8(surface.name).string());
+ mGbps.push_back(surface.graphicBufferProducer);
+ }
ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d",
__FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType);
@@ -161,6 +164,8 @@
mGbps.push_back(gbp);
mRotation = rotation;
mSurfaceSetID = surfaceSetID;
+ mIsDeferred = false;
+ mIsShared = false;
}
status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
@@ -183,18 +188,21 @@
err = parcel->writeInt32(mHeight);
if (err != OK) return err;
- int numSurfaces = mGbps.size();
- err = parcel->writeInt32(numSurfaces);
+ err = parcel->writeInt32(mIsDeferred ? 1 : 0);
if (err != OK) return err;
- for (int i = 0; i < numSurfaces; i++) {
+ err = parcel->writeInt32(mIsShared ? 1 : 0);
+ if (err != OK) return err;
+
+ std::vector<view::Surface> surfaceShims;
+ for (auto& gbp : mGbps) {
view::Surface surfaceShim;
surfaceShim.name = String16("unknown_name"); // name of surface
- surfaceShim.graphicBufferProducer = mGbps[i];
-
- err = surfaceShim.writeToParcel(parcel);
- if (err != OK) return err;
+ surfaceShim.graphicBufferProducer = gbp;
+ surfaceShims.push_back(surfaceShim);
}
+ err = parcel->writeParcelableVector(surfaceShims);
+ if (err != OK) return err;
return OK;
}
diff --git a/include/camera/camera2/OutputConfiguration.h b/include/camera/camera2/OutputConfiguration.h
index 2961e2a..8e641c7 100644
--- a/include/camera/camera2/OutputConfiguration.h
+++ b/include/camera/camera2/OutputConfiguration.h
@@ -44,6 +44,8 @@
int getSurfaceType() const;
int getWidth() const;
int getHeight() const;
+ bool isDeferred() const;
+ bool isShared() const;
/**
* Keep impl up-to-date with OutputConfiguration.java in frameworks/base
*/
@@ -70,6 +72,8 @@
mSurfaceType == other.mSurfaceType &&
mWidth == other.mWidth &&
mHeight == other.mHeight &&
+ mIsDeferred == other.mIsDeferred &&
+ mIsShared == other.mIsShared &&
gbpsEqual(other));
}
bool operator != (const OutputConfiguration& other) const {
@@ -92,7 +96,12 @@
if (mRotation != other.mRotation) {
return mRotation < other.mRotation;
}
-
+ if (mIsDeferred != other.mIsDeferred) {
+ return mIsDeferred < other.mIsDeferred;
+ }
+ if (mIsShared != other.mIsShared) {
+ return mIsShared < other.mIsShared;
+ }
return gbpsLessThan(other);
}
bool operator > (const OutputConfiguration& other) const {
@@ -108,6 +117,8 @@
int mSurfaceType;
int mWidth;
int mHeight;
+ bool mIsDeferred;
+ bool mIsShared;
// helper function
static String16 readMaybeEmptyString16(const android::Parcel* parcel);
};
diff --git a/include/media/IMediaAnalyticsService.h b/include/media/IMediaAnalyticsService.h
index 9213637..f635e94 100644
--- a/include/media/IMediaAnalyticsService.h
+++ b/include/media/IMediaAnalyticsService.h
@@ -52,14 +52,6 @@
// caller continues to own the passed item
virtual MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) = 0;
-
- // return lists of records that match the supplied parameters.
- // finished [or not] records since time 'ts' with key 'key'
- // timestamp 'ts' is nanoseconds, unix time.
- // caller responsible for deallocating returned data structures
- virtual List<MediaAnalyticsItem *> *getMediaAnalyticsItemList(bool finished, int64_t ts) = 0;
- virtual List<MediaAnalyticsItem *> *getMediaAnalyticsItemList(bool finished, int64_t ts, MediaAnalyticsItem::Key key) = 0;
-
};
// ----------------------------------------------------------------------------
diff --git a/media/libaudiohal/EffectBufferHalHidl.cpp b/media/libaudiohal/EffectBufferHalHidl.cpp
index 9a9535b..82b4a75 100644
--- a/media/libaudiohal/EffectBufferHalHidl.cpp
+++ b/media/libaudiohal/EffectBufferHalHidl.cpp
@@ -80,7 +80,7 @@
retval = OK;
}
});
- if (retval == OK) {
+ if (result.isOk() && retval == OK) {
mMemory = hardware::mapMemory(mHidlBuffer.data);
if (mMemory != 0) {
mMemory->update();
@@ -91,8 +91,10 @@
ALOGE("Failed to map allocated ashmem");
retval = NO_MEMORY;
}
+ } else {
+ ALOGE("Failed to allocate %d bytes from ashmem", (int)mBufferSize);
}
- return retval;
+ return result.isOk() ? retval : FAILED_TRANSACTION;
}
audio_buffer_t* EffectBufferHalHidl::audioBuffer() {
diff --git a/media/libmedia/IMediaAnalyticsService.cpp b/media/libmedia/IMediaAnalyticsService.cpp
index cc4aa35..340cf19 100644
--- a/media/libmedia/IMediaAnalyticsService.cpp
+++ b/media/libmedia/IMediaAnalyticsService.cpp
@@ -50,7 +50,6 @@
enum {
GENERATE_UNIQUE_SESSIONID = IBinder::FIRST_CALL_TRANSACTION,
SUBMIT_ITEM,
- GET_ITEM_LIST,
};
class BpMediaAnalyticsService: public BpInterface<IMediaAnalyticsService>
@@ -115,45 +114,6 @@
return sessionid;
}
- virtual List<MediaAnalyticsItem*> *getMediaAnalyticsItemList(bool finished, nsecs_t ts)
- {
- return getMediaAnalyticsItemList(finished, ts, MediaAnalyticsItem::kKeyAny);
- }
-
- virtual List<MediaAnalyticsItem*> *getMediaAnalyticsItemList(bool finished, nsecs_t ts, MediaAnalyticsItem::Key key)
- {
- Parcel data, reply;
- status_t err;
-
- data.writeInterfaceToken(IMediaAnalyticsService::getInterfaceDescriptor());
- data.writeInt32(finished);
- data.writeInt64(ts);
- const char *str = key.c_str();
- if (key.empty()) {
- str = MediaAnalyticsItem::kKeyNone.c_str();
- }
- data.writeCString(str);
- err = remote()->transact(GET_ITEM_LIST, data, &reply);
- if (err != NO_ERROR) {
- return NULL;
- }
-
- // read a count
- int32_t count = reply.readInt32();
- List<MediaAnalyticsItem*> *list = NULL;
-
- if (count > 0) {
- list = new List<MediaAnalyticsItem*>();
- for (int i=0;i<count;i++) {
- MediaAnalyticsItem *item = new MediaAnalyticsItem();
- // XXX: watch for failures here
- item->readFromParcel(reply);
- list->push_back(item);
- }
- }
-
- return list;
- }
};
IMPLEMENT_META_INTERFACE(MediaAnalyticsService, "android.media.IMediaAnalyticsService");
@@ -204,33 +164,6 @@
return NO_ERROR;
} break;
- case GET_ITEM_LIST: {
- CHECK_INTERFACE(IMediaPlayerService, data, reply);
- // get the parameters
- bool finished = data.readInt32();
- nsecs_t ts = data.readInt64();
- MediaAnalyticsItem::Key key = data.readCString();
-
- // find the (0 or more) items
- List<MediaAnalyticsItem*> *list = getMediaAnalyticsItemList(finished, ts, key);
- // encapsulate/serialize them
- reply->writeInt32(list->size());
- if (list->size() > 0) {
- for (List<MediaAnalyticsItem*>::iterator it = list->begin();
- it != list->end(); it++) {
- (*it)->writeToParcel(reply);
- }
-
-
- }
-
- // avoid leakiness; organized discarding of list and its contents
- list->clear();
- delete list;
-
- return NO_ERROR;
- } break;
-
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/MediaAnalyticsItem.cpp b/media/libmedia/MediaAnalyticsItem.cpp
index 76397c7..375d1d5 100644
--- a/media/libmedia/MediaAnalyticsItem.cpp
+++ b/media/libmedia/MediaAnalyticsItem.cpp
@@ -49,15 +49,15 @@
const MediaAnalyticsItem::Key MediaAnalyticsItem::kKeyAny = "any";
const MediaAnalyticsItem::Key MediaAnalyticsItem::kKeyNone = "none";
-const char * const MediaAnalyticsItem::EnabledProperty = "media.analytics.enabled";
-const char * const MediaAnalyticsItem::EnabledPropertyPersist = "persist.media.analytics.enabled";
+const char * const MediaAnalyticsItem::EnabledProperty = "media.metrics.enabled";
+const char * const MediaAnalyticsItem::EnabledPropertyPersist = "persist.media.metrics.enabled";
const int MediaAnalyticsItem::EnabledProperty_default = 0;
// access functions for the class
MediaAnalyticsItem::MediaAnalyticsItem()
- : mPid(0),
- mUid(0),
+ : mPid(-1),
+ mUid(-1),
mSessionID(MediaAnalyticsItem::SessionIDNone),
mTimestamp(0),
mFinalized(0),
@@ -67,8 +67,8 @@
}
MediaAnalyticsItem::MediaAnalyticsItem(MediaAnalyticsItem::Key key)
- : mPid(0),
- mUid(0),
+ : mPid(-1),
+ mUid(-1),
mSessionID(MediaAnalyticsItem::SessionIDNone),
mTimestamp(0),
mFinalized(0),
@@ -92,6 +92,9 @@
// clean allocated storage from key
mKey.clear();
+ // clean various major parameters
+ mSessionID = MediaAnalyticsItem::SessionIDNone;
+
// clean attributes
// contents of the attributes
for (size_t i = 0 ; i < mPropSize; i++ ) {
@@ -646,7 +649,6 @@
}
-
AString MediaAnalyticsItem::toString() {
AString result = "(";
@@ -763,7 +765,7 @@
//static
sp<IMediaAnalyticsService> MediaAnalyticsItem::getInstance() {
- static const char *servicename = "media.analytics";
+ static const char *servicename = "media.metrics";
static int tries_remaining = SVC_TRIES;
int enabled = isEnabled();
diff --git a/media/libmediaanalyticsservice/Android.mk b/media/libmediaanalyticsservice/Android.mk
deleted file mode 100644
index dd59651..0000000
--- a/media/libmediaanalyticsservice/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-#
-# libmediaanalyticsservice
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- MediaAnalyticsService.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libbinder \
- libcutils \
- liblog \
- libdl \
- libgui \
- libmedia \
- libmediautils \
- libstagefright_foundation \
- libutils
-
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libmedia
-
-LOCAL_C_INCLUDES := \
- $(TOP)/frameworks/av/media/libstagefright/include \
- $(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)/frameworks/native/include/media/hardware \
- $(TOP)/external/tremolo/Tremolo \
- libcore/include \
-
-LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
-LOCAL_CLANG := true
-
-LOCAL_MODULE:= libmediaanalyticsservice
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index f05e336..192eccd 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -435,7 +435,7 @@
void MPEG4Writer::initInternal(int fd) {
ALOGV("initInternal");
- mFd = fd;
+ mFd = dup(fd);
mNextFd = -1;
mInitCheck = mFd < 0? NO_INIT: OK;
mIsRealTimeRecording = true;
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index a55c23b..f6ca903 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -455,29 +455,15 @@
const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
outputConfiguration.getGraphicBufferProducers();
size_t numBufferProducers = bufferProducers.size();
+ bool deferredConsumer = outputConfiguration.isDeferred();
+ bool isShared = outputConfiguration.isShared();
if (numBufferProducers > MAX_SURFACES_PER_STREAM) {
ALOGE("%s: GraphicBufferProducer count %zu for stream exceeds limit of %d",
__FUNCTION__, bufferProducers.size(), MAX_SURFACES_PER_STREAM);
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Surface count is too high");
}
- if (numBufferProducers == 0) {
- ALOGE("%s: GraphicBufferProducer count 0 is not valid", __FUNCTION__);
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Malformed surface");
- }
- size_t deferredConsumerCnt = 0;
- for (auto bufferProducer : bufferProducers) {
- if (bufferProducer == nullptr) {
- deferredConsumerCnt++;
- }
- }
- if (deferredConsumerCnt > MAX_DEFERRED_SURFACES) {
- ALOGE("%s: %zu deferred consumer is not supported", __FUNCTION__, deferredConsumerCnt);
- return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "More than %d deferred consumer", MAX_DEFERRED_SURFACES);
- }
- bool deferredConsumer = deferredConsumerCnt > 0;
- bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 1;
+ bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
int surfaceType = outputConfiguration.getSurfaceType();
bool validSurfaceType = ((surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) ||
(surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_TEXTURE));
@@ -494,170 +480,51 @@
std::vector<sp<Surface>> surfaces;
std::vector<sp<IBinder>> binders;
- int streamWidth, streamHeight, streamFormat;
- int width, height, format;
- int32_t streamConsumerUsage;
- int32_t consumerUsage;
- android_dataspace dataSpace, streamDataSpace;
status_t err;
// Create stream for deferred surface case.
if (deferredConsumerOnly) {
- return createDeferredSurfaceStreamLocked(outputConfiguration, newStreamId);
+ return createDeferredSurfaceStreamLocked(outputConfiguration, isShared, newStreamId);
}
- bool isFirstSurface = true;
- streamWidth = -1;
- streamHeight = -1;
- streamFormat = -1;
- streamDataSpace = HAL_DATASPACE_UNKNOWN;
- streamConsumerUsage = 0;
-
+ OutputStreamInfo streamInfo;
+ bool isStreamInfoValid = false;
for (auto& bufferProducer : bufferProducers) {
- if (bufferProducer == nullptr) {
- continue;
- }
-
// Don't create multiple streams for the same target surface
- {
- ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
- if (index != NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
- "(ID %zd)", mCameraIdStr.string(), index);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
- }
- }
-
- // HACK b/10949105
- // Query consumer usage bits to set async operation mode for
- // GLConsumer using controlledByApp parameter.
- bool useAsync = false;
- if ((err = bufferProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
- &consumerUsage)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
- }
- if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
- ALOGW("%s: Camera %s with consumer usage flag: 0x%x: Forcing asynchronous mode for stream",
- __FUNCTION__, mCameraIdStr.string(), consumerUsage);
- useAsync = true;
- }
-
- int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
- GRALLOC_USAGE_RENDERSCRIPT;
- int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
- GraphicBuffer::USAGE_HW_TEXTURE |
- GraphicBuffer::USAGE_HW_COMPOSER;
- bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
- (consumerUsage & allowedFlags) != 0;
-
sp<IBinder> binder = IInterface::asBinder(bufferProducer);
- sp<Surface> surface = new Surface(bufferProducer, useAsync);
- ANativeWindow *anw = surface.get();
-
- if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface width: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
- }
- if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface height: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
- }
- if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
- }
- if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
- reinterpret_cast<int*>(&dataSpace))) != OK) {
- String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
- mCameraIdStr.string(), strerror(-err), err);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ ssize_t index = mStreamMap.indexOfKey(binder);
+ if (index != NAME_NOT_FOUND) {
+ String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
+ "(ID %zd)", mCameraIdStr.string(), index);
+ ALOGW("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
}
- // FIXME: remove this override since the default format should be
- // IMPLEMENTATION_DEFINED. b/9487482
- if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
- format <= HAL_PIXEL_FORMAT_BGRA_8888) {
- ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
- __FUNCTION__, mCameraIdStr.string(), format);
- format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
- }
- // Round dimensions to the nearest dimensions available for this format
- if (flexibleConsumer && isPublicFormat(format) &&
- !CameraDeviceClient::roundBufferDimensionNearest(width, height,
- format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
- String8 msg = String8::format("Camera %s: No supported stream configurations with "
- "format %#x defined, failed to create output stream",
- mCameraIdStr.string(), format);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
- }
- if (isFirstSurface) {
- streamWidth = width;
- streamHeight = height;
- streamFormat = format;
- streamDataSpace = dataSpace;
- streamConsumerUsage = consumerUsage;
- isFirstSurface = false;
- }
- if (width != streamWidth) {
- String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
- mCameraIdStr.string(), width, streamWidth);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
- }
- if (height != streamHeight) {
- String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
- mCameraIdStr.string(), height, streamHeight);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
- }
- if (format != streamFormat) {
- String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
- mCameraIdStr.string(), format, streamFormat);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
- }
- if (dataSpace != streamDataSpace) {
- String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
- mCameraIdStr.string(), dataSpace, streamDataSpace);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
- }
- //At the native side, there isn't a way to check whether 2 surfaces come from the same
- //surface class type. Use usage flag to approximate the comparison.
- //TODO: Support surfaces of different surface class type.
- if (consumerUsage != streamConsumerUsage) {
- String8 msg = String8::format(
- "Camera %s:Surface usage flag doesn't match 0x%x vs 0x%x",
- mCameraIdStr.string(), consumerUsage, streamConsumerUsage);
- ALOGE("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ sp<Surface> surface;
+ res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer);
+
+ if (!res.isOk())
+ return res;
+
+ if (!isStreamInfoValid) {
+ isStreamInfoValid = true;
}
- binders.push_back(binder);
+ binders.push_back(IInterface::asBinder(bufferProducer));
surfaces.push_back(surface);
}
int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
- err = mDevice->createStream(surfaces, deferredConsumer, width, height, format, dataSpace,
+ err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
+ streamInfo.height, streamInfo.format, streamInfo.dataSpace,
static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
- &streamId, outputConfiguration.getSurfaceSetID());
+ &streamId, outputConfiguration.getSurfaceSetID(), isShared);
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
"Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
- mCameraIdStr.string(), width, height, format, dataSpace, strerror(-err), err);
+ mCameraIdStr.string(), streamInfo.width, streamInfo.height, streamInfo.format,
+ streamInfo.dataSpace, strerror(-err), err);
} else {
int i = 0;
for (auto& binder : binders) {
@@ -665,9 +532,13 @@
__FUNCTION__, binder.get(), streamId, i);
mStreamMap.add(binder, StreamSurfaceId(streamId, i++));
}
+
+ mStreamInfoMap[streamId] = streamInfo;
+
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for output surface"
" (%d x %d) with format 0x%x.",
- __FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);
+ __FUNCTION__, mCameraIdStr.string(), streamId, streamInfo.width,
+ streamInfo.height, streamInfo.format);
// Set transform flags to ensure preview to be rotated correctly.
res = setStreamTransformLocked(streamId);
@@ -680,6 +551,7 @@
binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
const hardware::camera2::params::OutputConfiguration &outputConfiguration,
+ bool isShared,
/*out*/
int* newStreamId) {
int width, height, format, surfaceType;
@@ -708,7 +580,7 @@
err = mDevice->createStream(noSurface, /*hasDeferredConsumer*/true, width,
height, format, dataSpace,
static_cast<camera3_stream_rotation_t>(outputConfiguration.getRotation()),
- &streamId, outputConfiguration.getSurfaceSetID(), consumerUsage);
+ &streamId, outputConfiguration.getSurfaceSetID(), isShared, consumerUsage);
if (err != OK) {
res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -720,6 +592,9 @@
// relocated to mStreamMap.
mDeferredStreams.push_back(streamId);
+ mStreamInfoMap.emplace(std::piecewise_construct, std::forward_as_tuple(streamId),
+ std::forward_as_tuple(width, height, format, dataSpace, consumerUsage));
+
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
" (%d x %d) stream with format 0x%x.",
__FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);
@@ -862,6 +737,140 @@
}
}
+binder::Status CameraDeviceClient::createSurfaceFromGbp(
+ OutputStreamInfo& streamInfo, bool isStreamInfoValid,
+ sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp) {
+
+ // bufferProducer must be non-null
+ if (gbp == nullptr) {
+ String8 msg = String8::format("Camera %s: Surface is NULL", mCameraIdStr.string());
+ ALOGW("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ // HACK b/10949105
+ // Query consumer usage bits to set async operation mode for
+ // GLConsumer using controlledByApp parameter.
+ bool useAsync = false;
+ int32_t consumerUsage;
+ status_t err;
+ if ((err = gbp->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS,
+ &consumerUsage)) != OK) {
+ String8 msg = String8::format("Camera %s: Failed to query Surface consumer usage: %s (%d)",
+ mCameraIdStr.string(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ }
+ if (consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) {
+ ALOGW("%s: Camera %s with consumer usage flag: 0x%x: Forcing asynchronous mode for stream",
+ __FUNCTION__, mCameraIdStr.string(), consumerUsage);
+ useAsync = true;
+ }
+
+ int32_t disallowedFlags = GraphicBuffer::USAGE_HW_VIDEO_ENCODER |
+ GRALLOC_USAGE_RENDERSCRIPT;
+ int32_t allowedFlags = GraphicBuffer::USAGE_SW_READ_MASK |
+ GraphicBuffer::USAGE_HW_TEXTURE |
+ GraphicBuffer::USAGE_HW_COMPOSER;
+ bool flexibleConsumer = (consumerUsage & disallowedFlags) == 0 &&
+ (consumerUsage & allowedFlags) != 0;
+
+ surface = new Surface(gbp, useAsync);
+ ANativeWindow *anw = surface.get();
+
+ int width, height, format;
+ android_dataspace dataSpace;
+ if ((err = anw->query(anw, NATIVE_WINDOW_WIDTH, &width)) != OK) {
+ String8 msg = String8::format("Camera %s: Failed to query Surface width: %s (%d)",
+ mCameraIdStr.string(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ }
+ if ((err = anw->query(anw, NATIVE_WINDOW_HEIGHT, &height)) != OK) {
+ String8 msg = String8::format("Camera %s: Failed to query Surface height: %s (%d)",
+ mCameraIdStr.string(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ }
+ if ((err = anw->query(anw, NATIVE_WINDOW_FORMAT, &format)) != OK) {
+ String8 msg = String8::format("Camera %s: Failed to query Surface format: %s (%d)",
+ mCameraIdStr.string(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ }
+ if ((err = anw->query(anw, NATIVE_WINDOW_DEFAULT_DATASPACE,
+ reinterpret_cast<int*>(&dataSpace))) != OK) {
+ String8 msg = String8::format("Camera %s: Failed to query Surface dataspace: %s (%d)",
+ mCameraIdStr.string(), strerror(-err), err);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
+ }
+
+ // FIXME: remove this override since the default format should be
+ // IMPLEMENTATION_DEFINED. b/9487482
+ if (format >= HAL_PIXEL_FORMAT_RGBA_8888 &&
+ format <= HAL_PIXEL_FORMAT_BGRA_8888) {
+ ALOGW("%s: Camera %s: Overriding format %#x to IMPLEMENTATION_DEFINED",
+ __FUNCTION__, mCameraIdStr.string(), format);
+ format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+ }
+ // Round dimensions to the nearest dimensions available for this format
+ if (flexibleConsumer && isPublicFormat(format) &&
+ !CameraDeviceClient::roundBufferDimensionNearest(width, height,
+ format, dataSpace, mDevice->info(), /*out*/&width, /*out*/&height)) {
+ String8 msg = String8::format("Camera %s: No supported stream configurations with "
+ "format %#x defined, failed to create output stream",
+ mCameraIdStr.string(), format);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+
+ if (!isStreamInfoValid) {
+ streamInfo.width = width;
+ streamInfo.height = height;
+ streamInfo.format = format;
+ streamInfo.dataSpace = dataSpace;
+ streamInfo.consumerUsage = consumerUsage;
+ return binder::Status::ok();
+ }
+ if (width != streamInfo.width) {
+ String8 msg = String8::format("Camera %s:Surface width doesn't match: %d vs %d",
+ mCameraIdStr.string(), width, streamInfo.width);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ if (height != streamInfo.height) {
+ String8 msg = String8::format("Camera %s:Surface height doesn't match: %d vs %d",
+ mCameraIdStr.string(), height, streamInfo.height);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ if (format != streamInfo.format) {
+ String8 msg = String8::format("Camera %s:Surface format doesn't match: %d vs %d",
+ mCameraIdStr.string(), format, streamInfo.format);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ if (dataSpace != streamInfo.dataSpace) {
+ String8 msg = String8::format("Camera %s:Surface dataSpace doesn't match: %d vs %d",
+ mCameraIdStr.string(), dataSpace, streamInfo.dataSpace);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ //At the native side, there isn't a way to check whether 2 surfaces come from the same
+ //surface class type. Use usage flag to approximate the comparison. Treat
+ //different preview surface usage flags as the same.
+ int32_t previewUsageMask =
+ GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_HW_COMPOSER;
+ if ((consumerUsage & ~previewUsageMask) != (streamInfo.consumerUsage & ~previewUsageMask)) {
+ String8 msg = String8::format(
+ "Camera %s:Surface usage flag doesn't match 0x%x vs 0x%x",
+ mCameraIdStr.string(), consumerUsage, streamInfo.consumerUsage);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ return binder::Status::ok();
+}
+
bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
/*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
@@ -1167,7 +1176,7 @@
return res;
}
-binder::Status CameraDeviceClient::setDeferredConfiguration(int32_t streamId,
+binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId,
const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
ATRACE_CALL();
@@ -1179,70 +1188,84 @@
const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
outputConfiguration.getGraphicBufferProducers();
- // Client code should guarantee that the surface is from SurfaceView or SurfaceTexture.
- // And it's also saved in the last entry of graphicBufferProducer list
if (bufferProducers.size() == 0) {
ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
}
- // Right now, only first surface in the OutputConfiguration is allowed to be
- // deferred. And all other surfaces are checked to be the same (not null) at
- // the Java side.
- sp<IGraphicBufferProducer> bufferProducer = bufferProducers[0];
- if (bufferProducer == nullptr) {
- ALOGE("%s: bufferProducer must not be null", __FUNCTION__);
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
- "Target Surface is invalid");
+ // streamId should be in mStreamMap if this stream already has a surface attached
+ // to it. Otherwise, it should be in mDeferredStreams.
+ bool streamIdConfigured = false;
+ ssize_t deferredStreamIndex = NAME_NOT_FOUND;
+ for (size_t i = 0; i < mStreamMap.size(); i++) {
+ if (mStreamMap.valueAt(i).streamId() == streamId) {
+ streamIdConfigured = true;
+ break;
+ }
}
-
- // Check if this stream id is one of the deferred only streams
- ssize_t index = NAME_NOT_FOUND;
- if (bufferProducers.size() == 1) {
- for (size_t i = 0; i < mDeferredStreams.size(); i++) {
- if (streamId == mDeferredStreams[i]) {
- index = i;
- break;
- }
+ for (size_t i = 0; i < mDeferredStreams.size(); i++) {
+ if (streamId == mDeferredStreams[i]) {
+ deferredStreamIndex = i;
+ break;
}
- if (index == NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: deferred surface is set to a unknown stream"
- "(ID %d)", mCameraIdStr.string(), streamId);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
- }
+ }
+ if (deferredStreamIndex == NAME_NOT_FOUND && !streamIdConfigured) {
+ String8 msg = String8::format("Camera %s: deferred surface is set to a unknown stream"
+ "(ID %d)", mCameraIdStr.string(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
}
if (!mDevice.get()) {
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
- // Don't create multiple streams for the same target surface
- {
+ std::vector<sp<Surface>> consumerSurfaces;
+ std::vector<size_t> consumerSurfaceIds;
+ size_t surfaceId = 0;
+ for (auto& bufferProducer : bufferProducers) {
+ // Don't create multiple streams for the same target surface
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
if (index != NAME_NOT_FOUND) {
- String8 msg = String8::format("Camera %s: Surface already has a stream created "
+ ALOGV("Camera %s: Surface already has a stream created "
" for it (ID %zd)", mCameraIdStr.string(), index);
- ALOGW("%s: %s", __FUNCTION__, msg.string());
- return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
+ surfaceId++;
+ continue;
}
+
+ sp<Surface> surface;
+ res = createSurfaceFromGbp(mStreamInfoMap[streamId], true /*isStreamInfoValid*/,
+ surface, bufferProducer);
+
+ if (!res.isOk())
+ return res;
+
+ consumerSurfaces.push_back(surface);
+ consumerSurfaceIds.push_back(surfaceId);
+ surfaceId++;
}
- status_t err;
-
- // Always set to async, as we know the deferred surface is for preview streaming.
- sp<Surface> consumerSurface = new Surface(bufferProducer, /*useAsync*/true);
+ if (consumerSurfaces.size() == 0) {
+ String8 msg = String8::format("Camera %s: New OutputConfiguration has the same surfaces"
+ " for stream (ID %d)", mCameraIdStr.string(), streamId);
+ ALOGW("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
// Finish the deferred stream configuration with the surface.
- err = mDevice->setConsumerSurface(streamId, consumerSurface);
+ status_t err;
+ err = mDevice->setConsumerSurfaces(streamId, consumerSurfaces);
if (err == OK) {
- sp<IBinder> binder = IInterface::asBinder(bufferProducer);
- ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %zu", __FUNCTION__,
- binder.get(), streamId, bufferProducers.size()-1);
- mStreamMap.add(binder, StreamSurfaceId(streamId, bufferProducers.size()-1));
- if (index != NAME_NOT_FOUND) {
- mDeferredStreams.removeItemsAt(index);
+ for (size_t i = 0; i < consumerSurfaces.size(); i++) {
+ sp<IBinder> binder = IInterface::asBinder(
+ consumerSurfaces[i]->getIGraphicBufferProducer());
+ ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %zu", __FUNCTION__,
+ binder.get(), streamId, consumerSurfaceIds[i]);
+ mStreamMap.add(binder, StreamSurfaceId(streamId, consumerSurfaceIds[i]));
+ }
+ if (deferredStreamIndex != NAME_NOT_FOUND) {
+ mDeferredStreams.removeItemsAt(deferredStreamIndex);
}
} else if (err == NO_INIT) {
res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 047ccf2..2f6d414 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -131,8 +131,8 @@
// Prepare stream by preallocating up to maxCount of its buffers
virtual binder::Status prepare2(int32_t maxCount, int32_t streamId);
- // Set the deferred surface for a stream.
- virtual binder::Status setDeferredConfiguration(int32_t streamId,
+ // Finalize the output configurations with surfaces not added before.
+ virtual binder::Status finalizeOutputConfigurations(int32_t streamId,
const hardware::camera2::params::OutputConfiguration &outputConfiguration);
/**
@@ -207,6 +207,23 @@
}; // class StreamSurfaceId
+ // OutputStreamInfo describes the property of a camera stream.
+ class OutputStreamInfo {
+ public:
+ int width;
+ int height;
+ int format;
+ android_dataspace dataSpace;
+ int32_t consumerUsage;
+ OutputStreamInfo() :
+ width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
+ consumerUsage(0) {}
+ OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
+ int32_t _consumerUsage) :
+ width(_width), height(_height), format(_format),
+ dataSpace(_dataSpace), consumerUsage(_consumerUsage) {}
+ };
+
private:
/** ICameraDeviceUser interface-related private members */
@@ -228,6 +245,7 @@
// Create an output stream with surface deferred for future.
binder::Status createDeferredSurfaceStreamLocked(
const hardware::camera2::params::OutputConfiguration &outputConfiguration,
+ bool isShared,
int* newStreamId = NULL);
// Set the stream transform flags to automatically rotate the camera stream for preview use
@@ -244,6 +262,11 @@
//check if format is not custom format
static bool isPublicFormat(int32_t format);
+ // Create a Surface from an IGraphicBufferProducer. Returns error if
+ // IGraphicBufferProducer's property doesn't match with streamInfo
+ binder::Status createSurfaceFromGbp(OutputStreamInfo& streamInfo, bool isStreamInfoValid,
+ sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp);
+
// IGraphicsBufferProducer binder -> Stream ID + Surface ID for output streams
KeyedVector<sp<IBinder>, StreamSurfaceId> mStreamMap;
@@ -267,8 +290,10 @@
// Surface is configured, the stream id will be moved to mStreamMap.
Vector<int32_t> mDeferredStreams;
+ // stream ID -> outputStreamInfo mapping
+ std::unordered_map<int32_t, OutputStreamInfo> mStreamInfoMap;
+
static const int32_t MAX_SURFACES_PER_STREAM = 2;
- static const int32_t MAX_DEFERRED_SURFACES = 1;
};
}; // namespace android
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index a873402..98a3fcc 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -121,7 +121,7 @@
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
- uint32_t consumerUsage = 0) = 0;
+ bool isShared = false, uint32_t consumerUsage = 0) = 0;
/**
* Create an output stream of the requested size, format, rotation and
@@ -134,7 +134,7 @@
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
- uint32_t consumerUsage = 0) = 0;
+ bool isShared = false, uint32_t consumerUsage = 0) = 0;
/**
* Create an input stream of width, height, and format.
@@ -341,7 +341,8 @@
/**
* Set the deferred consumer surface and finish the rest of the stream configuration.
*/
- virtual status_t setConsumerSurface(int streamId, sp<Surface> consumer) = 0;
+ virtual status_t setConsumerSurfaces(int streamId,
+ const std::vector<sp<Surface>>& consumers) = 0;
};
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 1675584..977e7a8 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1292,7 +1292,7 @@
status_t Camera3Device::createStream(sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
- int streamSetId, uint32_t consumerUsage) {
+ int streamSetId, bool isShared, uint32_t consumerUsage) {
ATRACE_CALL();
if (consumer == nullptr) {
@@ -1304,19 +1304,19 @@
consumers.push_back(consumer);
return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
- format, dataSpace, rotation, id, streamSetId, consumerUsage);
+ format, dataSpace, rotation, id, streamSetId, isShared, consumerUsage);
}
status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
- int streamSetId, uint32_t consumerUsage) {
+ int streamSetId, bool isShared, uint32_t consumerUsage) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
- " consumer usage 0x%x", mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
- consumerUsage);
+ " consumer usage 0x%x, isShared %d", mId.string(), mNextStreamId, width, height, format,
+ dataSpace, rotation, consumerUsage, isShared);
status_t res;
bool wasActive = false;
@@ -1370,8 +1370,6 @@
return BAD_VALUE;
}
- bool streamSharing = consumers.size() > 1 || (consumers.size() > 0 && hasDeferredConsumer);
-
// Use legacy dataspace values for older HALs
if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) {
dataSpace = mapToLegacyDataspace(dataSpace);
@@ -1403,14 +1401,14 @@
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
mTimestampOffset, streamSetId);
+ } else if (isShared) {
+ newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
+ width, height, format, consumerUsage, dataSpace, rotation,
+ mTimestampOffset, streamSetId);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, streamSetId);
- } else if (streamSharing) {
- newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
- hasDeferredConsumer, width, height, format, consumerUsage,
- dataSpace, rotation, mTimestampOffset, streamSetId);
} else {
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
@@ -2067,14 +2065,16 @@
}
}
-status_t Camera3Device::setConsumerSurface(int streamId, sp<Surface> consumer) {
+status_t Camera3Device::setConsumerSurfaces(int streamId,
+ const std::vector<sp<Surface>>& consumers) {
ATRACE_CALL();
- ALOGV("%s: Camera %s: set consumer surface for stream %d", __FUNCTION__, mId.string(), streamId);
+ ALOGV("%s: Camera %s: set consumer surface for stream %d",
+ __FUNCTION__, mId.string(), streamId);
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
- if (consumer == nullptr) {
- CLOGE("Null consumer is passed!");
+ if (consumers.size() == 0) {
+ CLOGE("No consumer is passed!");
return BAD_VALUE;
}
@@ -2084,7 +2084,7 @@
return idx;
}
sp<Camera3OutputStreamInterface> stream = mOutputStreams[idx];
- status_t res = stream->setConsumer(consumer);
+ status_t res = stream->setConsumers(consumers);
if (res != OK) {
CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
return res;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 9b869a9..91d682e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -109,18 +109,18 @@
// Actual stream creation/deletion is delayed until first request is submitted
// If adding streams while actively capturing, will pause device before adding
// stream, reconfiguring device, and unpausing. If the client create a stream
- // with nullptr consumer surface, the client must then call setConsumer()
+ // with nullptr consumer surface, the client must then call setConsumers()
// and finish the stream configuration before starting output streaming.
status_t createStream(sp<Surface> consumer,
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
- uint32_t consumerUsage = 0) override;
+ bool isShared = false, uint32_t consumerUsage = 0) override;
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
- uint32_t consumerUsage = 0) override;
+ bool isShared = false, uint32_t consumerUsage = 0) override;
status_t createInputStream(
uint32_t width, uint32_t height, int format,
@@ -183,10 +183,10 @@
void notifyStatus(bool idle); // updates from StatusTracker
/**
- * Set the deferred consumer surface to the output stream and finish the deferred
+ * Set the deferred consumer surfaces to the output stream and finish the deferred
* consumer configuration.
*/
- status_t setConsumerSurface(int streamId, sp<Surface> consumer) override;
+ status_t setConsumerSurfaces(int streamId, const std::vector<sp<Surface>>& consumers) override;
private:
static const size_t kDumpLockAttempts = 10;
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index 7f61c7a..1a730d6 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -115,9 +115,9 @@
return false;
}
-status_t Camera3DummyStream::setConsumer(sp<Surface> consumer) {
- ALOGE("%s: Stream %d: Dummy stream doesn't support set consumer surface %p!",
- __FUNCTION__, mId, consumer.get());
+status_t Camera3DummyStream::setConsumers(const std::vector<sp<Surface>>& /*consumers*/) {
+ ALOGE("%s: Stream %d: Dummy stream doesn't support set consumer surface!",
+ __FUNCTION__, mId);
return INVALID_OPERATION;
}
}; // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index 37efbbb..b6ec99c 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -70,9 +70,9 @@
virtual bool isConsumerConfigurationDeferred(size_t surface_id) const;
/**
- * Set the consumer surface to the output stream.
+ * Set the consumer surfaces to the output stream.
*/
- virtual status_t setConsumer(sp<Surface> consumer);
+ virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
protected:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 1e76a27..b5883e3 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -710,14 +710,19 @@
Mutex::Autolock l(mLock);
if (surface_id != 0) {
- ALOGE("%s: surface_id for Camera3OutputStream should be 0!", __FUNCTION__);
+ ALOGE("%s: surface_id %zu for Camera3OutputStream should be 0!", __FUNCTION__, surface_id);
}
return mConsumer == nullptr;
}
-status_t Camera3OutputStream::setConsumer(sp<Surface> consumer) {
- if (consumer == nullptr) {
- ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
+status_t Camera3OutputStream::setConsumers(const std::vector<sp<Surface>>& consumers) {
+ if (consumers.size() != 1) {
+ ALOGE("%s: it's illegal to set %zu consumer surfaces!",
+ __FUNCTION__, consumers.size());
+ return INVALID_OPERATION;
+ }
+ if (consumers[0] == nullptr) {
+ ALOGE("%s: it's illegal to set null consumer surface!", __FUNCTION__);
return INVALID_OPERATION;
}
@@ -726,7 +731,7 @@
return INVALID_OPERATION;
}
- mConsumer = consumer;
+ mConsumer = consumers[0];
return OK;
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 26ea63f..080c721 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -138,9 +138,9 @@
virtual bool isConsumerConfigurationDeferred(size_t surface_id) const;
/**
- * Set the consumer surface to the output stream.
+ * Set the consumer surfaces to the output stream.
*/
- virtual status_t setConsumer(sp<Surface> consumer);
+ virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
class BufferReleasedListener : public BnProducerListener {
public:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 6a911c6..11868e7 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -46,9 +46,9 @@
virtual bool isConsumerConfigurationDeferred(size_t surface_id = 0) const = 0;
/**
- * Set the consumer surface to the output stream.
+ * Set the consumer surfaces to the output stream.
*/
- virtual status_t setConsumer(sp<Surface> consumer) = 0;
+ virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers) = 0;
/**
* Detach an unused buffer from the stream.
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index b419e06..0d6a96c 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -22,7 +22,6 @@
Camera3SharedOutputStream::Camera3SharedOutputStream(int id,
const std::vector<sp<Surface>>& surfaces,
- bool hasDeferredSurface,
uint32_t width, uint32_t height, int format,
uint32_t consumerUsage, android_dataspace dataSpace,
camera3_stream_rotation_t rotation,
@@ -30,8 +29,7 @@
Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
format, dataSpace, rotation, consumerUsage,
timestampOffset, setId),
- mSurfaces(surfaces),
- mDeferred(hasDeferredSurface) {
+ mSurfaces(surfaces) {
}
Camera3SharedOutputStream::~Camera3SharedOutputStream() {
@@ -70,23 +68,35 @@
bool Camera3SharedOutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
Mutex::Autolock l(mLock);
- return (mDeferred && surface_id >= mSurfaces.size());
+ return (surface_id >= mSurfaces.size());
}
-status_t Camera3SharedOutputStream::setConsumer(sp<Surface> surface) {
- if (surface == nullptr) {
- ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
+status_t Camera3SharedOutputStream::setConsumers(const std::vector<sp<Surface>>& surfaces) {
+ if (surfaces.size() == 0) {
+ ALOGE("%s: it's illegal to set zero consumer surfaces!", __FUNCTION__);
return INVALID_OPERATION;
}
- if (!mDeferred) {
- ALOGE("%s: Current stream isn't deferred!", __FUNCTION__);
- return INVALID_OPERATION;
+ status_t ret = OK;
+ for (auto& surface : surfaces) {
+ if (surface == nullptr) {
+ ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ mSurfaces.push_back(surface);
+
+ // Only call addOutput if the splitter has been connected.
+ if (mStreamSplitter != nullptr) {
+ ret = mStreamSplitter->addOutput(surface, camera3_stream::max_buffers);
+ if (ret != OK) {
+ ALOGE("%s: addOutput failed with error code %d", __FUNCTION__, ret);
+ return ret;
+
+ }
+ }
}
-
- mSurfaces.push_back(surface);
-
- return mStreamSplitter->addOutput(surface, camera3_stream::max_buffers);
+ return ret;
}
status_t Camera3SharedOutputStream::configureQueueLocked() {
@@ -124,7 +134,7 @@
status_t Camera3SharedOutputStream::getEndpointUsage(uint32_t *usage) const {
- status_t res;
+ status_t res = OK;
uint32_t u = 0;
if (mConsumer == nullptr) {
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 1b37d7c..cc96076 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -33,7 +33,7 @@
* sharing between multiple streams.
*/
Camera3SharedOutputStream(int id, const std::vector<sp<Surface>>& surfaces,
- bool hasDeferredSurface, uint32_t width, uint32_t height, int format,
+ uint32_t width, uint32_t height, int format,
uint32_t consumerUsage, android_dataspace dataSpace,
camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
int setId = CAMERA3_STREAM_SET_ID_INVALID);
@@ -45,7 +45,7 @@
virtual bool isConsumerConfigurationDeferred(size_t surface_id) const;
- virtual status_t setConsumer(sp<Surface> consumer);
+ virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
private:
// Surfaces passed in constructor from app
@@ -68,8 +68,6 @@
virtual status_t getEndpointUsage(uint32_t *usage) const;
- bool mDeferred;
-
}; // class Camera3SharedOutputStream
} // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index b935141..07f9491 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -55,14 +55,15 @@
// Add output surfaces. This has to be before creating internal buffer queue
// in order to get max consumer side buffers.
for (size_t i = 0; i < surfaces.size(); i++) {
- if (surfaces[i] != nullptr) {
- res = addOutputLocked(surfaces[i], hal_max_buffers,
- OutputType::NonDeferred);
- if (res != OK) {
- ALOGE("%s: Failed to add output surface: %s(%d)",
- __FUNCTION__, strerror(-res), res);
- return res;
- }
+ if (surfaces[i] == nullptr) {
+ ALOGE("%s: Fatal: surface is NULL", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ res = addOutputLocked(surfaces[i], hal_max_buffers, OutputType::NonDeferred);
+ if (res != OK) {
+ ALOGE("%s: Failed to add output surface: %s(%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
}
}
@@ -110,7 +111,7 @@
}
status_t Camera3StreamSplitter::addOutput(
- sp<Surface>& outputQueue, size_t hal_max_buffers) {
+ const sp<Surface>& outputQueue, size_t hal_max_buffers) {
Mutex::Autolock lock(mMutex);
return addOutputLocked(outputQueue, hal_max_buffers, OutputType::Deferred);
}
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 5a25712..32ae073 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -61,7 +61,7 @@
// outputQueue has not been added to the splitter. BAD_VALUE is returned if
// outputQueue is NULL. See IGraphicBufferProducer::connect for explanations
// of other error codes.
- status_t addOutput(sp<Surface>& outputQueue, size_t hal_max_buffers);
+ status_t addOutput(const sp<Surface>& outputQueue, size_t hal_max_buffers);
// Request surfaces for a particular frame number. The requested surfaces
// are stored in a FIFO queue. And when the buffer becomes available from the
diff --git a/services/mediaanalytics/Android.mk b/services/mediaanalytics/Android.mk
index 76a5c1c..ef49df4 100644
--- a/services/mediaanalytics/Android.mk
+++ b/services/mediaanalytics/Android.mk
@@ -5,28 +5,43 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- main_mediaanalytics.cpp
+ main_mediametrics.cpp \
+ MediaAnalyticsService.cpp
LOCAL_SHARED_LIBRARIES := \
- libcutils \
- liblog \
- libmedia \
- libmediaanalyticsservice \
- libutils \
- libbinder \
- libicuuc
+ libcutils \
+ liblog \
+ libmedia \
+ libutils \
+ libbinder \
+ libdl \
+ libgui \
+ libmedia \
+ libmediautils \
+ libstagefright_foundation \
+ libutils
LOCAL_STATIC_LIBRARIES := \
- libicuandroid_utils \
libregistermsext
-LOCAL_C_INCLUDES := \
- frameworks/av/media/libmediaanalyticsservice
+LOCAL_C_INCLUDES := \
+ $(TOP)/frameworks/av/media/libstagefright/include \
+ $(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)/frameworks/native/include/media/hardware \
+ $(TOP)/external/tremolo/Tremolo \
+ libcore/include
-LOCAL_MODULE:= mediaanalytics
-LOCAL_INIT_RC := mediaanalytics.rc
+LOCAL_MODULE:= mediametrics
-LOCAL_CFLAGS := -Werror -Wall
+LOCAL_INIT_RC := mediametrics.rc
+
+LOCAL_CFLAGS := -Werror -Wall -Wno-error=deprecated-declarations
+LOCAL_CLANG := true
include $(BUILD_EXECUTABLE)
diff --git a/media/libmediaanalyticsservice/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
similarity index 87%
rename from media/libmediaanalyticsservice/MediaAnalyticsService.cpp
rename to services/mediaanalytics/MediaAnalyticsService.cpp
index 1d0246d..eacafdd 100644
--- a/media/libmediaanalyticsservice/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -85,7 +85,7 @@
void MediaAnalyticsService::instantiate() {
defaultServiceManager()->addService(
- String16("media.analytics"), new MediaAnalyticsService());
+ String16("media.metrics"), new MediaAnalyticsService());
}
// XXX: add dynamic controls for mMaxRecords
@@ -125,18 +125,46 @@
MediaAnalyticsItem::SessionID_t id = MediaAnalyticsItem::SessionIDInvalid;
- // we control these, not using whatever the user might have sent
+ // we control these, generally not trusting user input
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
item->setTimestamp(now);
int pid = IPCThreadState::self()->getCallingPid();
- item->setPid(pid);
int uid = IPCThreadState::self()->getCallingUid();
- item->setUid(uid);
+
+ int uid_given = item->getUid();
+ int pid_given = item->getPid();
+
+ // although we do make exceptions for particular client uids
+ // that we know we trust.
+ //
+ bool isTrusted = false;
+
+ switch (uid) {
+ case AID_MEDIA:
+ case AID_MEDIA_CODEC:
+ case AID_MEDIA_EX:
+ case AID_MEDIA_DRM:
+ // trusted source, only override default values
+ isTrusted = true;
+ if (uid_given == (-1)) {
+ item->setUid(uid);
+ }
+ if (pid_given == (-1)) {
+ item->setPid(pid);
+ }
+ break;
+ default:
+ isTrusted = false;
+ item->setPid(pid);
+ item->setUid(uid);
+ break;
+ }
+
mItemsSubmitted++;
// validate the record; we discard if we don't like it
- if (contentValid(item) == false) {
+ if (contentValid(item, isTrusted) == false) {
delete item;
return MediaAnalyticsItem::SessionIDInvalid;
}
@@ -275,14 +303,14 @@
Mutex::Autolock _l(mLock);
- snprintf(buffer, SIZE, "Dump of the mediaanalytics process:\n");
+ snprintf(buffer, SIZE, "Dump of the mediametrics process:\n");
result.append(buffer);
int enabled = MediaAnalyticsItem::isEnabled();
if (enabled) {
- snprintf(buffer, SIZE, "Analytics gathering: enabled\n");
+ snprintf(buffer, SIZE, "Metrics gathering: enabled\n");
} else {
- snprintf(buffer, SIZE, "Analytics gathering: DISABLED via property\n");
+ snprintf(buffer, SIZE, "Metrics gathering: DISABLED via property\n");
}
result.append(buffer);
@@ -300,11 +328,11 @@
}
// show the recently recorded records
- snprintf(buffer, sizeof(buffer), "\nFinalized Analytics (oldest first):\n");
+ snprintf(buffer, sizeof(buffer), "\nFinalized Metrics (oldest first):\n");
result.append(buffer);
result.append(this->dumpQueue(mFinalized, ts_since));
- snprintf(buffer, sizeof(buffer), "\nIn-Progress Analytics (newest first):\n");
+ snprintf(buffer, sizeof(buffer), "\nIn-Progress Metrics (newest first):\n");
result.append(buffer);
result.append(this->dumpQueue(mOpen, ts_since));
@@ -402,9 +430,7 @@
oitem->getTimestamp());
}
l->erase(l->begin());
- ALOGD("drop record at %s:%d", __FILE__, __LINE__);
delete oitem;
- ALOGD("[done] drop record at %s:%d", __FILE__, __LINE__);
mItemsDiscarded++;
}
}
@@ -510,10 +536,34 @@
}
}
-// are the contents good
-bool MediaAnalyticsService::contentValid(MediaAnalyticsItem *) {
+static AString allowedKeys[] =
+{
+ "codec",
+ "extractor"
+};
- // certain keys require certain uids
+static const int nAllowedKeys = sizeof(allowedKeys) / sizeof(allowedKeys[0]);
+
+// are the contents good
+bool MediaAnalyticsService::contentValid(MediaAnalyticsItem *item, bool isTrusted) {
+
+ // untrusted uids can only send us a limited set of keys
+ if (isTrusted == false) {
+ // restrict to a specific set of keys
+ AString key = item->getKey();
+
+ size_t i;
+ for(i = 0; i < nAllowedKeys; i++) {
+ if (key == allowedKeys[i]) {
+ break;
+ }
+ }
+ if (i == nAllowedKeys) {
+ ALOGD("Ignoring (key): %s", item->toString().c_str());
+ return false;
+ }
+ }
+
// internal consistency
return true;
diff --git a/media/libmediaanalyticsservice/MediaAnalyticsService.h b/services/mediaanalytics/MediaAnalyticsService.h
similarity index 97%
rename from media/libmediaanalyticsservice/MediaAnalyticsService.h
rename to services/mediaanalytics/MediaAnalyticsService.h
index 3e2298f..d2b0f09 100644
--- a/media/libmediaanalyticsservice/MediaAnalyticsService.h
+++ b/services/mediaanalytics/MediaAnalyticsService.h
@@ -69,7 +69,7 @@
int32_t mMaxRecords;
// input validation after arrival from client
- bool contentValid(MediaAnalyticsItem *);
+ bool contentValid(MediaAnalyticsItem *item, bool isTrusted);
bool rateLimited(MediaAnalyticsItem *);
// the ones that are still open
diff --git a/services/mediaanalytics/main_mediaanalytics.cpp b/services/mediaanalytics/main_mediametrics.cpp
similarity index 87%
rename from services/mediaanalytics/main_mediaanalytics.cpp
rename to services/mediaanalytics/main_mediametrics.cpp
index 672d13d..8020a03 100644
--- a/services/mediaanalytics/main_mediaanalytics.cpp
+++ b/services/mediaanalytics/main_mediametrics.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "mediaanalytics"
+#define LOG_TAG "mediametrics"
//#define LOG_NDEBUG 0
#include <binder/IPCThreadState.h>
@@ -24,7 +24,6 @@
//#include "RegisterExtensions.h"
// from LOCAL_C_INCLUDES
-#include "IcuUtils.h"
#include "MediaAnalyticsService.h"
using namespace android;
@@ -34,16 +33,16 @@
signal(SIGPIPE, SIG_IGN);
// to match the service name
- // we're replacing "/system/bin/mediaanalytics" with "media.analytics"
+ // we're replacing "/system/bin/mediametrics" with "media.metrics"
// we add a ".", but discard the path components: we finish with a shorter string
- strcpy(argv[0], "media.analytics");
+ strcpy(argv[0], "media.metrics");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
- InitializeIcuOrDie();
MediaAnalyticsService::instantiate();
+
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
diff --git a/services/mediaanalytics/mediaanalytics.rc b/services/mediaanalytics/mediametrics.rc
similarity index 69%
rename from services/mediaanalytics/mediaanalytics.rc
rename to services/mediaanalytics/mediametrics.rc
index 0af69f5..3829f8c 100644
--- a/services/mediaanalytics/mediaanalytics.rc
+++ b/services/mediaanalytics/mediametrics.rc
@@ -1,4 +1,4 @@
-service mediaanalytics /system/bin/mediaanalytics
+service mediametrics /system/bin/mediametrics
class main
user media
ioprio rt 4