Remove finalized concept from media.metrics

the 'finalized' concept didn't pan out -- remove references to it.
Simplifies the code flow.
Also purged some uses of generateSessionID().

Bug: 71874686
Test: logcat/dumpsys
Change-Id: I39e48526a5696158d8195f47154881ca6ecda266
gugelfrei
Ray Essick 7 years ago
parent 3923b1b716
commit 92d23b433b

@ -80,7 +80,6 @@ status_t reportMetricsGroup(const MetricsGroup& metricsGroup,
} }
} }
analyticsItem.setFinalized(true);
if (!analyticsItem.selfrecord()) { if (!analyticsItem.selfrecord()) {
ALOGE("selfrecord() returned false. sessioId %" PRId64, sessionId); ALOGE("selfrecord() returned false. sessioId %" PRId64, sessionId);
} }

@ -703,7 +703,6 @@ private:
// mAnalyticsItem alloc failure will be flagged in the constructor // mAnalyticsItem alloc failure will be flagged in the constructor
// don't log empty records // don't log empty records
if (mAnalyticsItem->count() > 0) { if (mAnalyticsItem->count() > 0) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
} }
} }

@ -1198,7 +1198,6 @@ private:
// mAnalyticsItem alloc failure will be flagged in the constructor // mAnalyticsItem alloc failure will be flagged in the constructor
// don't log empty records // don't log empty records
if (mAnalyticsItem->count() > 0) { if (mAnalyticsItem->count() > 0) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
} }
} }

