LogStatistics.cpp revision ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6
134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn/*
234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Copyright (C) 2014 The Android Open Source Project
334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *
434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License");
534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * you may not use this file except in compliance with the License.
634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * You may obtain a copy of the License at
734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *
834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *      http://www.apache.org/licenses/LICENSE-2.0
934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *
1034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Unless required by applicable law or agreed to in writing, software
1134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS,
1234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * See the License for the specific language governing permissions and
1434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * limitations under the License.
1534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn */
1634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
1797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <algorithm> // std::max
189a03863e88da99ba010342c874252089dd771f7fMark Salyzyn#include <fcntl.h>
1997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <stdio.h>
2097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <string.h>
2197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <unistd.h>
2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/logger.h>
2434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <private/android_filesystem_config.h>
2534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <utils/String8.h>
2634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
2734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include "LogStatistics.h"
2834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
29720f6d1d55d936d98cc9752e96f479e03e6d5009Mark SalyzynLogStatistics::LogStatistics()
30720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        : enable(false) {
3197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
3297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mSizes[id] = 0;
3397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mElements[id] = 0;
3497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mSizesTotal[id] = 0;
3597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        mElementsTotal[id] = 0;
3634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
3734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
3834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
39720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android {
40720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
4197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string
42720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynstatic char *pidToName(pid_t pid) {
439a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    char *retval = NULL;
44df5aa61f05ccbef441cf8b024d4bbc1b717451f9Mark Salyzyn    if (pid == 0) { // special case from auditd for kernel
45df5aa61f05ccbef441cf8b024d4bbc1b717451f9Mark Salyzyn        retval = strdup("logd.auditd");
4697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    } else {
479a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        char buffer[512];
489a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
499a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        int fd = open(buffer, O_RDONLY);
509a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        if (fd >= 0) {
519a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            ssize_t ret = read(fd, buffer, sizeof(buffer));
529a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            if (ret > 0) {
539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                buffer[sizeof(buffer)-1] = '\0';
549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                // frameworks intermediate state
559a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                if (strcmp(buffer, "<pre-initialized>")) {
569a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                    retval = strdup(buffer);
579a03863e88da99ba010342c874252089dd771f7fMark Salyzyn                }
589a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            }
599a03863e88da99ba010342c874252089dd771f7fMark Salyzyn            close(fd);
609a03863e88da99ba010342c874252089dd771f7fMark Salyzyn        }
619a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    }
629a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    return retval;
639a03863e88da99ba010342c874252089dd771f7fMark Salyzyn}
649a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
65720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
66720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
6797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynvoid LogStatistics::add(LogBufferElement *e) {
6897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_t log_id = e->getLogId();
6997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    unsigned short size = e->getMsgLen();
7097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizes[log_id] += size;
7197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    ++mElements[log_id];
7234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
7397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uid_t uid = e->getUid();
74ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    unsigned short dropped = e->getDropped();
7597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    android::hash_t hash = android::hash_type(uid);
7697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t &table = uidTable[log_id];
7797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    ssize_t index = table.find(-1, hash, uid);
7897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (index == -1) {
7997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        UidEntry initEntry(uid);
8097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        initEntry.add(size);
81ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        initEntry.add_dropped(dropped);
8297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        table.add(hash, initEntry);
8334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    } else {
8497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        UidEntry &entry = table.editEntryAt(index);
8597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        entry.add(size);
86ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        entry.add_dropped(dropped);
8734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
88c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
8997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizesTotal[log_id] += size;
9097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    ++mElementsTotal[log_id];
91720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
92720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (!enable) {
93720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return;
94720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
95720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
96720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pid_t pid = e->getPid();
97720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    hash = android::hash_type(pid);
98720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    index = pidTable.find(-1, hash, pid);
99720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (index == -1) {
100720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        PidEntry initEntry(pid, uid, android::pidToName(pid));
101720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        initEntry.add(size);
102ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        initEntry.add_dropped(dropped);
103720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        pidTable.add(hash, initEntry);
104720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    } else {
105720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        PidEntry &entry = pidTable.editEntryAt(index);
106720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (entry.getUid() != uid) {
107720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            entry.setUid(uid);
108720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            entry.setName(android::pidToName(pid));
109720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        } else if (!entry.getName()) {
110720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            char *name = android::pidToName(pid);
111720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (name) {
112720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                entry.setName(name);
113720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
114720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
115720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        entry.add(size);
116ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        entry.add_dropped(dropped);
117720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
11834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
11934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
12097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynvoid LogStatistics::subtract(LogBufferElement *e) {
12197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_t log_id = e->getLogId();
12297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    unsigned short size = e->getMsgLen();
12397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    mSizes[log_id] -= size;
12497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    --mElements[log_id];
12534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
12697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uid_t uid = e->getUid();
127ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    unsigned short dropped = e->getDropped();
12897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    android::hash_t hash = android::hash_type(uid);
12997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t &table = uidTable[log_id];
13097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    ssize_t index = table.find(-1, hash, uid);
13197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (index != -1) {
13297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        UidEntry &entry = table.editEntryAt(index);
133ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
13497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            table.removeAt(index);
13534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
13634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
13734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
138720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (!enable) {
139720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return;
14034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
14134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
142720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pid_t pid = e->getPid();
143720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    hash = android::hash_type(pid);
144720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    index = pidTable.find(-1, hash, pid);
145720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (index != -1) {
146720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        PidEntry &entry = pidTable.editEntryAt(index);
147ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
148720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            pidTable.removeAt(index);
149c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn        }
150c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn    }
151c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn}
152c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
153ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// Atomically set an entry to drop
154ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// entry->setDropped(1) must follow this call, caller should do this explicitly.
155ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzynvoid LogStatistics::drop(LogBufferElement *e) {
156ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    log_id_t log_id = e->getLogId();
157ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    unsigned short size = e->getMsgLen();
158ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    mSizes[log_id] -= size;
159ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
160ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    uid_t uid = e->getUid();
161ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    android::hash_t hash = android::hash_type(uid);
162ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    typeof uidTable[0] &table = uidTable[log_id];
163ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    ssize_t index = table.find(-1, hash, uid);
164ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (index != -1) {
165ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        UidEntry &entry = table.editEntryAt(index);
166ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        entry.subtract(size);
167ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        entry.add_dropped(1);
168ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
169ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
170ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (!enable) {
171ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        return;
172ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
173ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
174ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    pid_t pid = e->getPid();
175ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    hash = android::hash_type(pid);
176ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    index = pidTable.find(-1, hash, pid);
177ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (index != -1) {
178ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        PidEntry &entry = pidTable.editEntryAt(index);
179ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        entry.subtract(size);
180ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        entry.add_dropped(1);
181ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
182ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn}
183ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
18497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string
18597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynchar *LogStatistics::uidToName(uid_t uid) {
18697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Local hard coded favourites
18797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (uid == AID_LOGD) {
18897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        return strdup("auditd");
18934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
19034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
19197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Android hard coded
19297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    const struct android_id_info *info = android_ids;
19334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
19497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    for (size_t i = 0; i < android_id_count; ++i) {
19597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (info->aid == uid) {
19697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            return strdup(info->name);
19734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
19897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        ++info;
19934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
20034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
20108739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    // Parse /data/system/packages.list
20208739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    char *name = android::uidToName(uid);
20308739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    if (name) {
20408739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn        return name;
20508739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn    }
206720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
207720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // report uid -> pid(s) -> pidToName if unique
208720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ssize_t index = -1;
209720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    while ((index = pidTable.next(index)) != -1) {
210720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        const PidEntry &entry = pidTable.entryAt(index);
211720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
212720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (entry.getUid() == uid) {
213720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            const char *n = entry.getName();
214720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
215720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (n) {
216720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                if (!name) {
217720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    name = strdup(n);
218720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                } else if (strcmp(name, n)) {
219720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    free(name);
220720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    return NULL;
221720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
222720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
223720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
224720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
225720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
22697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // No one
227720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    return name;
22834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
22934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
23097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynstatic void format_line(android::String8 &output,
231ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        android::String8 &name, android::String8 &size, android::String8 &pruned) {
232ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    static const size_t pruned_len = 6;
233ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    static const size_t total_len = 70 + pruned_len;
234ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
235ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
236ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    ssize_t size_len = std::max(size.length() + 1,
237ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                                total_len - name.length() - drop_len - 1);
238ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
239ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (pruned.length()) {
240ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        output.appendFormat("%s%*s%*s\n", name.string(),
241ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                                          (int)size_len, size.string(),
242ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                                          (int)drop_len, pruned.string());
243ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    } else {
244ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        output.appendFormat("%s%*s\n", name.string(),
245ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                                       (int)size_len, size.string());
246ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
24734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
24834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
24997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzynvoid LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
2509a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    static const unsigned short spaces_total = 19;
25134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
25234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    if (*buf) {
253239605ef64d34ced82c97870e3f3f5c4145be58cGreg Hackmann        free(*buf);
25434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        *buf = NULL;
25534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
25634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
25797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Report on total logging, current and for all time
25897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
25997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    android::String8 output("size/num");
26034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t oldLength;
26197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    short spaces = 1;
26234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
26397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
26497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
265c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn            continue;
266c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn        }
26797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        oldLength = output.length();
268c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn        if (spaces < 0) {
269c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn            spaces = 0;
270c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn        }
27197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        output.appendFormat("%*s%s", spaces, "", android_log_id_to_name(id));
27297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        spaces += spaces_total + oldLength - output.length();
27397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    }
274c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
27597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    spaces = 4;
27697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    output.appendFormat("\nTotal");
277c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn
27897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
27997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
28097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            continue;
28134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
28297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        oldLength = output.length();
28397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (spaces < 0) {
28497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            spaces = 0;
285e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn        }
28697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        output.appendFormat("%*s%zu/%zu", spaces, "",
28797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                            sizesTotal(id), elementsTotal(id));
28897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        spaces += spaces_total + oldLength - output.length();
28934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
29034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
29197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    spaces = 6;
29297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    output.appendFormat("\nNow");
29334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
29497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
29597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
29634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            continue;
29734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
29834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
29997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        size_t els = elements(id);
30034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        if (els) {
30197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            oldLength = output.length();
302e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            if (spaces < 0) {
303e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                spaces = 0;
304e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn            }
30597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            output.appendFormat("%*s%zu/%zu", spaces, "", sizes(id), els);
30697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            spaces -= output.length() - oldLength;
30734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
30834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        spaces += spaces_total;
30934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
31034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
31197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Report on Chattiest
3128e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
31397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // Chattiest by application (UID)
314720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    static const size_t maximum_sorted_entries = 32;
31597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    log_id_for_each(id) {
31697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        if (!(logMask & (1 << id))) {
3178e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn            continue;
3188e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn        }
3198e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn
320720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        bool headerPrinted = false;
321720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        std::unique_ptr<const UidEntry *[]> sorted = sort(maximum_sorted_entries, id);
322720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        ssize_t index = -1;
323720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        while ((index = uidTable_t::next(index, sorted, maximum_sorted_entries)) >= 0) {
32497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            const UidEntry *entry = sorted[index];
32597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            uid_t u = entry->getKey();
32697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            if ((uid != AID_ROOT) && (u != uid)) {
32734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn                continue;
32834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
32934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
330720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (!headerPrinted) {
33197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                if (uid == AID_ROOT) {
33297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                    output.appendFormat(
33397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                        "\n\nChattiest UIDs in %s:\n",
33497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                        android_log_id_to_name(id));
33597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                } else {
33697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                    output.appendFormat(
33797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                        "\n\nLogging for your UID in %s:\n",
33897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                        android_log_id_to_name(id));
339e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn                }
340ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                android::String8 name("UID");
341ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                android::String8 size("Size");
342ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                android::String8 pruned("Pruned");
343ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                if (id == LOG_ID_CRASH) {
344ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                    pruned.setTo("");
345ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                }
346ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                format_line(output, name, size, pruned);
347720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                headerPrinted = true;
34834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
34934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
35097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            android::String8 name("");
35197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            name.appendFormat("%u", u);
35297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            char *n = uidToName(u);
35397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            if (n) {
35497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                name.appendFormat("%*s%s", (int)std::max(6 - name.length(), (size_t)1), "", n);
35597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                free(n);
35634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn            }
35734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
35897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            android::String8 size("");
359720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            size.appendFormat("%zu", entry->getSizes());
36034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
361ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            android::String8 pruned("");
362ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            size_t dropped = entry->getDropped();
363ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            if (dropped) {
364ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                pruned.appendFormat("%zu", dropped);
365ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            }
366ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
367ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            format_line(output, name, size, pruned);
36834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn        }
369720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
37097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
371720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (enable) {
372720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        bool headerPrinted = false;
373720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
374720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        ssize_t index = -1;
375720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        while ((index = pidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
376720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            const PidEntry *entry = sorted[index];
377720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            uid_t u = entry->getUid();
378720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if ((uid != AID_ROOT) && (u != uid)) {
379720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                continue;
380720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
381720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
382720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (!headerPrinted) {
383720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                if (uid == AID_ROOT) {
384720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    output.appendFormat("\n\nChattiest PIDs:\n");
385720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                } else {
386720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    output.appendFormat("\n\nLogging for this PID:\n");
387720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
388720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                android::String8 name("  PID/UID");
389720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                android::String8 size("Size");
390ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                android::String8 pruned("Pruned");
391ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                format_line(output, name, size, pruned);
392720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                headerPrinted = true;
393720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
394720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
395720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            android::String8 name("");
396720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            name.appendFormat("%5u/%u", entry->getKey(), u);
397720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            const char *n = entry->getName();
398720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (n) {
399720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
400720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            } else {
401720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                char *un = uidToName(u);
402720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                if (un) {
403720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
404720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    free(un);
405720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
406720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
407720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
408720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            android::String8 size("");
409720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            size.appendFormat("%zu", entry->getSizes());
410720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
411ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            android::String8 pruned("");
412ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            size_t dropped = entry->getDropped();
413ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            if (dropped) {
414ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn                pruned.appendFormat("%zu", dropped);
415ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            }
416ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
417ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn            format_line(output, name, size, pruned);
418720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
41934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    }
42034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
42197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    *buf = strdup(output.string());
42234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn}
4234ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn
424720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android {
425720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
426720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t pidToUid(pid_t pid) {
42797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    char buffer[512];
42897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
42997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    FILE *fp = fopen(buffer, "r");
43097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    if (fp) {
43197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        while (fgets(buffer, sizeof(buffer), fp)) {
43297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            int uid;
43397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn            if (sscanf(buffer, "Groups: %d", &uid) == 1) {
43497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                fclose(fp);
43597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn                return uid;
4364ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn            }
4374ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn        }
43897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn        fclose(fp);
4394ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    }
4404ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    return getuid(); // associate this with the logger
4414ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn}
442720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
443720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
444720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
445720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) {
446720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    uid_t uid;
447720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    android::hash_t hash = android::hash_type(pid);
448720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ssize_t index = pidTable.find(-1, hash, pid);
449720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (index == -1) {
450720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        uid = android::pidToUid(pid);
451720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        PidEntry initEntry(pid, uid, android::pidToName(pid));
452720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        pidTable.add(hash, initEntry);
453720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    } else {
454720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        PidEntry &entry = pidTable.editEntryAt(index);
455720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (!entry.getName()) {
456720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            char *name = android::pidToName(pid);
457720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (name) {
458720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                entry.setName(name);
459720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
460720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
461720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        uid = entry.getUid();
462720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
463720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    return uid;
464720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
465720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
466720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn// caller must free character string
467720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynchar *LogStatistics::pidToName(pid_t pid) {
468720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    char *name;
469720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
470720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    android::hash_t hash = android::hash_type(pid);
471720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ssize_t index = pidTable.find(-1, hash, pid);
472720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    if (index == -1) {
473720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        name = android::pidToName(pid);
474720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        PidEntry initEntry(pid, android::pidToUid(pid), name ? strdup(name) : NULL);
475720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        pidTable.add(hash, initEntry);
476720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    } else {
477720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        PidEntry &entry = pidTable.editEntryAt(index);
478720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        const char *n = entry.getName();
479720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (n) {
480720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            name = strdup(n);
481720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        } else {
482720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            name = android::pidToName(pid);
483720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (name) {
484720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                entry.setName(strdup(name));
485720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
486720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
487720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
488720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
489720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    return name;
490720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn}
491