|
|
|
@ -100,9 +100,6 @@ MediaAnalyticsService::MediaAnalyticsService()
|
|
|
|
|
mDumpProtoDefault(MediaAnalyticsItem::PROTO_V1) {
|
|
|
|
|
|
|
|
|
|
ALOGD("MediaAnalyticsService created");
|
|
|
|
|
// clear our queues
|
|
|
|
|
mOpen = new List<MediaAnalyticsItem *>();
|
|
|
|
|
mFinalized = new List<MediaAnalyticsItem *>();
|
|
|
|
|
|
|
|
|
|
mItemsSubmitted = 0;
|
|
|
|
|
mItemsFinalized = 0;
|
|
|
|
@ -118,26 +115,13 @@ MediaAnalyticsService::MediaAnalyticsService()
|
|
|
|
|
MediaAnalyticsService::~MediaAnalyticsService() {
|
|
|
|
|
ALOGD("MediaAnalyticsService destroyed");
|
|
|
|
|
|
|
|
|
|
// clean out mOpen and mFinalized
|
|
|
|
|
while (mOpen->size() > 0) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(mOpen->begin());
|
|
|
|
|
mOpen->erase(mOpen->begin());
|
|
|
|
|
while (mItems.size() > 0) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(mItems.begin());
|
|
|
|
|
mItems.erase(mItems.begin());
|
|
|
|
|
delete oitem;
|
|
|
|
|
mItemsDiscarded++;
|
|
|
|
|
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'
|
|
|
|
|
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
|
|
|
|
|
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
|
|
|
|
@ -164,9 +153,7 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem
|
|
|
|
|
int uid_given = item->getUid();
|
|
|
|
|
int pid_given = item->getPid();
|
|
|
|
|
|
|
|
|
|
// although we do make exceptions for particular client uids
|
|
|
|
|
// that we know we trust.
|
|
|
|
|
//
|
|
|
|
|
// although we do make exceptions for some trusted client uids
|
|
|
|
|
bool isTrusted = false;
|
|
|
|
|
|
|
|
|
|
ALOGV("caller has uid=%d, embedded uid=%d", uid, uid_given);
|
|
|
|
@ -192,7 +179,6 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Overwrite package name and version if the caller was untrusted.
|
|
|
|
|
if (!isTrusted) {
|
|
|
|
|
setPkgInfo(item, item->getUid(), true, true);
|
|
|
|
@ -217,75 +203,23 @@ MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem
|
|
|
|
|
return MediaAnalyticsItem::SessionIDInvalid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if we have a sesisonid in the new record, look to make
|
|
|
|
|
// XXX: if we have a sessionid in the new record, look to make
|
|
|
|
|
// sure it doesn't appear in the finalized list.
|
|
|
|
|
// XXX: this is for security / DOS prevention.
|
|
|
|
|
// may also require that we persist the unique sessionIDs
|
|
|
|
|
// across boots [instead of within a single boot]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// match this new record up against records in the open
|
|
|
|
|
// list...
|
|
|
|
|
// if there's a match, merge them together
|
|
|
|
|
// deal with moving the old / merged record into the finalized que
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
if (item->count() == 0) {
|
|
|
|
|
// drop empty records
|
|
|
|
|
delete item;
|
|
|
|
|
item = NULL;
|
|
|
|
|
return MediaAnalyticsItem::SessionIDInvalid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// save the new record
|
|
|
|
|
MediaAnalyticsItem::SessionID_t id = item->getSessionID();
|
|
|
|
|
saveItem(item);
|
|
|
|
|
mItemsFinalized++;
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -378,6 +312,7 @@ status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Mutex::Autolock _l(mLock);
|
|
|
|
|
// mutex between insertion and dumping the contents
|
|
|
|
|
|
|
|
|
|
mDumpProto = chosenProto;
|
|
|
|
|
|
|
|
|
@ -392,9 +327,9 @@ status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
|
|
|
|
|
|
|
|
|
|
if (clear) {
|
|
|
|
|
// remove everything from the finalized queue
|
|
|
|
|
while (mFinalized->size() > 0) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(mFinalized->begin());
|
|
|
|
|
mFinalized->erase(mFinalized->begin());
|
|
|
|
|
while (mItems.size() > 0) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(mItems.begin());
|
|
|
|
|
mItems.erase(mItems.begin());
|
|
|
|
|
delete oitem;
|
|
|
|
|
mItemsDiscarded++;
|
|
|
|
|
}
|
|
|
|
@ -408,7 +343,8 @@ status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
char buffer[SIZE];
|
|
|
|
|
|
|
|
|
@ -425,7 +361,7 @@ void MediaAnalyticsService::dumpHeaders(String8 &result, nsecs_t ts_since) {
|
|
|
|
|
|
|
|
|
|
snprintf(buffer, SIZE,
|
|
|
|
|
"Since Boot: Submissions: %8" PRId64
|
|
|
|
|
" Finalizations: %8" PRId64 "\n",
|
|
|
|
|
" Accepted: %8" PRId64 "\n",
|
|
|
|
|
mItemsSubmitted, mItemsFinalized);
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
snprintf(buffer, SIZE,
|
|
|
|
@ -433,19 +369,17 @@ void MediaAnalyticsService::dumpHeaders(String8 &result, nsecs_t ts_since) {
|
|
|
|
|
" (by Count: %" PRId64 " by Expiration: %" PRId64 ")\n",
|
|
|
|
|
mItemsDiscarded, mItemsDiscardedCount, mItemsDiscardedExpire);
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
snprintf(buffer, SIZE,
|
|
|
|
|
"Summary Sets Discarded: %" PRId64 "\n", mSetsDiscarded);
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
if (ts_since != 0) {
|
|
|
|
|
snprintf(buffer, SIZE,
|
|
|
|
|
"Dumping Queue entries more recent than: %" PRId64 "\n",
|
|
|
|
|
"Emitting Queue entries more recent than: %" PRId64 "\n",
|
|
|
|
|
(int64_t) ts_since);
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
char buffer[SIZE];
|
|
|
|
|
|
|
|
|
@ -456,30 +390,27 @@ void MediaAnalyticsService::dumpRecent(String8 &result, nsecs_t ts_since, const
|
|
|
|
|
// show the recently recorded records
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "\nFinalized Metrics (oldest first):\n");
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
result.append(this->dumpQueue(mFinalized, ts_since, only));
|
|
|
|
|
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "\nIn-Progress Metrics (newest first):\n");
|
|
|
|
|
result.append(buffer);
|
|
|
|
|
result.append(this->dumpQueue(mOpen, ts_since, only));
|
|
|
|
|
result.append(this->dumpQueue(ts_since, only));
|
|
|
|
|
|
|
|
|
|
// show who is connected and injecting records?
|
|
|
|
|
// talk about # records fed to the 'readers'
|
|
|
|
|
// talk about # records we discarded, perhaps "discarded w/o reading" too
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// caller has locked mLock...
|
|
|
|
|
String8 MediaAnalyticsService::dumpQueue(List<MediaAnalyticsItem *> *theList) {
|
|
|
|
|
return dumpQueue(theList, (nsecs_t) 0, NULL);
|
|
|
|
|
String8 MediaAnalyticsService::dumpQueue() {
|
|
|
|
|
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;
|
|
|
|
|
int slot = 0;
|
|
|
|
|
|
|
|
|
|
if (theList->empty()) {
|
|
|
|
|
if (mItems.empty()) {
|
|
|
|
|
result.append("empty\n");
|
|
|
|
|
} else {
|
|
|
|
|
List<MediaAnalyticsItem *>::iterator it = theList->begin();
|
|
|
|
|
for (; it != theList->end(); it++) {
|
|
|
|
|
List<MediaAnalyticsItem *>::iterator it = mItems.begin();
|
|
|
|
|
for (; it != mItems.end(); it++) {
|
|
|
|
|
nsecs_t when = (*it)->getTimestamp();
|
|
|
|
|
if (when < ts_since) {
|
|
|
|
|
continue;
|
|
|
|
@ -500,35 +431,25 @@ String8 MediaAnalyticsService::dumpQueue(List<MediaAnalyticsItem *> *theList, ns
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Our Cheap in-core, non-persistent records management.
|
|
|
|
|
// XXX: rewrite this to manage persistence, etc.
|
|
|
|
|
|
|
|
|
|
// insert appropriately into queue
|
|
|
|
|
// caller should hold mLock
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
void MediaAnalyticsService::saveItem(MediaAnalyticsItem * item)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// our reclaim process is for oldest-first queues
|
|
|
|
|
if (front) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Mutex::Autolock _l(mLock);
|
|
|
|
|
// mutex between insertion and dumping the contents
|
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
if (mMaxRecords > 0) {
|
|
|
|
|
while (l->size() > (size_t) mMaxRecords) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(l->begin());
|
|
|
|
|
while (mItems.size() > (size_t) mMaxRecords) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(mItems.begin());
|
|
|
|
|
if (oitem == item) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
l->erase(l->begin());
|
|
|
|
|
mItems.erase(mItems.begin());
|
|
|
|
|
delete oitem;
|
|
|
|
|
mItemsDiscarded++;
|
|
|
|
|
mItemsDiscardedCount++;
|
|
|
|
@ -536,10 +457,11 @@ void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyti
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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) {
|
|
|
|
|
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
|
|
|
|
|
while (l->size() > 0) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(l->begin());
|
|
|
|
|
while (mItems.size() > 0) {
|
|
|
|
|
MediaAnalyticsItem * oitem = *(mItems.begin());
|
|
|
|
|
nsecs_t when = oitem->getTimestamp();
|
|
|
|
|
if (oitem == item) {
|
|
|
|
|
break;
|
|
|
|
@ -549,7 +471,7 @@ void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyti
|
|
|
|
|
// this (and the rest) are recent enough to keep
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
l->erase(l->begin());
|
|
|
|
|
mItems.erase(mItems.begin());
|
|
|
|
|
delete oitem;
|
|
|
|
|
mItemsDiscarded++;
|
|
|
|
|
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[] =
|
|
|
|
|
{
|
|
|
|
|
"audiorecord",
|
|
|
|
@ -676,7 +525,9 @@ bool MediaAnalyticsService::rateLimited(MediaAnalyticsItem *) {
|
|
|
|
|
#define PKG_EXPIRATION_NS (30*60*1000000000ll) // 30 minutes, in nsecs
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
|
|
if (!setName && !setVersion) {
|
|
|
|
@ -686,22 +537,26 @@ void MediaAnalyticsService::setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool
|
|
|
|
|
|
|
|
|
|
nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
|
|
|
|
|
struct UidToPkgMap mapping;
|
|
|
|
|
mapping.uid = (-1);
|
|
|
|
|
|
|
|
|
|
ssize_t i = mPkgMappings.indexOfKey(uid);
|
|
|
|
|
if (i >= 0) {
|
|
|
|
|
mapping = mPkgMappings.valueAt(i);
|
|
|
|
|
ALOGV("Expiration? uid %d expiration %" PRId64 " now %" PRId64,
|
|
|
|
|
uid, mapping.expiration, now);
|
|
|
|
|
if (mapping.expiration < now) {
|
|
|
|
|
// purge our current entry and re-query
|
|
|
|
|
ALOGV("entry for uid %d expired, now= %" PRId64 "", uid, now);
|
|
|
|
|
mPkgMappings.removeItemsAt(i, 1);
|
|
|
|
|
// could cheat and use a goto back to the top of the routine.
|
|
|
|
|
// a good compiler should recognize the local tail recursion...
|
|
|
|
|
return setPkgInfo(item, uid, setName, setVersion);
|
|
|
|
|
mapping.uid = (uid_t)(-1);
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
Mutex::Autolock _l(mLock_mappings);
|
|
|
|
|
int i = mPkgMappings.indexOfKey(uid);
|
|
|
|
|
if (i >= 0) {
|
|
|
|
|
mapping = mPkgMappings.valueAt(i);
|
|
|
|
|
ALOGV("Expiration? uid %d expiration %" PRId64 " now %" PRId64,
|
|
|
|
|
uid, mapping.expiration, now);
|
|
|
|
|
if (mapping.expiration <= now) {
|
|
|
|
|
// purge the stale entry and fall into re-fetching
|
|
|
|
|
ALOGV("entry for uid %d expired, now= %" PRId64 "", uid, now);
|
|
|
|
|
mPkgMappings.removeItemsAt(i);
|
|
|
|
|
mapping.uid = (uid_t)(-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we did not find it
|
|
|
|
|
if (mapping.uid == (uid_t)(-1)) {
|
|
|
|
|
std::string pkg;
|
|
|
|
|
std::string installer = "";
|
|
|
|
|
int64_t versionCode = 0;
|
|
|
|
@ -711,7 +566,7 @@ void MediaAnalyticsService::setPkgInfo(MediaAnalyticsItem *item, uid_t uid, bool
|
|
|
|
|
pkg = pw->pw_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find the proper value -- should we cache this binder??
|
|
|
|
|
// find the proper value
|
|
|
|
|
|
|
|
|
|
sp<IBinder> binder = NULL;
|
|
|
|
|
sp<IServiceManager> sm = defaultServiceManager();
|
|
|
|
|