MediaMetrics: Make submit one-way
Remove the unused session id to improve speed and clarity.
Test: dumpsys media.metrics sanity, mediametrics_tests
Change-Id: Ide5e9218811e110997fed19f43eb6a5fdc5812ec
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 66610b3..e2ea83a 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -59,7 +59,6 @@
IDrmEngine& engine = mPlugInManager.getPlugIn(plugInId);
std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("drmmanager"));
- item->generateSessionID();
item->setUid(IPCThreadState::self()->getCallingUid());
item->setCString("function_name", func);
item->setCString("plugin_id", plugInId.getPathLeaf().getBasePath().c_str());
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 37609eb..4529fe5 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -1574,7 +1574,6 @@
void DrmHal::reportFrameworkMetrics() const
{
std::unique_ptr<MediaAnalyticsItem> item(MediaAnalyticsItem::create("mediadrm"));
- item->generateSessionID();
item->setPkgName(mMetrics.GetAppPackageName().c_str());
String8 vendor;
String8 description;
diff --git a/drm/libmediadrm/PluginMetricsReporting.cpp b/drm/libmediadrm/PluginMetricsReporting.cpp
index 8cd6f96..098f07b 100644
--- a/drm/libmediadrm/PluginMetricsReporting.cpp
+++ b/drm/libmediadrm/PluginMetricsReporting.cpp
@@ -35,8 +35,6 @@
const String8& name,
const String8& appPackageName) {
std::unique_ptr<MediaAnalyticsItem> analyticsItem(MediaAnalyticsItem::create(name.c_str()));
- analyticsItem->generateSessionID();
-
std::string app_package_name(appPackageName.c_str(), appPackageName.size());
analyticsItem->setPkgName(app_package_name);
if (metrics.size() > 0) {
@@ -44,7 +42,7 @@
}
if (!analyticsItem->selfrecord()) {
- ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem->getSessionID());
+ ALOGE("%s: selfrecord() returned false", __func__);
}
return OK;
diff --git a/media/libmediametrics/IMediaAnalyticsService.cpp b/media/libmediametrics/IMediaAnalyticsService.cpp
index 9114927..1ab6653 100644
--- a/media/libmediametrics/IMediaAnalyticsService.cpp
+++ b/media/libmediametrics/IMediaAnalyticsService.cpp
@@ -32,15 +32,10 @@
#include <media/MediaAnalyticsItem.h>
#include <media/IMediaAnalyticsService.h>
-#define DEBUGGING 0
-#define DEBUGGING_FLOW 0
-#define DEBUGGING_RETURNS 0
-
namespace android {
enum {
- GENERATE_UNIQUE_SESSIONID = IBinder::FIRST_CALL_TRANSACTION,
- SUBMIT_ITEM,
+ SUBMIT_ITEM_ONEWAY = IBinder::FIRST_CALL_TRANSACTION,
};
class BpMediaAnalyticsService: public BpInterface<IMediaAnalyticsService>
@@ -51,61 +46,23 @@
{
}
- virtual MediaAnalyticsItem::SessionID_t generateUniqueSessionID() {
- Parcel data, reply;
- status_t err;
- MediaAnalyticsItem::SessionID_t sessionid =
- MediaAnalyticsItem::SessionIDInvalid;
-
- data.writeInterfaceToken(IMediaAnalyticsService::getInterfaceDescriptor());
- err = remote()->transact(GENERATE_UNIQUE_SESSIONID, data, &reply);
- if (err != NO_ERROR) {
- ALOGW("bad response from service for generateSessionId, err=%d", err);
- return MediaAnalyticsItem::SessionIDInvalid;
- }
- sessionid = reply.readInt64();
- if (DEBUGGING_RETURNS) {
- ALOGD("the caller gets a sessionid of %" PRId64 " back", sessionid);
- }
- return sessionid;
- }
-
- virtual MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew)
+ status_t submit(MediaAnalyticsItem *item) override
{
- // have this record submit itself
- // this will be a binder call with appropriate timing
- // return value is the uuid that the system generated for it.
- // the return value 0 and -1 are reserved.
- // -1 to indicate that there was a problem recording...
-
- Parcel data, reply;
- status_t err;
-
- if (item == NULL) {
- return MediaAnalyticsItem::SessionIDInvalid;
+ if (item == nullptr) {
+ return BAD_VALUE;
}
+ ALOGV("%s: (ONEWAY) item=%s", __func__, item->toString().c_str());
+ Parcel data;
data.writeInterfaceToken(IMediaAnalyticsService::getInterfaceDescriptor());
- if(DEBUGGING_FLOW) {
- ALOGD("client offers record: %s", item->toString().c_str());
- }
- data.writeBool(forcenew);
item->writeToParcel(&data);
- err = remote()->transact(SUBMIT_ITEM, data, &reply);
- if (err != NO_ERROR) {
- ALOGW("bad response from service for submit, err=%d", err);
- return MediaAnalyticsItem::SessionIDInvalid;
- }
-
- // get an answer out of 'reply'
- int64_t sessionid = reply.readInt64();
- if (DEBUGGING_RETURNS) {
- ALOGD("the caller gets sessionid=%" PRId64 "", sessionid);
- }
- return sessionid;
+ status_t err = remote()->transact(
+ SUBMIT_ITEM_ONEWAY, data, nullptr /* reply */, IBinder::FLAG_ONEWAY);
+ ALOGW_IF(err != NO_ERROR, "%s: bad response from service for submit, err=%d",
+ __func__, err);
+ return err;
}
-
};
IMPLEMENT_META_INTERFACE(MediaAnalyticsService, "android.media.IMediaAnalyticsService");
@@ -115,49 +72,23 @@
status_t BnMediaAnalyticsService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
-
-
- // get calling pid/tid
- IPCThreadState *ipc = IPCThreadState::self();
- int clientPid = ipc->getCallingPid();
- // permission checking
-
- if(DEBUGGING_FLOW) {
- ALOGD("running in service, code %d, pid %d; called from pid %d",
- code, getpid(), clientPid);
- }
+ const int clientPid = IPCThreadState::self()->getCallingPid();
switch (code) {
+ case SUBMIT_ITEM_ONEWAY: {
+ CHECK_INTERFACE(IMediaAnalyticsService, data, reply);
- case GENERATE_UNIQUE_SESSIONID: {
- CHECK_INTERFACE(IMediaAnalyticsService, data, reply);
+ MediaAnalyticsItem * const item = MediaAnalyticsItem::create();
+ if (item->readFromParcel(data) < 0) {
+ return BAD_VALUE;
+ }
+ item->setPid(clientPid);
+ const status_t status __unused = submitInternal(item, true /* release */);
+ return NO_ERROR;
+ } break;
- MediaAnalyticsItem::SessionID_t sessionid = generateUniqueSessionID();
- reply->writeInt64(sessionid);
-
- return NO_ERROR;
- } break;
-
- case SUBMIT_ITEM: {
- CHECK_INTERFACE(IMediaAnalyticsService, data, reply);
-
- bool forcenew;
- MediaAnalyticsItem *item = MediaAnalyticsItem::create();
-
- data.readBool(&forcenew);
- item->readFromParcel(data);
-
- item->setPid(clientPid);
-
- // submit() takes over ownership of 'item'
- MediaAnalyticsItem::SessionID_t sessionid = submit(item, forcenew);
- reply->writeInt64(sessionid);
-
- return NO_ERROR;
- } break;
-
- default:
- return BBinder::onTransact(code, data, reply, flags);
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
}
}
diff --git a/media/libmediametrics/MediaAnalyticsItem.cpp b/media/libmediametrics/MediaAnalyticsItem.cpp
index c8713bf..20b10db 100644
--- a/media/libmediametrics/MediaAnalyticsItem.cpp
+++ b/media/libmediametrics/MediaAnalyticsItem.cpp
@@ -22,10 +22,11 @@
#include <string.h>
#include <sys/types.h>
+#include <mutex>
+
#include <binder/Parcel.h>
#include <utils/Errors.h>
#include <utils/Log.h>
-#include <utils/Mutex.h>
#include <utils/SortedVector.h>
#include <utils/threads.h>
@@ -79,9 +80,7 @@
: mPid(-1),
mUid(-1),
mPkgVersionCode(0),
- mSessionID(MediaAnalyticsItem::SessionIDNone),
mTimestamp(0),
- mFinalized(1),
mPropCount(0), mPropSize(0), mProps(NULL)
{
mKey = MediaAnalyticsItem::kKeyNone;
@@ -91,9 +90,7 @@
: mPid(-1),
mUid(-1),
mPkgVersionCode(0),
- mSessionID(MediaAnalyticsItem::SessionIDNone),
mTimestamp(0),
- mFinalized(1),
mPropCount(0), mPropSize(0), mProps(NULL)
{
if (DEBUG_ALLOCATIONS) {
@@ -114,9 +111,6 @@
// 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 < mPropCount; i++ ) {
@@ -143,9 +137,7 @@
dst->mUid = this->mUid;
dst->mPkgName = this->mPkgName;
dst->mPkgVersionCode = this->mPkgVersionCode;
- dst->mSessionID = this->mSessionID;
dst->mTimestamp = this->mTimestamp;
- dst->mFinalized = this->mFinalized;
// properties aka attributes
dst->growProps(this->mPropCount);
@@ -158,35 +150,6 @@
return dst;
}
-MediaAnalyticsItem &MediaAnalyticsItem::setSessionID(MediaAnalyticsItem::SessionID_t id) {
- mSessionID = id;
- return *this;
-}
-
-MediaAnalyticsItem::SessionID_t MediaAnalyticsItem::getSessionID() const {
- return mSessionID;
-}
-
-MediaAnalyticsItem::SessionID_t MediaAnalyticsItem::generateSessionID() {
-
- if (mSessionID == SessionIDNone) {
- // get one from the server
- MediaAnalyticsItem::SessionID_t newid = SessionIDNone;
- sp<IMediaAnalyticsService> svc = getInstance();
- if (svc != NULL) {
- newid = svc->generateUniqueSessionID();
- }
- mSessionID = newid;
- }
-
- return mSessionID;
-}
-
-MediaAnalyticsItem &MediaAnalyticsItem::clearSessionID() {
- mSessionID = MediaAnalyticsItem::SessionIDNone;
- return *this;
-}
-
MediaAnalyticsItem &MediaAnalyticsItem::setTimestamp(nsecs_t ts) {
mTimestamp = ts;
return *this;
@@ -679,11 +642,8 @@
mUid = data.readInt32();
mPkgName = data.readCString();
mPkgVersionCode = data.readInt64();
- mSessionID = data.readInt64();
// We no longer pay attention to user setting of finalized, BUT it's
// still part of the wire packet -- so read & discard.
- mFinalized = data.readInt32();
- mFinalized = 1;
mTimestamp = data.readInt64();
int count = data.readInt32();
@@ -744,8 +704,6 @@
data->writeInt32(mUid);
data->writeCString(mPkgName.c_str());
data->writeInt64(mPkgVersionCode);
- data->writeInt64(mSessionID);
- data->writeInt32(mFinalized);
data->writeInt64(mTimestamp);
// set of items
@@ -821,9 +779,7 @@
// same order as we spill into the parcel, although not required
// key+session are our primary matching criteria
result.append(mKey.c_str());
- result.append(":");
- snprintf(buffer, sizeof(buffer), "%" PRId64 ":", mSessionID);
- result.append(buffer);
+ result.append(":0:"); // sessionID
snprintf(buffer, sizeof(buffer), "%d:", mUid);
result.append(buffer);
@@ -842,7 +798,7 @@
}
result.append(buffer);
- snprintf(buffer, sizeof(buffer), "%d:", mFinalized);
+ snprintf(buffer, sizeof(buffer), "%d:", 0 /* finalized */); // TODO: remove this.
result.append(buffer);
snprintf(buffer, sizeof(buffer), "%" PRId64 ":", mTimestamp);
result.append(buffer);
@@ -899,23 +855,12 @@
// for the lazy, we offer methods that finds the service and
// calls the appropriate daemon
bool MediaAnalyticsItem::selfrecord() {
- return selfrecord(false);
-}
-
-bool MediaAnalyticsItem::selfrecord(bool forcenew) {
-
- if (DEBUG_API) {
- std::string p = this->toString();
- ALOGD("selfrecord of: %s [forcenew=%d]", p.c_str(), forcenew);
- }
-
+ ALOGD_IF(DEBUG_API, "%s: delivering %s", __func__, this->toString().c_str());
sp<IMediaAnalyticsService> svc = getInstance();
-
if (svc != NULL) {
- MediaAnalyticsItem::SessionID_t newid = svc->submit(this, forcenew);
- if (newid == SessionIDInvalid) {
- std::string p = this->toString();
- ALOGW("Failed to record: %s [forcenew=%d]", p.c_str(), forcenew);
+ status_t status = svc->submit(this);
+ if (status != NO_ERROR) {
+ ALOGW("%s: failed to record: %s", __func__, this->toString().c_str());
return false;
}
return true;
@@ -924,29 +869,33 @@
}
}
-// get a connection we can reuse for most of our lifetime
-// static
-sp<IMediaAnalyticsService> MediaAnalyticsItem::sAnalyticsService;
-static Mutex sInitMutex;
-static int remainingBindAttempts = SVC_TRIES;
//static
bool MediaAnalyticsItem::isEnabled() {
- int enabled = property_get_int32(MediaAnalyticsItem::EnabledProperty, -1);
+ // completely skip logging from certain UIDs. We do this here
+ // to avoid the multi-second timeouts while we learn that
+ // sepolicy will not let us find the service.
+ // We do this only for a select set of UIDs
+ // The sepolicy protection is still in place, we just want a faster
+ // response from this specific, small set of uids.
+ // This is checked only once in the lifetime of the process.
+ const uid_t uid = getuid();
+ switch (uid) {
+ case AID_RADIO: // telephony subsystem, RIL
+ return false;
+ }
+
+ int enabled = property_get_int32(MediaAnalyticsItem::EnabledProperty, -1);
if (enabled == -1) {
enabled = property_get_int32(MediaAnalyticsItem::EnabledPropertyPersist, -1);
}
if (enabled == -1) {
enabled = MediaAnalyticsItem::EnabledProperty_default;
}
- if (enabled <= 0) {
- return false;
- }
- return true;
+ return enabled > 0;
}
-
// monitor health of our connection to the metrics service
class MediaMetricsDeathNotifier : public IBinder::DeathRecipient {
virtual void binderDied(const wp<IBinder> &) {
@@ -955,83 +904,56 @@
}
};
-static sp<MediaMetricsDeathNotifier> sNotifier = NULL;
+static sp<MediaMetricsDeathNotifier> sNotifier;
+// static
+sp<IMediaAnalyticsService> MediaAnalyticsItem::sAnalyticsService;
+static std::mutex sServiceMutex;
+static int sRemainingBindAttempts = SVC_TRIES;
// static
void MediaAnalyticsItem::dropInstance() {
- Mutex::Autolock _l(sInitMutex);
- remainingBindAttempts = SVC_TRIES;
- sAnalyticsService = NULL;
+ std::lock_guard _l(sServiceMutex);
+ sRemainingBindAttempts = SVC_TRIES;
+ sAnalyticsService = nullptr;
}
//static
sp<IMediaAnalyticsService> MediaAnalyticsItem::getInstance() {
-
static const char *servicename = "media.metrics";
- int enabled = isEnabled();
+ static const bool enabled = isEnabled(); // singleton initialized
if (enabled == false) {
- if (DEBUG_SERVICEACCESS) {
- ALOGD("disabled");
- }
- return NULL;
+ ALOGD_IF(DEBUG_SERVICEACCESS, "disabled");
+ return nullptr;
}
-
- // completely skip logging from certain UIDs. We do this here
- // to avoid the multi-second timeouts while we learn that
- // sepolicy will not let us find the service.
- // We do this only for a select set of UIDs
- // The sepolicy protection is still in place, we just want a faster
- // response from this specific, small set of uids.
- {
- uid_t uid = getuid();
- switch (uid) {
- case AID_RADIO: // telephony subsystem, RIL
- return NULL;
- break;
- default:
- // let sepolicy deny access if appropriate
- break;
- }
- }
-
- {
- Mutex::Autolock _l(sInitMutex);
+ std::lock_guard _l(sServiceMutex);
+ // think of remainingBindAttempts as telling us whether service == nullptr because
+ // (1) we haven't tried to initialize it yet
+ // (2) we've tried to initialize it, but failed.
+ if (sAnalyticsService == nullptr && sRemainingBindAttempts > 0) {
const char *badness = "";
-
- // think of remainingBindAttempts as telling us whether service==NULL because
- // (1) we haven't tried to initialize it yet
- // (2) we've tried to initialize it, but failed.
- if (sAnalyticsService == NULL && remainingBindAttempts > 0) {
- sp<IServiceManager> sm = defaultServiceManager();
- if (sm != NULL) {
- sp<IBinder> binder = sm->getService(String16(servicename));
- if (binder != NULL) {
- sAnalyticsService = interface_cast<IMediaAnalyticsService>(binder);
- if (sNotifier != NULL) {
- sNotifier = NULL;
- }
- sNotifier = new MediaMetricsDeathNotifier();
- binder->linkToDeath(sNotifier);
- } else {
- badness = "did not find service";
- }
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (sm != nullptr) {
+ sp<IBinder> binder = sm->getService(String16(servicename));
+ if (binder != nullptr) {
+ sAnalyticsService = interface_cast<IMediaAnalyticsService>(binder);
+ sNotifier = new MediaMetricsDeathNotifier();
+ binder->linkToDeath(sNotifier);
} else {
- badness = "No Service Manager access";
+ badness = "did not find service";
}
-
- if (sAnalyticsService == NULL) {
- if (remainingBindAttempts > 0) {
- remainingBindAttempts--;
- }
- if (DEBUG_SERVICEACCESS) {
- ALOGD("Unable to bind to service %s: %s", servicename, badness);
- }
- }
+ } else {
+ badness = "No Service Manager access";
}
-
- return sAnalyticsService;
+ if (sAnalyticsService == nullptr) {
+ if (sRemainingBindAttempts > 0) {
+ sRemainingBindAttempts--;
+ }
+ ALOGD_IF(DEBUG_SERVICEACCESS, "%s: unable to bind to service %s: %s",
+ __func__, servicename, badness);
+ }
}
+ return sAnalyticsService;
}
// merge the info from 'incoming' into this record.
@@ -1042,8 +964,6 @@
// 'this' should never be missing both of them...
if (mKey.empty()) {
mKey = incoming->mKey;
- } else if (mSessionID == 0) {
- mSessionID = incoming->mSessionID;
}
// for each attribute from 'incoming', resolve appropriately
diff --git a/media/libmediametrics/include/IMediaAnalyticsService.h b/media/libmediametrics/include/IMediaAnalyticsService.h
index f2e7710..1453b5f 100644
--- a/media/libmediametrics/include/IMediaAnalyticsService.h
+++ b/media/libmediametrics/include/IMediaAnalyticsService.h
@@ -40,24 +40,15 @@
DECLARE_META_INTERFACE(MediaAnalyticsService);
/**
- * Returns a unique sessionID to use across multiple requests;
- * 'unique' is within this device, since last reboot.
- */
- virtual MediaAnalyticsItem::SessionID_t generateUniqueSessionID() = 0;
-
- /**
* Submits the indicated record to the mediaanalytics service, where
* it will be merged (if appropriate) with incomplete records that
* share the same key and sessionID.
*
* \param item the item to submit.
- * \param forcenew marks any matching incomplete record as complete before
- * inserting this new record.
- *
- * \return the sessionID associated with that item or
- * MediaAnalyticsItem::SessionIDInvalid on failure.
+ * \return status which is negative if an error is detected (some errors
+ may be silent and return 0 - success).
*/
- virtual MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) = 0;
+ virtual status_t submit(MediaAnalyticsItem *item) = 0;
};
// ----------------------------------------------------------------------------
@@ -69,6 +60,11 @@
const Parcel& data,
Parcel* reply,
uint32_t flags = 0) override;
+
+protected:
+ // Internal call where release is true if the service is to delete the item.
+ virtual status_t submitInternal(
+ MediaAnalyticsItem *item, bool release) = 0;
};
}; // namespace android
diff --git a/media/libmediametrics/include/MediaAnalyticsItem.h b/media/libmediametrics/include/MediaAnalyticsItem.h
index 3024c84..b37eff43 100644
--- a/media/libmediametrics/include/MediaAnalyticsItem.h
+++ b/media/libmediametrics/include/MediaAnalyticsItem.h
@@ -56,12 +56,6 @@
kTypeRate = 5,
};
- // sessionid
- // unique within device, within boot,
- typedef int64_t SessionID_t;
- static constexpr SessionID_t SessionIDInvalid = -1;
- static constexpr SessionID_t SessionIDNone = 0;
-
// Key: the record descriminator
// values for the record discriminator
// values can be "component/component"
@@ -102,16 +96,6 @@
// access functions for the class
~MediaAnalyticsItem();
- // SessionID ties multiple submissions for same key together
- // so that if video "height" and "width" are known at one point
- // and "framerate" is only known later, they can be be brought
- // together.
- MediaAnalyticsItem &setSessionID(SessionID_t);
- MediaAnalyticsItem &clearSessionID();
- SessionID_t getSessionID() const;
- // generates and stores a new ID iff mSessionID == SessionIDNone
- SessionID_t generateSessionID();
-
// reset all contents, discarding any extra data
void clear();
MediaAnalyticsItem *dup();
@@ -149,10 +133,7 @@
bool getCString(Attr, char **value);
bool getString(Attr, std::string *value);
- // parameter indicates whether to close any existing open
- // record with same key before establishing a new record
- // caller retains ownership of 'this'.
- bool selfrecord(bool);
+ // Deliver the item to MediaMetrics
bool selfrecord();
// remove indicated attributes and their values
@@ -231,12 +212,8 @@
static void dropInstance();
// tracking information
- SessionID_t mSessionID; // grouping similar records
nsecs_t mTimestamp; // ns, system_time_monotonic
- // will this record accept further updates
- bool mFinalized;
-
Key mKey;
struct Prop {
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index f0cb9c1..1ed8b74 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -66,19 +66,8 @@
mItems.clear();
}
-MediaAnalyticsItem::SessionID_t MediaAnalyticsService::generateUniqueSessionID() {
- return ++mLastSessionID;
-}
-
-// TODO: consider removing forcenew.
-MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(
- MediaAnalyticsItem *item, bool forcenew __unused)
+status_t MediaAnalyticsService::submitInternal(MediaAnalyticsItem *item, bool release)
{
- // fill in a sessionID if we do not yet have one
- if (item->getSessionID() <= MediaAnalyticsItem::SessionIDNone) {
- item->setSessionID(generateUniqueSessionID());
- }
-
// we control these, generally not trusting user input
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
// round nsecs to seconds
@@ -136,8 +125,8 @@
// validate the record; we discard if we don't like it
if (isContentValid(item, isTrusted) == false) {
- delete item;
- return MediaAnalyticsItem::SessionIDInvalid;
+ if (release) delete item;
+ return PERMISSION_DENIED;
}
// XXX: if we have a sessionid in the new record, look to make
@@ -145,18 +134,17 @@
if (item->count() == 0) {
ALOGV("%s: dropping empty record...", __func__);
- delete item;
- return MediaAnalyticsItem::SessionIDInvalid;
+ if (release) delete item;
+ return BAD_VALUE;
}
// send to statsd
extern bool dump2Statsd(MediaAnalyticsItem *item); // extern hook
(void)dump2Statsd(item); // failure should be logged in function.
- // keep our copy
- const MediaAnalyticsItem::SessionID_t id = item->getSessionID();
+ if (!release) item = item->dup();
saveItem(item);
- return id;
+ return NO_ERROR;
}
status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
diff --git a/services/mediaanalytics/MediaAnalyticsService.h b/services/mediaanalytics/MediaAnalyticsService.h
index ed7b7b1..eb7d725 100644
--- a/services/mediaanalytics/MediaAnalyticsService.h
+++ b/services/mediaanalytics/MediaAnalyticsService.h
@@ -35,31 +35,28 @@
~MediaAnalyticsService() override;
/**
- * Submits the indicated record to the mediaanalytics service, where
- * it will be merged (if appropriate) with incomplete records that
- * share the same key and sessionid.
+ * Submits the indicated record to the mediaanalytics service.
*
* \param item the item to submit.
- * \param forcenew marks any matching incomplete record as complete before
- * inserting this new record.
- *
- * \return the sessionID associated with that item or
- * MediaAnalyticsItem::SessionIDInvalid on failure.
- *
- * BEWARE: When called directly on the service (not from the binder interface),
- * the caller surrenders ownership of item, MediaAnalyticsService will delete
- * even on error. The binder interface does not take ownership.
- * TODO: fix this inconsistency with the binder RPC interface.
+ * \return status failure, which is negative on binder transaction failure.
+ * As the transaction is one-way, remote failures will not be reported.
*/
- MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) override;
+ status_t submit(MediaAnalyticsItem *item) override {
+ return submitInternal(item, false /* release */);
+ }
status_t dump(int fd, const Vector<String16>& args) override;
static constexpr const char * const kServiceName = "media.metrics";
+protected:
+
+ // Internal call where release is true if ownership of item is transferred
+ // to the service (that is, the service will eventually delete the item).
+ status_t submitInternal(MediaAnalyticsItem *item, bool release) override;
+
private:
void processExpirations();
- MediaAnalyticsItem::SessionID_t generateUniqueSessionID();
// input validation after arrival from client
static bool isContentValid(const MediaAnalyticsItem *item, bool isTrusted);
bool isRateLimited(MediaAnalyticsItem *) const;
@@ -86,8 +83,6 @@
const size_t mMaxRecordsExpiredAtOnce;
const int mDumpProtoDefault;
- std::atomic<MediaAnalyticsItem::SessionID_t> mLastSessionID{};
-
class UidInfo {
public:
void setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion);
diff --git a/services/mediaanalytics/tests/mediametrics_tests.cpp b/services/mediaanalytics/tests/mediametrics_tests.cpp
index 794b2f0..ea7739b 100644
--- a/services/mediaanalytics/tests/mediametrics_tests.cpp
+++ b/services/mediaanalytics/tests/mediametrics_tests.cpp
@@ -30,26 +30,25 @@
sp mediaMetrics = new MediaAnalyticsService();
status_t status;
- // NOTE: submission of items to MediaMetrics releases ownership, even on error.
-
// random keys ignored when empty
- status = mediaMetrics->submit(MediaAnalyticsItem::create("random_key"), false);
- ASSERT_EQ(MediaAnalyticsItem::SessionIDInvalid, status);
+ std::unique_ptr<MediaAnalyticsItem> random_key(MediaAnalyticsItem::create("random_key"));
+ status = mediaMetrics->submit(random_key.get());
+ ASSERT_EQ(PERMISSION_DENIED, status);
// random keys ignored with data
- auto random_key = MediaAnalyticsItem::create("random_key");
random_key->setInt32("foo", 10);
- status = mediaMetrics->submit(random_key, false);
- ASSERT_EQ(MediaAnalyticsItem::SessionIDInvalid, status);
+ status = mediaMetrics->submit(random_key.get());
+ ASSERT_EQ(PERMISSION_DENIED, status);
// known keys ignored if empty
- status = mediaMetrics->submit(MediaAnalyticsItem::create("audiotrack"), false);
- ASSERT_EQ(MediaAnalyticsItem::SessionIDInvalid, status);
+ std::unique_ptr<MediaAnalyticsItem> audiotrack_key(MediaAnalyticsItem::create("audiotrack"));
+ status = mediaMetrics->submit(audiotrack_key.get());
+ ASSERT_EQ(BAD_VALUE, status);
- auto audiotrack = MediaAnalyticsItem::create("audiotrack");
- audiotrack->addInt32("foo", 10);
- status = mediaMetrics->submit(audiotrack, false);
- ASSERT_GT(status, MediaAnalyticsItem::SessionIDNone);
+ // known keys not ignored if not empty
+ audiotrack_key->addInt32("foo", 10);
+ status = mediaMetrics->submit(audiotrack_key.get());
+ ASSERT_EQ(NO_ERROR, status);
mediaMetrics->dump(fileno(stdout), {} /* args */);
}