blob: 35c1f5b4c2117f735970ee49af05b6006864ef1f [file] [log] [blame]
Ray Essick3938dc62016-11-01 08:56:56 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// Proxy for media player implementations
18
19//#define LOG_NDEBUG 0
20#define LOG_TAG "MediaAnalyticsService"
21#include <utils/Log.h>
22
23#include <inttypes.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <sys/time.h>
27#include <dirent.h>
28#include <unistd.h>
29
30#include <string.h>
31
32#include <cutils/atomic.h>
33#include <cutils/properties.h> // for property_get
34
35#include <utils/misc.h>
36
37#include <binder/IPCThreadState.h>
38#include <binder/IServiceManager.h>
39#include <binder/MemoryHeapBase.h>
40#include <binder/MemoryBase.h>
41#include <gui/Surface.h>
42#include <utils/Errors.h> // for status_t
43#include <utils/List.h>
44#include <utils/String8.h>
45#include <utils/SystemClock.h>
46#include <utils/Timers.h>
47#include <utils/Vector.h>
48
49#include <media/AudioPolicyHelper.h>
50#include <media/IMediaHTTPService.h>
51#include <media/IRemoteDisplay.h>
52#include <media/IRemoteDisplayClient.h>
53#include <media/MediaPlayerInterface.h>
54#include <media/mediarecorder.h>
55#include <media/MediaMetadataRetrieverInterface.h>
56#include <media/Metadata.h>
57#include <media/AudioTrack.h>
58#include <media/MemoryLeakTrackUtil.h>
59#include <media/stagefright/MediaCodecList.h>
60#include <media/stagefright/MediaErrors.h>
61#include <media/stagefright/Utils.h>
62#include <media/stagefright/foundation/ADebug.h>
63#include <media/stagefright/foundation/ALooperRoster.h>
64#include <mediautils/BatteryNotifier.h>
65
66//#include <memunreachable/memunreachable.h>
67#include <system/audio.h>
68
69#include <private/android_filesystem_config.h>
70
71#include "MediaAnalyticsService.h"
72
73
74namespace android {
75
76
Ray Essickb5fac8e2016-12-12 11:33:56 -080077#define DEBUG_QUEUE 0
Ray Essick3938dc62016-11-01 08:56:56 -070078
79//using android::status_t;
80//using android::OK;
81//using android::BAD_VALUE;
82//using android::NOT_ENOUGH_DATA;
83//using android::Parcel;
84
85
86void MediaAnalyticsService::instantiate() {
87 defaultServiceManager()->addService(
Ray Essickd38e1742017-01-23 15:17:06 -080088 String16("media.metrics"), new MediaAnalyticsService());
Ray Essick3938dc62016-11-01 08:56:56 -070089}
90
91// XXX: add dynamic controls for mMaxRecords
92MediaAnalyticsService::MediaAnalyticsService()
93 : mMaxRecords(100) {
94
95 ALOGD("MediaAnalyticsService created");
96 // clear our queues
Ray Essickb5fac8e2016-12-12 11:33:56 -080097 mOpen = new List<MediaAnalyticsItem *>();
98 mFinalized = new List<MediaAnalyticsItem *>();
Ray Essick3938dc62016-11-01 08:56:56 -070099
100 mItemsSubmitted = 0;
101 mItemsFinalized = 0;
102 mItemsDiscarded = 0;
103
104 mLastSessionID = 0;
105 // recover any persistency we set up
106 // etc
107}
108
109MediaAnalyticsService::~MediaAnalyticsService() {
110 ALOGD("MediaAnalyticsService destroyed");
111
112 // XXX: clean out mOpen and mFinalized
113}
114
115
116MediaAnalyticsItem::SessionID_t MediaAnalyticsService::generateUniqueSessionID() {
117 // generate a new sessionid
118
119 Mutex::Autolock _l(mLock_ids);
120 return (++mLastSessionID);
121}
122
Ray Essickb5fac8e2016-12-12 11:33:56 -0800123// caller surrenders ownership of 'item'
124MediaAnalyticsItem::SessionID_t MediaAnalyticsService::submit(MediaAnalyticsItem *item, bool forcenew) {
Ray Essick3938dc62016-11-01 08:56:56 -0700125
126 MediaAnalyticsItem::SessionID_t id = MediaAnalyticsItem::SessionIDInvalid;
127
Ray Essickd38e1742017-01-23 15:17:06 -0800128 // we control these, generally not trusting user input
Ray Essick3938dc62016-11-01 08:56:56 -0700129 nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
130 item->setTimestamp(now);
131 int pid = IPCThreadState::self()->getCallingPid();
Ray Essick3938dc62016-11-01 08:56:56 -0700132 int uid = IPCThreadState::self()->getCallingUid();
Ray Essickd38e1742017-01-23 15:17:06 -0800133
134 int uid_given = item->getUid();
135 int pid_given = item->getPid();
136
137 // although we do make exceptions for particular client uids
138 // that we know we trust.
139 //
140 bool isTrusted = false;
141
142 switch (uid) {
143 case AID_MEDIA:
144 case AID_MEDIA_CODEC:
145 case AID_MEDIA_EX:
146 case AID_MEDIA_DRM:
147 // trusted source, only override default values
148 isTrusted = true;
149 if (uid_given == (-1)) {
150 item->setUid(uid);
151 }
152 if (pid_given == (-1)) {
153 item->setPid(pid);
154 }
155 break;
156 default:
157 isTrusted = false;
158 item->setPid(pid);
159 item->setUid(uid);
160 break;
161 }
162
Ray Essick3938dc62016-11-01 08:56:56 -0700163
164 mItemsSubmitted++;
165
166 // validate the record; we discard if we don't like it
Ray Essickd38e1742017-01-23 15:17:06 -0800167 if (contentValid(item, isTrusted) == false) {
Ray Essickb5fac8e2016-12-12 11:33:56 -0800168 delete item;
Ray Essick3938dc62016-11-01 08:56:56 -0700169 return MediaAnalyticsItem::SessionIDInvalid;
170 }
171
172
173 // if we have a sesisonid in the new record, look to make
174 // sure it doesn't appear in the finalized list.
175 // XXX: this is for security / DOS prevention.
176 // may also require that we persist the unique sessionIDs
177 // across boots [instead of within a single boot]
178
179
180 // match this new record up against records in the open
181 // list...
182 // if there's a match, merge them together
183 // deal with moving the old / merged record into the finalized que
184
185 bool finalizing = item->getFinalized();
186
187 // if finalizing, we'll remove it
Ray Essickb5fac8e2016-12-12 11:33:56 -0800188 MediaAnalyticsItem *oitem = findItem(mOpen, item, finalizing | forcenew);
Ray Essick3938dc62016-11-01 08:56:56 -0700189 if (oitem != NULL) {
190 if (forcenew) {
191 // old one gets finalized, then we insert the new one
192 // so we'll have 2 records at the end of this.
193 // but don't finalize an empty record
Ray Essickb5fac8e2016-12-12 11:33:56 -0800194 if (oitem->count() == 0) {
195 // we're responsible for disposing of the dead record
196 delete oitem;
197 oitem = NULL;
198 } else {
Ray Essick3938dc62016-11-01 08:56:56 -0700199 oitem->setFinalized(true);
200 saveItem(mFinalized, oitem, 0);
201 }
202 // new record could itself be marked finalized...
203 if (finalizing) {
204 saveItem(mFinalized, item, 0);
205 mItemsFinalized++;
206 } else {
207 saveItem(mOpen, item, 1);
208 }
209 id = item->getSessionID();
210 } else {
211 // combine the records, send it to finalized if appropriate
212 oitem->merge(item);
213 if (finalizing) {
214 saveItem(mFinalized, oitem, 0);
215 mItemsFinalized++;
216 }
217 id = oitem->getSessionID();
Ray Essickb5fac8e2016-12-12 11:33:56 -0800218
219 // we're responsible for disposing of the dead record
220 delete item;
221 item = NULL;
Ray Essick3938dc62016-11-01 08:56:56 -0700222 }
223 } else {
Ray Essickb5fac8e2016-12-12 11:33:56 -0800224 // nothing to merge, save the new record
225 id = item->getSessionID();
226 if (finalizing) {
227 if (item->count() == 0) {
228 // drop empty records
229 delete item;
230 item = NULL;
Ray Essick3938dc62016-11-01 08:56:56 -0700231 } else {
Ray Essickb5fac8e2016-12-12 11:33:56 -0800232 saveItem(mFinalized, item, 0);
233 mItemsFinalized++;
Ray Essick3938dc62016-11-01 08:56:56 -0700234 }
Ray Essickb5fac8e2016-12-12 11:33:56 -0800235 } else {
236 saveItem(mOpen, item, 1);
237 }
Ray Essick3938dc62016-11-01 08:56:56 -0700238 }
Ray Essick3938dc62016-11-01 08:56:56 -0700239 return id;
240}
241
Ray Essickb5fac8e2016-12-12 11:33:56 -0800242List<MediaAnalyticsItem *> *MediaAnalyticsService::getMediaAnalyticsItemList(bool finished, nsecs_t ts) {
Ray Essick3938dc62016-11-01 08:56:56 -0700243 // this might never get called; the binder interface maps to the full parm list
244 // on the client side before making the binder call.
245 // but this lets us be sure...
Ray Essickb5fac8e2016-12-12 11:33:56 -0800246 List<MediaAnalyticsItem*> *list;
Ray Essick3938dc62016-11-01 08:56:56 -0700247 list = getMediaAnalyticsItemList(finished, ts, MediaAnalyticsItem::kKeyAny);
248 return list;
249}
250
Ray Essickb5fac8e2016-12-12 11:33:56 -0800251List<MediaAnalyticsItem *> *MediaAnalyticsService::getMediaAnalyticsItemList(bool , nsecs_t , MediaAnalyticsItem::Key ) {
Ray Essick3938dc62016-11-01 08:56:56 -0700252
253 // XXX: implement the get-item-list semantics
254
Ray Essickb5fac8e2016-12-12 11:33:56 -0800255 List<MediaAnalyticsItem *> *list = NULL;
Ray Essick3938dc62016-11-01 08:56:56 -0700256 // set up our query on the persistent data
257 // slurp in all of the pieces
258 // return that
259 return list;
260}
261
Ray Essickb5fac8e2016-12-12 11:33:56 -0800262status_t MediaAnalyticsService::dump(int fd, const Vector<String16>& args)
Ray Essick3938dc62016-11-01 08:56:56 -0700263{
Ray Essickb5fac8e2016-12-12 11:33:56 -0800264 const size_t SIZE = 512;
Ray Essick3938dc62016-11-01 08:56:56 -0700265 char buffer[SIZE];
266 String8 result;
267
268 if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
269 snprintf(buffer, SIZE, "Permission Denial: "
270 "can't dump MediaAnalyticsService from pid=%d, uid=%d\n",
271 IPCThreadState::self()->getCallingPid(),
272 IPCThreadState::self()->getCallingUid());
273 result.append(buffer);
Ray Essickb5fac8e2016-12-12 11:33:56 -0800274 write(fd, result.string(), result.size());
275 return NO_ERROR;
Ray Essick3938dc62016-11-01 08:56:56 -0700276 }
Ray Essickb5fac8e2016-12-12 11:33:56 -0800277
278 // crack any parameters
279 bool clear = false;
280 nsecs_t ts_since = 0;
281 String16 clearOption("-clear");
282 String16 sinceOption("-since");
Ray Essick35ad27f2017-01-30 14:04:11 -0800283 String16 helpOption("-help");
Ray Essickb5fac8e2016-12-12 11:33:56 -0800284 int n = args.size();
285 for (int i = 0; i < n; i++) {
286 String8 myarg(args[i]);
287 if (args[i] == clearOption) {
288 clear = true;
289 } else if (args[i] == sinceOption) {
290 i++;
291 if (i < n) {
292 String8 value(args[i]);
293 char *endp;
294 const char *p = value.string();
295 ts_since = strtoll(p, &endp, 10);
296 if (endp == p || *endp != '\0') {
297 ts_since = 0;
298 }
299 } else {
300 ts_since = 0;
301 }
Ray Essick35ad27f2017-01-30 14:04:11 -0800302 // command line is milliseconds; internal units are nano-seconds
303 ts_since *= 1000*1000;
304 } else if (args[i] == helpOption) {
305 result.append("Recognized parameters:\n");
306 result.append("-help this help message\n");
307 result.append("-clear clears out saved records\n");
308 result.append("-since XXX include records since XXX\n");
309 result.append(" (XXX is milliseconds since the UNIX epoch)\n");
310 write(fd, result.string(), result.size());
311 return NO_ERROR;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800312 }
313 }
314
315 Mutex::Autolock _l(mLock);
316
Ray Essickd38e1742017-01-23 15:17:06 -0800317 snprintf(buffer, SIZE, "Dump of the mediametrics process:\n");
Ray Essickb5fac8e2016-12-12 11:33:56 -0800318 result.append(buffer);
319
320 int enabled = MediaAnalyticsItem::isEnabled();
321 if (enabled) {
Ray Essickd38e1742017-01-23 15:17:06 -0800322 snprintf(buffer, SIZE, "Metrics gathering: enabled\n");
Ray Essickb5fac8e2016-12-12 11:33:56 -0800323 } else {
Ray Essickd38e1742017-01-23 15:17:06 -0800324 snprintf(buffer, SIZE, "Metrics gathering: DISABLED via property\n");
Ray Essickb5fac8e2016-12-12 11:33:56 -0800325 }
326 result.append(buffer);
327
328 snprintf(buffer, SIZE,
329 "Since Boot: Submissions: %" PRId64
330 " Finalizations: %" PRId64
331 " Discarded: %" PRId64 "\n",
332 mItemsSubmitted, mItemsFinalized, mItemsDiscarded);
333 result.append(buffer);
334 if (ts_since != 0) {
335 snprintf(buffer, SIZE,
336 "Dumping Queue entries more recent than: %" PRId64 "\n",
337 (int64_t) ts_since);
338 result.append(buffer);
339 }
340
341 // show the recently recorded records
Ray Essickd38e1742017-01-23 15:17:06 -0800342 snprintf(buffer, sizeof(buffer), "\nFinalized Metrics (oldest first):\n");
Ray Essickb5fac8e2016-12-12 11:33:56 -0800343 result.append(buffer);
344 result.append(this->dumpQueue(mFinalized, ts_since));
345
Ray Essickd38e1742017-01-23 15:17:06 -0800346 snprintf(buffer, sizeof(buffer), "\nIn-Progress Metrics (newest first):\n");
Ray Essickb5fac8e2016-12-12 11:33:56 -0800347 result.append(buffer);
348 result.append(this->dumpQueue(mOpen, ts_since));
349
350 // show who is connected and injecting records?
351 // talk about # records fed to the 'readers'
352 // talk about # records we discarded, perhaps "discarded w/o reading" too
353
354 if (clear) {
355 // remove everything from the finalized queue
356 while (mFinalized->size() > 0) {
357 MediaAnalyticsItem * oitem = *(mFinalized->begin());
358 if (DEBUG_QUEUE) {
359 ALOGD("zap old record: key %s sessionID %" PRId64 " ts %" PRId64 "",
360 oitem->getKey().c_str(), oitem->getSessionID(),
361 oitem->getTimestamp());
362 }
363 mFinalized->erase(mFinalized->begin());
364 mItemsDiscarded++;
365 }
366 }
367
Ray Essick3938dc62016-11-01 08:56:56 -0700368 write(fd, result.string(), result.size());
369 return NO_ERROR;
370}
371
372// caller has locked mLock...
Ray Essickb5fac8e2016-12-12 11:33:56 -0800373String8 MediaAnalyticsService::dumpQueue(List<MediaAnalyticsItem *> *theList) {
374 return dumpQueue(theList, (nsecs_t) 0);
375}
376
377String8 MediaAnalyticsService::dumpQueue(List<MediaAnalyticsItem *> *theList, nsecs_t ts_since) {
Ray Essick3938dc62016-11-01 08:56:56 -0700378 String8 result;
379 int slot = 0;
380
381 if (theList->empty()) {
382 result.append("empty\n");
383 } else {
Ray Essickb5fac8e2016-12-12 11:33:56 -0800384 List<MediaAnalyticsItem *>::iterator it = theList->begin();
385 for (; it != theList->end(); it++) {
386 nsecs_t when = (*it)->getTimestamp();
387 if (when < ts_since) {
388 continue;
389 }
Ray Essick3938dc62016-11-01 08:56:56 -0700390 AString entry = (*it)->toString();
Ray Essick35ad27f2017-01-30 14:04:11 -0800391 result.appendFormat("%5d: %s\n", slot, entry.c_str());
Ray Essickb5fac8e2016-12-12 11:33:56 -0800392 slot++;
Ray Essick3938dc62016-11-01 08:56:56 -0700393 }
394 }
395
396 return result;
397}
398
399//
400// Our Cheap in-core, non-persistent records management.
401// XXX: rewrite this to manage persistence, etc.
402
403// insert appropriately into queue
Ray Essickb5fac8e2016-12-12 11:33:56 -0800404void MediaAnalyticsService::saveItem(List<MediaAnalyticsItem *> *l, MediaAnalyticsItem * item, int front) {
Ray Essick3938dc62016-11-01 08:56:56 -0700405
406 Mutex::Autolock _l(mLock);
407
Ray Essickb5fac8e2016-12-12 11:33:56 -0800408 if (DEBUG_QUEUE) {
Ray Essick3938dc62016-11-01 08:56:56 -0700409 ALOGD("Inject a record: session %" PRId64 " ts %" PRId64 "",
410 item->getSessionID(), item->getTimestamp());
Ray Essick3938dc62016-11-01 08:56:56 -0700411 String8 before = dumpQueue(l);
412 ALOGD("Q before insert: %s", before.string());
413 }
414
415 // adding at back of queue (fifo order)
416 if (front) {
417 l->push_front(item);
418 } else {
419 l->push_back(item);
420 }
421
Ray Essickb5fac8e2016-12-12 11:33:56 -0800422 if (DEBUG_QUEUE) {
Ray Essick3938dc62016-11-01 08:56:56 -0700423 String8 after = dumpQueue(l);
424 ALOGD("Q after insert: %s", after.string());
425 }
426
427 // keep removing old records the front until we're in-bounds
428 if (mMaxRecords > 0) {
429 while (l->size() > (size_t) mMaxRecords) {
Ray Essickb5fac8e2016-12-12 11:33:56 -0800430 MediaAnalyticsItem * oitem = *(l->begin());
431 if (DEBUG_QUEUE) {
Ray Essick3938dc62016-11-01 08:56:56 -0700432 ALOGD("zap old record: key %s sessionID %" PRId64 " ts %" PRId64 "",
433 oitem->getKey().c_str(), oitem->getSessionID(),
434 oitem->getTimestamp());
435 }
436 l->erase(l->begin());
Ray Essickb5fac8e2016-12-12 11:33:56 -0800437 delete oitem;
Ray Essickb5fac8e2016-12-12 11:33:56 -0800438 mItemsDiscarded++;
Ray Essick3938dc62016-11-01 08:56:56 -0700439 }
440 }
441
Ray Essickb5fac8e2016-12-12 11:33:56 -0800442 if (DEBUG_QUEUE) {
Ray Essick3938dc62016-11-01 08:56:56 -0700443 String8 after = dumpQueue(l);
444 ALOGD("Q after cleanup: %s", after.string());
445 }
446}
447
448// are they alike enough that nitem can be folded into oitem?
Ray Essickb5fac8e2016-12-12 11:33:56 -0800449static bool compatibleItems(MediaAnalyticsItem * oitem, MediaAnalyticsItem * nitem) {
Ray Essick3938dc62016-11-01 08:56:56 -0700450
451 if (0) {
452 ALOGD("Compare: o %s n %s",
453 oitem->toString().c_str(), nitem->toString().c_str());
454 }
455
456 // general safety
457 if (nitem->getUid() != oitem->getUid()) {
458 return false;
459 }
460 if (nitem->getPid() != oitem->getPid()) {
461 return false;
462 }
463
464 // key -- needs to match
465 if (nitem->getKey() == oitem->getKey()) {
466 // still in the game.
467 } else {
468 return false;
469 }
470
471 // session id -- empty field in new is allowed
472 MediaAnalyticsItem::SessionID_t osession = oitem->getSessionID();
473 MediaAnalyticsItem::SessionID_t nsession = nitem->getSessionID();
474 if (nsession != osession) {
475 // incoming '0' matches value in osession
476 if (nsession != 0) {
477 return false;
478 }
479 }
480
481 return true;
482}
483
484// find the incomplete record that this will overlay
Ray Essickb5fac8e2016-12-12 11:33:56 -0800485MediaAnalyticsItem *MediaAnalyticsService::findItem(List<MediaAnalyticsItem*> *theList, MediaAnalyticsItem *nitem, bool removeit) {
Ray Essick3938dc62016-11-01 08:56:56 -0700486 if (nitem == NULL) {
487 return NULL;
488 }
489
Ray Essickb5fac8e2016-12-12 11:33:56 -0800490 MediaAnalyticsItem *item = NULL;
491
Ray Essick3938dc62016-11-01 08:56:56 -0700492 Mutex::Autolock _l(mLock);
493
Ray Essickb5fac8e2016-12-12 11:33:56 -0800494 for (List<MediaAnalyticsItem *>::iterator it = theList->begin();
Ray Essick3938dc62016-11-01 08:56:56 -0700495 it != theList->end(); it++) {
Ray Essickb5fac8e2016-12-12 11:33:56 -0800496 MediaAnalyticsItem *tmp = (*it);
Ray Essick3938dc62016-11-01 08:56:56 -0700497
498 if (!compatibleItems(tmp, nitem)) {
499 continue;
500 }
501
502 // we match! this is the one I want.
503 if (removeit) {
504 theList->erase(it);
505 }
506 item = tmp;
507 break;
508 }
509 return item;
510}
511
512
513// delete the indicated record
Ray Essickb5fac8e2016-12-12 11:33:56 -0800514void MediaAnalyticsService::deleteItem(List<MediaAnalyticsItem *> *l, MediaAnalyticsItem *item) {
Ray Essick3938dc62016-11-01 08:56:56 -0700515
516 Mutex::Autolock _l(mLock);
517
Ray Essickb5fac8e2016-12-12 11:33:56 -0800518 if(DEBUG_QUEUE) {
Ray Essick3938dc62016-11-01 08:56:56 -0700519 String8 before = dumpQueue(l);
520 ALOGD("Q before delete: %s", before.string());
521 }
522
Ray Essickb5fac8e2016-12-12 11:33:56 -0800523 for (List<MediaAnalyticsItem *>::iterator it = l->begin();
Ray Essick3938dc62016-11-01 08:56:56 -0700524 it != l->end(); it++) {
525 if ((*it)->getSessionID() != item->getSessionID())
526 continue;
527
Ray Essickb5fac8e2016-12-12 11:33:56 -0800528 if (DEBUG_QUEUE) {
529 ALOGD(" --- removing record for SessionID %" PRId64 "", item->getSessionID());
530 ALOGD("drop record at %s:%d", __FILE__, __LINE__);
531 }
532 delete *it;
Ray Essick3938dc62016-11-01 08:56:56 -0700533 l->erase(it);
534 break;
535 }
536
Ray Essickb5fac8e2016-12-12 11:33:56 -0800537 if (DEBUG_QUEUE) {
Ray Essick3938dc62016-11-01 08:56:56 -0700538 String8 after = dumpQueue(l);
539 ALOGD("Q after delete: %s", after.string());
540 }
541}
542
Ray Essickd38e1742017-01-23 15:17:06 -0800543static AString allowedKeys[] =
544{
545 "codec",
546 "extractor"
547};
Ray Essick3938dc62016-11-01 08:56:56 -0700548
Ray Essickd38e1742017-01-23 15:17:06 -0800549static const int nAllowedKeys = sizeof(allowedKeys) / sizeof(allowedKeys[0]);
550
551// are the contents good
552bool MediaAnalyticsService::contentValid(MediaAnalyticsItem *item, bool isTrusted) {
553
554 // untrusted uids can only send us a limited set of keys
555 if (isTrusted == false) {
556 // restrict to a specific set of keys
557 AString key = item->getKey();
558
559 size_t i;
560 for(i = 0; i < nAllowedKeys; i++) {
561 if (key == allowedKeys[i]) {
562 break;
563 }
564 }
565 if (i == nAllowedKeys) {
566 ALOGD("Ignoring (key): %s", item->toString().c_str());
567 return false;
568 }
569 }
570
Ray Essick3938dc62016-11-01 08:56:56 -0700571 // internal consistency
572
573 return true;
574}
575
576// are we rate limited, normally false
Ray Essickb5fac8e2016-12-12 11:33:56 -0800577bool MediaAnalyticsService::rateLimited(MediaAnalyticsItem *) {
Ray Essick3938dc62016-11-01 08:56:56 -0700578
579 return false;
580}
581
582
583} // namespace android