@ -129,7 +129,6 @@ NuPlayer2Driver::NuPlayer2Driver(pid_t pid)
// set up an analytics record // set up an analytics record
mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer); mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer);
mAnalyticsItem->generateSessionID();
mNuPlayer2Looper->start( mNuPlayer2Looper->start(
false, /* runOnCallingThread */ false, /* runOnCallingThread */
@ -661,14 +660,12 @@ void NuPlayer2Driver::logMetrics(const char *where) {
// So the canonical "empty" record has 3 elements in it. // So the canonical "empty" record has 3 elements in it.
if (mAnalyticsItem->count() > 3) { if (mAnalyticsItem->count() > 3) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
// re-init in case we prepare() and start() again. // re-init in case we prepare() and start() again.
delete mAnalyticsItem ; delete mAnalyticsItem ;
mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer); mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer);
if (mAnalyticsItem) { if (mAnalyticsItem) {
mAnalyticsItem->generateSessionID();
mAnalyticsItem->setUid(mClientUid); mAnalyticsItem->setUid(mClientUid);
} }
} else { } else {

@ -60,7 +60,7 @@ MediaAnalyticsItem::MediaAnalyticsItem()
mPkgVersionCode(0), mPkgVersionCode(0),
mSessionID(MediaAnalyticsItem::SessionIDNone), mSessionID(MediaAnalyticsItem::SessionIDNone),
mTimestamp(0), mTimestamp(0),
mFinalized(0), mFinalized(1),
mPropCount(0), mPropSize(0), mProps(NULL) mPropCount(0), mPropSize(0), mProps(NULL)
{ {
mKey = MediaAnalyticsItem::kKeyNone; mKey = MediaAnalyticsItem::kKeyNone;
@ -72,7 +72,7 @@ MediaAnalyticsItem::MediaAnalyticsItem(MediaAnalyticsItem::Key key)
mPkgVersionCode(0), mPkgVersionCode(0),
mSessionID(MediaAnalyticsItem::SessionIDNone), mSessionID(MediaAnalyticsItem::SessionIDNone),
mTimestamp(0), mTimestamp(0),
mFinalized(0), mFinalized(1),
mPropCount(0), mPropSize(0), mProps(NULL) mPropCount(0), mPropSize(0), mProps(NULL)
{ {
if (DEBUG_ALLOCATIONS) { if (DEBUG_ALLOCATIONS) {
@ -137,16 +137,6 @@ MediaAnalyticsItem *MediaAnalyticsItem::dup() {
return dst; return dst;
} }
// so clients can send intermediate values to be overlaid later
MediaAnalyticsItem &MediaAnalyticsItem::setFinalized(bool value) {
mFinalized = value;
return *this;
}
bool MediaAnalyticsItem::getFinalized() const {
return mFinalized;
}
MediaAnalyticsItem &MediaAnalyticsItem::setSessionID(MediaAnalyticsItem::SessionID_t id) { MediaAnalyticsItem &MediaAnalyticsItem::setSessionID(MediaAnalyticsItem::SessionID_t id) {
mSessionID = id; mSessionID = id;
return *this; return *this;
@ -636,7 +626,10 @@ int32_t MediaAnalyticsItem::readFromParcel(const Parcel& data) {
mPkgName = data.readCString(); mPkgName = data.readCString();
mPkgVersionCode = data.readInt64(); mPkgVersionCode = data.readInt64();
mSessionID = 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 = data.readInt32();
mFinalized = 1;
mTimestamp = data.readInt64(); mTimestamp = data.readInt64();
int count = data.readInt32(); int count = data.readInt32();
@ -978,9 +971,6 @@ bool MediaAnalyticsItem::merge(MediaAnalyticsItem *incoming) {
mSessionID = incoming->mSessionID; mSessionID = incoming->mSessionID;
} }
// we always take the more recent 'finalized' value
setFinalized(incoming->getFinalized());
// for each attribute from 'incoming', resolve appropriately // for each attribute from 'incoming', resolve appropriately
int nattr = incoming->mPropCount; int nattr = incoming->mPropCount;
for (int i = 0 ; i < nattr; i++ ) { for (int i = 0 ; i < nattr; i++ ) {

@ -89,10 +89,6 @@ class MediaAnalyticsItem {
MediaAnalyticsItem(Key); MediaAnalyticsItem(Key);
~MediaAnalyticsItem(); ~MediaAnalyticsItem();
// so clients can send intermediate values to be overlaid later
MediaAnalyticsItem &setFinalized(bool);
bool getFinalized() const;
// SessionID ties multiple submissions for same key together // SessionID ties multiple submissions for same key together
// so that if video "height" and "width" are known at one point // so that if video "height" and "width" are known at one point
// and "framerate" is only known later, they can be be brought // and "framerate" is only known later, they can be be brought

@ -125,7 +125,6 @@ StagefrightRecorder::~StagefrightRecorder() {
if (mAnalyticsDirty && mAnalyticsItem != NULL) { if (mAnalyticsDirty && mAnalyticsItem != NULL) {
updateMetrics(); updateMetrics();
if (mAnalyticsItem->count() > 0) { if (mAnalyticsItem->count() > 0) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
} }
delete mAnalyticsItem; delete mAnalyticsItem;
@ -185,14 +184,12 @@ void StagefrightRecorder::resetMetrics() {
if (mAnalyticsDirty && mAnalyticsItem != NULL) { if (mAnalyticsDirty && mAnalyticsItem != NULL) {
updateMetrics(); updateMetrics();
if (mAnalyticsItem->count() > 0) { if (mAnalyticsItem->count() > 0) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
} }
delete mAnalyticsItem; delete mAnalyticsItem;
mAnalyticsItem = NULL; mAnalyticsItem = NULL;
} }
mAnalyticsItem = new MediaAnalyticsItem(kKeyRecorder); mAnalyticsItem = new MediaAnalyticsItem(kKeyRecorder);
(void) mAnalyticsItem->generateSessionID();
mAnalyticsDirty = false; mAnalyticsDirty = false;
} }

@ -91,7 +91,6 @@ NuPlayerDriver::NuPlayerDriver(pid_t pid)
// set up an analytics record // set up an analytics record
mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer); mAnalyticsItem = new MediaAnalyticsItem(kKeyPlayer);
mAnalyticsItem->generateSessionID();
mLooper->start( mLooper->start(
false, /* runOnCallingThread */ false, /* runOnCallingThread */
@ -617,14 +616,12 @@ void NuPlayerDriver::logMetrics(const char *where) {
// So the canonical "empty" record has 3 elements in it. // So the canonical "empty" record has 3 elements in it.
if (mAnalyticsItem->count() > 3) { if (mAnalyticsItem->count() > 3) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
// re-init in case we prepare() and start() again. // re-init in case we prepare() and start() again.
delete mAnalyticsItem ; delete mAnalyticsItem ;
mAnalyticsItem = new MediaAnalyticsItem("nuplayer"); mAnalyticsItem = new MediaAnalyticsItem("nuplayer");
if (mAnalyticsItem) { if (mAnalyticsItem) {
mAnalyticsItem->generateSessionID();
mAnalyticsItem->setUid(mClientUid); mAnalyticsItem->setUid(mClientUid);
} }
} else { } else {

@ -502,7 +502,6 @@ void MediaCodec::initAnalyticsItem() {
// set up our new record, get a sessionID, put it into the in-progress list // set up our new record, get a sessionID, put it into the in-progress list
mAnalyticsItem = new MediaAnalyticsItem(kCodecKeyName); mAnalyticsItem = new MediaAnalyticsItem(kCodecKeyName);
if (mAnalyticsItem != NULL) { if (mAnalyticsItem != NULL) {
(void) mAnalyticsItem->generateSessionID();
// don't record it yet; only at the end, when we have decided that we have // don't record it yet; only at the end, when we have decided that we have
// data worth writing (e.g. .count() > 0) // data worth writing (e.g. .count() > 0)
} }
@ -512,7 +511,6 @@ void MediaCodec::flushAnalyticsItem() {
if (mAnalyticsItem != NULL) { if (mAnalyticsItem != NULL) {
// don't log empty records // don't log empty records
if (mAnalyticsItem->count() > 0) { if (mAnalyticsItem->count() > 0) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
} }
delete mAnalyticsItem; delete mAnalyticsItem;

@ -44,7 +44,6 @@ RemoteMediaExtractor::RemoteMediaExtractor(
mAnalyticsItem = nullptr; mAnalyticsItem = nullptr;
if (MEDIA_LOG) { if (MEDIA_LOG) {
mAnalyticsItem = new MediaAnalyticsItem(kKeyExtractor); mAnalyticsItem = new MediaAnalyticsItem(kKeyExtractor);
(void) mAnalyticsItem->generateSessionID();
// track the container format (mpeg, aac, wvm, etc) // track the container format (mpeg, aac, wvm, etc)
size_t ntracks = extractor->countTracks(); size_t ntracks = extractor->countTracks();
@ -73,7 +72,6 @@ RemoteMediaExtractor::~RemoteMediaExtractor() {
if (MEDIA_LOG) { if (MEDIA_LOG) {
if (mAnalyticsItem != nullptr) { if (mAnalyticsItem != nullptr) {
if (mAnalyticsItem->count() > 0) { if (mAnalyticsItem->count() > 0) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord(); mAnalyticsItem->selfrecord();
} }
} }

@ -100,9 +100,6 @@ MediaAnalyticsService::MediaAnalyticsService()
mDumpProtoDefault(MediaAnalyticsItem::PROTO_V1) { mDumpProtoDefault(MediaAnalyticsItem::PROTO_V1) {
ALOGD("MediaAnalyticsService created"); ALOGD("MediaAnalyticsService created");
// clear our queues
mOpen = new List<MediaAnalyticsItem *>();
mFinalized = new List<MediaAnalyticsItem *>();
mItemsSubmitted = 0; mItemsSubmitted = 0;
mItemsFinalized = 0; mItemsFinalized = 0;
@ -118,26 +115,13 @@ MediaAnalyticsService::MediaAnalyticsService()
MediaAnalyticsService::~MediaAnalyticsService() { MediaAnalyticsService::~MediaAnalyticsService() {
ALOGD("MediaAnalyticsService destroyed"); ALOGD("MediaAnalyticsService destroyed");
// clean out mOpen and mFinalized while (mItems.size() > 0) {
while (mOpen->size() > 0) { MediaAnalyticsItem * oitem = *(mItems.begin());
MediaAnalyticsItem * oitem = *(mOpen->begin()); mItems.erase(mItems.begin());
mOpen->erase(mOpen->begin());
delete oitem; delete oitem;
mItemsDiscarded++; mItemsDiscarded++;
mItemsDiscardedCount++; mItemsDiscardedCount++;
} }
delete mOpen;
mOpen = NULL;
while (mFinalized->size() > 0) {
MediaAnalyticsItem * oitem = *(mFinalized->begin());
mFinalized->erase(mFinalized->begin());
delete oitem;
mItemsDiscarded++;
mItemsDiscardedCount++;
}
delete mFinalized;
mFinalized = NULL;
} }
@ -149,9 +133,14 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::generateUniqueSessionID()
} }
// caller surrenders ownership of 'item' // caller surrenders ownership of 'item'
MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem *item, bool forcenew) { MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem *item, bool forcenew)
{
UNUSED(forcenew);
MediaAnalyticsItem::SessionID_t id = MediaAnalyticsItem::SessionIDInvalid; // 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 // we control these, generally not trusting user input
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME); nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
@ -164,9 +153,7 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem
int uid_given = item->getUid(); int uid_given = item->getUid();
int pid_given = item->getPid(); int pid_given = item->getPid();
// although we do make exceptions for particular client uids // although we do make exceptions for some trusted client uids
// that we know we trust.
//
bool isTrusted = false; bool isTrusted = false;
ALOGV("caller has uid=%d, embedded uid=%d", uid, uid_given); ALOGV("caller has uid=%d, embedded uid=%d", uid, uid_given);
@ -192,7 +179,6 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem
break; break;
} }
// Overwrite package name and version if the caller was untrusted. // Overwrite package name and version if the caller was untrusted.
if (!isTrusted) { if (!isTrusted) {
setPkgInfo(item, item->getUid(), true, true); setPkgInfo(item, item->getUid(), true, true);
@ -217,75 +203,23 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem
return MediaAnalyticsItem::SessionIDInvalid; return MediaAnalyticsItem::SessionIDInvalid;
} }
// XXX: if we have a sessionid in the new record, look to make
// if we have a sesisonid in the new record, look to make
// sure it doesn't appear in the finalized list. // sure it doesn't appear in the finalized list.
// XXX: this is for security / DOS prevention. // XXX: this is for security / DOS prevention.
// may also require that we persist the unique sessionIDs // may also require that we persist the unique sessionIDs
// across boots [instead of within a single boot] // across boots [instead of within a single boot]
if (item->count() == 0) {
// match this new record up against records in the open // drop empty records
// list... delete item;
// if there's a match, merge them together item = NULL;
// deal with moving the old / merged record into the finalized que return MediaAnalyticsItem::SessionIDInvalid;
bool finalizing = item->getFinalized();
Mutex::Autolock _l(mLock);
// if finalizing, we'll remove it
MediaAnalyticsItem *oitem = findItem(mOpen, item, finalizing | forcenew);
if (oitem != NULL) {
if (forcenew) {
// old one gets finalized, then we insert the new one
// so we'll have 2 records at the end of this.
// but don't finalize an empty record
if (oitem->count() == 0) {
// we're responsible for disposing of the dead record
delete oitem;
oitem = NULL;
} else {
oitem->setFinalized(true);
saveItem(mFinalized, oitem, 0);
}
// new record could itself be marked finalized...
id = item->getSessionID();
if (finalizing) {
saveItem(mFinalized, item, 0);
mItemsFinalized++;
} else {
saveItem(mOpen, item, 1);
}
} else {
// combine the records, send it to finalized if appropriate
oitem->merge(item);
id = oitem->getSessionID();
if (finalizing) {
saveItem(mFinalized, oitem, 0);
mItemsFinalized++;
}
// we're responsible for disposing of the dead record
delete item;
item = NULL;
}
} else {
// nothing to merge, save the new record
id = item->getSessionID();
if (finalizing) {
if (item->count() == 0) {
// drop empty records
delete item;
item = NULL;
} else {
saveItem(mFinalized, item, 0);
mItemsFinalized++;
}
} else {
saveItem(mOpen, item, 1);
}
} }
// save the new record
MediaAnalyticsItem::SessionID_t id = item->getSessionID();
saveItem(item);
mItemsFinalized++;
return id; return id;
} }
@ -378,6 +312,7 @@ status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
} }
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
// mutex between insertion and dumping the contents
mDumpProto = chosenProto; mDumpProto = chosenProto;
@ -392,9 +327,9 @@ status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
if (clear) { if (clear) {
// remove everything from the finalized queue // remove everything from the finalized queue
while (mFinalized->size() > 0) { while (mItems.size() > 0) {
MediaAnalyticsItem * oitem = *(mFinalized->begin()); MediaAnalyticsItem * oitem = *(mItems.begin());
mFinalized->erase(mFinalized->begin()); mItems.erase(mItems.begin());
delete oitem; delete oitem;
mItemsDiscarded++; mItemsDiscarded++;
} }
@ -408,7 +343,8 @@ status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
} }
// dump headers // dump headers
void MediaAnalyticsService::dumpHeaders(String8 &result, nsecs_t ts_since) { void MediaAnalyticsService::dumpHeaders(String8 &result, nsecs_t ts_since)
{
const size_t SIZE = 512; const size_t SIZE = 512;
char buffer[SIZE]; char buffer[SIZE];
@ -425,7 +361,7 @@ void MediaAnalyticsService::dumpHeaders(String8 &result, nsecs_t ts_since) {
snprintf(buffer, SIZE, snprintf(buffer, SIZE,
"Since Boot: Submissions: %8" PRId64 "Since Boot: Submissions: %8" PRId64
" Finalizations: %8" PRId64 "\n", " Accepted: %8" PRId64 "\n",
mItemsSubmitted, mItemsFinalized); mItemsSubmitted, mItemsFinalized);
result.append(buffer); result.append(buffer);
snprintf(buffer, SIZE, snprintf(buffer, SIZE,
@ -433,19 +369,17 @@ void MediaAnalyticsService::dumpHeaders(String8 &result, nsecs_t ts_since) {
" (by Count: %" PRId64 " by Expiration: %" PRId64 ")\n", " (by Count: %" PRId64 " by Expiration: %" PRId64 ")\n",
mItemsDiscarded, mItemsDiscardedCount, mItemsDiscardedExpire); mItemsDiscarded, mItemsDiscardedCount, mItemsDiscardedExpire);
result.append(buffer); result.append(buffer);
snprintf(buffer, SIZE,
"Summary Sets Discarded: %" PRId64 "\n", mSetsDiscarded);
result.append(buffer);
if (ts_since != 0) { if (ts_since != 0) {
snprintf(buffer, SIZE, snprintf(buffer, SIZE,
"Dumping Queue entries more recent than: %" PRId64 "\n", "Emitting Queue entries more recent than: %" PRId64 "\n",
(int64_t) ts_since); (int64_t) ts_since);
result.append(buffer); result.append(buffer);
} }
} }
// the recent, detailed queues // the recent, detailed queues
void MediaAnalyticsService::dumpRecent(String8 &result, nsecs_t ts_since, const char * only) { void MediaAnalyticsService::dumpRecent(String8 &result, nsecs_t ts_since, const char * only)
{
const size_t SIZE = 512; const size_t SIZE = 512;
char buffer[SIZE]; char buffer[SIZE];
@ -456,30 +390,27 @@ void MediaAnalyticsService::dumpRecent(String8 &result, nsecs_t ts_since, const
// show the recently recorded records // show the recently recorded records
snprintf(buffer, sizeof(buffer), "\nFinalized Metrics (oldest first):\n"); snprintf(buffer, sizeof(buffer), "\nFinalized Metrics (oldest first):\n");
result.append(buffer); result.append(buffer);
result.append(this->dumpQueue(mFinalized, ts_since, only)); result.append(this->dumpQueue(ts_since, only));
snprintf(buffer, sizeof(buffer), "\nIn-Progress Metrics (newest first):\n");
result.append(buffer);
result.append(this->dumpQueue(mOpen, ts_since, only));
// show who is connected and injecting records? // show who is connected and injecting records?
// talk about # records fed to the 'readers' // talk about # records fed to the 'readers'
// talk about # records we discarded, perhaps "discarded w/o reading" too // talk about # records we discarded, perhaps "discarded w/o reading" too
} }
// caller has locked mLock... // caller has locked mLock...
String8 MediaAnalyticsService::dumpQueue(List<MediaAnalyticsItem *> *theList) { String8 MediaAnalyticsService::dumpQueue() {
return dumpQueue(theList, (nsecs_t) 0, NULL); return dumpQueue((nsecs_t) 0, NULL);
} }
String8 MediaAnalyticsService::dumpQueue(List<MediaAnalyticsItem *> *theList, nsecs_t ts_since, const char * only) { String8 MediaAnalyticsService::dumpQueue(nsecs_t ts_since, const char * only) {
String8 result; String8 result;
int slot = 0; int slot = 0;
if (theList->empty()) { if (mItems.empty()) {
result.append("empty\n"); result.append("empty\n");
} else { } else {
List<MediaAnalyticsItem *>::iterator it = theList->begin(); List<MediaAnalyticsItem *>::iterator it = mItems.begin();
for (; it != theList->end(); it++) { for (; it != mItems.end(); it++) {
nsecs_t when = (*it)->getTimestamp(); nsecs_t when = (*it)->getTimestamp();
if (when < ts_since) { if (when < ts_since) {
continue; continue;
@ -500,35 +431,25 @@ String8 MediaAnalyticsService::dumpQueue(List<MediaAnalyticsItem *> *theList, ns
// //
// Our Cheap in-core, non-persistent records management. // Our Cheap in-core, non-persistent records management.
// XXX: rewrite this to manage persistence, etc.
// insert appropriately into queue // insert appropriately into queue
// caller should hold mLock void MediaAnalyticsService::saveItem(MediaAnalyticsItem * item)
void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyticsItem * item, int front) { {
if (front) {
// for non-finalized stuff, since we expect to reference it again soon,
// make it quicker to find (nearer the front of our list)
l->push_front(item);
} else {
// for finalized records, which we want to dump 'in sequence order'
l->push_back(item);
}
// our reclaim process is for oldest-first queues Mutex::Autolock _l(mLock);
if (front) { // mutex between insertion and dumping the contents
return;
}
// we want to dump 'in FIFO order', so insert at the end
mItems.push_back(item);
// keep removing old records the front until we're in-bounds (count) // keep removing old records the front until we're in-bounds (count)
if (mMaxRecords > 0) { if (mMaxRecords > 0) {
while (l->size() > (size_t) mMaxRecords) { while (mItems.size() > (size_t) mMaxRecords) {
MediaAnalyticsItem * oitem = *(l->begin()); MediaAnalyticsItem * oitem = *(mItems.begin());
if (oitem == item) { if (oitem == item) {
break; break;
} }
l->erase(l->begin()); mItems.erase(mItems.begin());
delete oitem; delete oitem;
mItemsDiscarded++; mItemsDiscarded++;
mItemsDiscardedCount++; mItemsDiscardedCount++;
@ -536,10 +457,11 @@ void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyti
} }
// keep removing old records the front until we're in-bounds (count) // keep removing old records the front until we're in-bounds (count)
// NB: expired entries aren't removed until the next insertion, which could be a while
if (mMaxRecordAgeNs > 0) { if (mMaxRecordAgeNs > 0) {
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME); nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
while (l->size() > 0) { while (mItems.size() > 0) {
MediaAnalyticsItem * oitem = *(l->begin()); MediaAnalyticsItem * oitem = *(mItems.begin());
nsecs_t when = oitem->getTimestamp(); nsecs_t when = oitem->getTimestamp();
if (oitem == item) { if (oitem == item) {
break; break;
@ -549,7 +471,7 @@ void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyti
// this (and the rest) are recent enough to keep // this (and the rest) are recent enough to keep
break; break;
} }
l->erase(l->begin()); mItems.erase(mItems.begin());
delete oitem; delete oitem;
mItemsDiscarded++; mItemsDiscarded++;
mItemsDiscardedExpire++; mItemsDiscardedExpire++;
@ -557,79 +479,6 @@ void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyti
} }
} }
// are they alike enough that nitem can be folded into oitem?
static bool compatibleItems(MediaAnalyticsItem * oitem, MediaAnalyticsItem * nitem) {
// general safety
if (nitem->getUid() != oitem->getUid()) {
return false;
}
if (nitem->getPid() != oitem->getPid()) {
return false;
}
// key -- needs to match
if (nitem->getKey() == oitem->getKey()) {
// still in the game.
} else {
return false;
}
// session id -- empty field in new is allowed
MediaAnalyticsItem::SessionID_t osession = oitem->getSessionID();
MediaAnalyticsItem::SessionID_t nsession = nitem->getSessionID();
if (nsession != osession) {
// incoming '0' matches value in osession
if (nsession != 0) {
return false;
}
}
return true;
}
// find the incomplete record that this will overlay
// caller should hold mLock
MediaAnalyticsItem *MediaAnalyticsService::findItem(List<MediaAnalyticsItem*> *theList, MediaAnalyticsItem *nitem, bool removeit) {
if (nitem == NULL) {
return NULL;
}
MediaAnalyticsItem *item = NULL;
for (List<MediaAnalyticsItem *>::iterator it = theList->begin();
it != theList->end(); it++) {
MediaAnalyticsItem *tmp = (*it);
if (!compatibleItems(tmp, nitem)) {
continue;
}
// we match! this is the one I want.
if (removeit) {
theList->erase(it);
}
item = tmp;
break;
}
return item;
}
// delete the indicated record
// caller should hold mLock
void MediaAnalyticsService::deleteItem(List<MediaAnalyticsItem *> *l, MediaAnalyticsItem *item) {
for (List<MediaAnalyticsItem *>::iterator it = l->begin();
it != l->end(); it++) {
if ((*it)->getSessionID() != item->getSessionID())
continue;
delete *it;
l->erase(it);
break;
}
}
static std::string allowedKeys[] = static std::string allowedKeys[] =
{ {
"audiorecord", "audiorecord",
@ -676,7 +525,9 @@ bool MediaAnalyticsService::rateLimited(MediaAnalyticsItem *) {
#define PKG_EXPIRATION_NS (30*60*1000000000ll) // 30 minutes, in nsecs #define PKG_EXPIRATION_NS (30*60*1000000000ll) // 30 minutes, in nsecs
// give me the package name, perhaps going to find it // give me the package name, perhaps going to find it
void MediaAnalyticsService::setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion) { // manages its own mutex operations internally
void MediaAnalyticsService::setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool setName, bool setVersion)
{
ALOGV("asking for packagename to go with uid=%d", uid); ALOGV("asking for packagename to go with uid=%d", uid);
if (!setName && !setVersion) { if (!setName && !setVersion) {
@ -686,22 +537,26 @@ void MediaAnalyticsService::setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME); nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
struct UidToPkgMap mapping; struct UidToPkgMap mapping;
mapping.uid = (-1); mapping.uid = (uid_t)(-1);
ssize_t i = mPkgMappings.indexOfKey(uid); {
if (i >= 0) { Mutex::Autolock _l(mLock_mappings);
mapping = mPkgMappings.valueAt(i); int i = mPkgMappings.indexOfKey(uid);
ALOGV("Expiration? uid %d expiration %" PRId64 " now %" PRId64, if (i >= 0) {
uid, mapping.expiration, now); mapping = mPkgMappings.valueAt(i);
if (mapping.expiration < now) { ALOGV("Expiration? uid %d expiration %" PRId64 " now %" PRId64,
// purge our current entry and re-query uid, mapping.expiration, now);
ALOGV("entry for uid %d expired, now= %" PRId64 "", uid, now); if (mapping.expiration <= now) {
mPkgMappings.removeItemsAt(i, 1); // purge the stale entry and fall into re-fetching
// could cheat and use a goto back to the top of the routine. ALOGV("entry for uid %d expired, now= %" PRId64 "", uid, now);
// a good compiler should recognize the local tail recursion... mPkgMappings.removeItemsAt(i);
return setPkgInfo(item, uid, setName, setVersion); mapping.uid = (uid_t)(-1);
}
} }
} else { }
// if we did not find it
if (mapping.uid == (uid_t)(-1)) {
std::string pkg; std::string pkg;
std::string installer = ""; std::string installer = "";
int64_t versionCode = 0; int64_t versionCode = 0;
@ -711,7 +566,7 @@ void MediaAnalyticsService::setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool
pkg = pw->pw_name; pkg = pw->pw_name;
} }
// find the proper value -- should we cache this binder?? // find the proper value
sp<IBinder> binder = NULL; sp<IBinder> binder = NULL;
sp<IServiceManager> sm = defaultServiceManager(); sp<IServiceManager> sm = defaultServiceManager();

@ -53,7 +53,6 @@ class MediaAnalyticsService : public BnMediaAnalyticsService
int64_t mItemsDiscarded; int64_t mItemsDiscarded;
int64_t mItemsDiscardedExpire; int64_t mItemsDiscardedExpire;
int64_t mItemsDiscardedCount; int64_t mItemsDiscardedCount;
int64_t mSetsDiscarded;
MediaAnalyticsItem::SessionID_t mLastSessionID; MediaAnalyticsItem::SessionID_t mLastSessionID;
// partitioned a bit so we don't over serialize // partitioned a bit so we don't over serialize
@ -76,25 +75,15 @@ class MediaAnalyticsService : public BnMediaAnalyticsService
bool contentValid(MediaAnalyticsItem *item, bool isTrusted); bool contentValid(MediaAnalyticsItem *item, bool isTrusted);
bool rateLimited(MediaAnalyticsItem *); bool rateLimited(MediaAnalyticsItem *);
// the ones that are still open
// (newest at front) since we keep looking for them
List<MediaAnalyticsItem *> *mOpen;
// the ones we've finalized
// (oldest at front) so it prints nicely for dumpsys // (oldest at front) so it prints nicely for dumpsys
List<MediaAnalyticsItem *> *mFinalized; List<MediaAnalyticsItem *> mItems;
// searching within these queues: queue, key void saveItem(MediaAnalyticsItem *);
MediaAnalyticsItem *findItem(List<MediaAnalyticsItem *> *,
MediaAnalyticsItem *, bool removeit);
void saveItem(MediaAnalyticsItem);
void saveItem(List<MediaAnalyticsItem *> *, MediaAnalyticsItem *, int);
void deleteItem(List<MediaAnalyticsItem *> *, MediaAnalyticsItem *);
// support for generating output // support for generating output
int mDumpProto; int mDumpProto;
int mDumpProtoDefault; int mDumpProtoDefault;
String8 dumpQueue(List<MediaAnalyticsItem*> *); String8 dumpQueue();
String8 dumpQueue(List<MediaAnalyticsItem*> *, nsecs_t, const char *only); String8 dumpQueue(nsecs_t, const char *only);
void dumpHeaders(String8 &result, nsecs_t ts_since); void dumpHeaders(String8 &result, nsecs_t ts_since);
void dumpSummaries(String8 &result, nsecs_t ts_since, const char * only); void dumpSummaries(String8 &result, nsecs_t ts_since, const char * only);

Loading…
Cancel
Save