11754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/* 21754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Copyright (C) 2016 The Android Open Source Project 31754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * 41754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 51754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * you may not use this file except in compliance with the License. 61754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * You may obtain a copy of the License at 71754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * 81754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * http://www.apache.org/licenses/LICENSE-2.0 91754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * 101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Unless required by applicable law or agreed to in writing, software 111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * See the License for the specific language governing permissions and 141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * limitations under the License. 151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */ 161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#define LOG_TAG "incidentd" 181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "Reporter.h" 201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "protobuf.h" 211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "report_directory.h" 231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "section_list.h" 241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <private/android_filesystem_config.h> 261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <android/os/DropBoxManager.h> 271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <utils/SystemClock.h> 281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <sys/types.h> 301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <sys/stat.h> 311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <dirent.h> 321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <fcntl.h> 331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <errno.h> 341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/** 361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * The directory where the incident reports are stored. 371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */ 381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic const String8 INCIDENT_DIRECTORY("/data/incidents"); 391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatic status_t 411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratowrite_all(int fd, uint8_t const* buf, size_t size) 421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while (size > 0) { 441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ssize_t amt = ::write(fd, buf, size); 451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (amt < 0) { 461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return -errno; 471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato size -= amt; 491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato buf += amt; 501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return NO_ERROR; 521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReportRequest::ReportRequest(const IncidentReportArgs& a, 561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const sp<IIncidentReportStatusListener> &l, int f) 571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato :args(a), 581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato listener(l), 591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato fd(f), 601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato err(NO_ERROR) 611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReportRequest::~ReportRequest() 651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReportRequestSet::ReportRequestSet() 701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato :mRequests(), 711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mWritableCount(0), 721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mMainFd(-1) 731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReportRequestSet::~ReportRequestSet() 771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratovoid 811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReportRequestSet::add(const sp<ReportRequest>& request) 821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mRequests.push_back(request); 841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mWritableCount++; 851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratovoid 881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReportRequestSet::setMainFd(int fd) 891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mMainFd = fd; 911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mWritableCount++; 921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatus_t 951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReportRequestSet::write(uint8_t const* buf, size_t size) 961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato status_t err = EBADF; 981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // The streaming ones 1001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int const N = mRequests.size(); 1011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (int i=N-1; i>=0; i--) { 1021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato sp<ReportRequest> request = mRequests[i]; 1031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (request->fd >= 0 && request->err == NO_ERROR) { 1041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato err = write_all(request->fd, buf, size); 1051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err != NO_ERROR) { 1061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato request->err = err; 1071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mWritableCount--; 1081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // The dropbox file 1131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (mMainFd >= 0) { 1141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato err = write_all(mMainFd, buf, size); 1151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err != NO_ERROR) { 1161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mMainFd = -1; 1171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mWritableCount--; 1181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Return an error only when there are no FDs to write. 1221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return mWritableCount > 0 ? NO_ERROR : err; 1231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 1241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 1271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReporter::Reporter() 1281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato :args(), 1291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato batch() 1301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 1311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato char buf[100]; 1321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // TODO: Make the max size smaller for user builds. 1341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mMaxSize = 100 * 1024 * 1024; 1351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mMaxCount = 100; 1361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // There can't be two at the same time because it's on one thread. 1381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mStartTime = time(NULL); 1391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato strftime(buf, sizeof(buf), "/incident-%Y%m%d-%H%M%S", localtime(&mStartTime)); 1401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato mFilename = INCIDENT_DIRECTORY + buf; 1411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 1421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReporter::~Reporter() 1441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 1451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 1461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReporter::run_report_status_t 1481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReporter::runReport() 1491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 1501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato status_t err = NO_ERROR; 1521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato bool needMainFd = false; 1531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int mainFd = -1; 1541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // See if we need the main file 1561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) { 1571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if ((*it)->fd < 0 && mainFd < 0) { 1581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato needMainFd = true; 1591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato break; 1601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (needMainFd) { 1631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Create the directory 1641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato err = create_directory(INCIDENT_DIRECTORY); 1651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err != NO_ERROR) { 1661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato goto done; 1671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // If there are too many files in the directory (for whatever reason), 1701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // delete the oldest ones until it's under the limit. Doing this first 1711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // does mean that we can go over, so the max size is not a hard limit. 1721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato clean_directory(INCIDENT_DIRECTORY, mMaxSize, mMaxCount); 1731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Open the file. 1751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato err = create_file(&mainFd); 1761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err != NO_ERROR) { 1771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato goto done; 1781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Add to the set 1811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato batch.setMainFd(mainFd); 1821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Tell everyone that we're starting. 1851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) { 1861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if ((*it)->listener != NULL) { 1871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato (*it)->listener->onReportStarted(); 1881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 1901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Write the incident headers 1921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) { 1931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const sp<ReportRequest> request = (*it); 1941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const vector<vector<int8_t>>& headers = request->args.headers(); 1951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 1961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (vector<vector<int8_t>>::const_iterator buf=headers.begin(); buf!=headers.end(); 1971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato buf++) { 1981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato int fd = request->fd >= 0 ? request->fd : mainFd; 1991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint8_t buffer[20]; 2011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato uint8_t* p = write_length_delimited_tag_header(buffer, FIELD_ID_INCIDENT_HEADER, 2021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato buf->size()); 2031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato write_all(fd, buffer, p-buffer); 2041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato write_all(fd, (uint8_t const*)buf->data(), buf->size()); 2061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // If there was an error now, there will be an error later and we will remove 2071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // it from the list then. 2081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // For each of the report fields, see if we need it, and if so, execute the command 2121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // and report to those that care that we're doing it. 2131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (const Section** section=SECTION_LIST; *section; section++) { 2141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const int id = (*section)->id; 2151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGD("Taking incident report section %d '%s'", id, (*section)->name.string()); 2161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (this->args.containsSection(id)) { 2181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Notify listener of starting 2191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) { 2201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if ((*it)->listener != NULL && (*it)->args.containsSection(id)) { 2211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato (*it)->listener->onReportSectionStatus(id, 2221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato IIncidentReportStatusListener::STATUS_STARTING); 2231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Execute - go get the data and write it into the file descriptors. 2271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato err = (*section)->Execute(&batch); 2281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err != NO_ERROR) { 2291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGW("Incident section %s (%d) failed. Stopping report.", 2301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato (*section)->name.string(), id); 2311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato goto done; 2321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Notify listener of starting 2351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) { 2361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if ((*it)->listener != NULL && (*it)->args.containsSection(id)) { 2371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato (*it)->listener->onReportSectionStatus(id, 2381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato IIncidentReportStatusListener::STATUS_FINISHED); 2391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratodone: 2451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Close the file. 2461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (mainFd >= 0) { 2471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato close(mainFd); 2481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Tell everyone that we're done. 2511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato for (ReportRequestSet::iterator it=batch.begin(); it!=batch.end(); it++) { 2521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if ((*it)->listener != NULL) { 2531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (err == NO_ERROR) { 2541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato (*it)->listener->onReportFinished(); 2551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } else { 2561754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato (*it)->listener->onReportFailed(); 2571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Put the report into dropbox. 2621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (needMainFd && err == NO_ERROR) { 2631754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato sp<DropBoxManager> dropbox = new DropBoxManager(); 2641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato Status status = dropbox->addFile(String16("incident"), mFilename, 0); 2651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGD("Incident report done. dropbox status=%s\n", status.toString8().string()); 2661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (!status.isOk()) { 2671754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return REPORT_NEEDS_DROPBOX; 2681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // If the status was ok, delete the file. If not, leave it around until the next 2711754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // boot or the next checkin. If the directory gets too big older files will 2721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // be rotated out. 2731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato unlink(mFilename.c_str()); 2741754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return REPORT_FINISHED; 2771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 2781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2791754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/** 2801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Create our output file and set the access permissions to -rw-rw---- 2811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */ 2821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onoratostatus_t 2831754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReporter::create_file(int* fd) 2841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 2851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato const char* filename = mFilename.c_str(); 2861754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0660); 2881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (*fd < 0) { 2891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGE("Couldn't open incident file: %s (%s)", filename, strerror(errno)); 2901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return -errno; 2911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 2921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Override umask. Not super critical. If it fails go on with life. 2941754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato chmod(filename, 0660); 2951754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 2961754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (chown(filename, AID_SYSTEM, AID_SYSTEM)) { 2971754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGE("Unable to change ownership of incident file %s: %s\n", filename, strerror(errno)); 2981754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato status_t err = -errno; 2991754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato unlink(mFilename.c_str()); 3001754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return err; 3011754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3021754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3031754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return NO_ERROR; 3041754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 3051754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3061754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato// ================================================================================ 3071754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReporter::run_report_status_t 3081754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoReporter::upload_backlog() 3091754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato{ 3101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato DIR* dir; 3111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato struct dirent* entry; 3121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato struct stat st; 3131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if ((dir = opendir(INCIDENT_DIRECTORY.string())) == NULL) { 3151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGE("Couldn't open incident directory: %s", INCIDENT_DIRECTORY.string()); 3161754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return REPORT_NEEDS_DROPBOX; 3171754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato String8 dirbase(INCIDENT_DIRECTORY + "/"); 3201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato sp<DropBoxManager> dropbox = new DropBoxManager(); 3211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // Enumerate, count and add up size 3231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato while ((entry = readdir(dir)) != NULL) { 3241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (entry->d_name[0] == '.') { 3251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato continue; 3261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3271754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato String8 filename = dirbase + entry->d_name; 3281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (stat(filename.string(), &st) != 0) { 3291754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGE("Unable to stat file %s", filename.string()); 3301754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato continue; 3311754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3321754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (!S_ISREG(st.st_mode)) { 3331754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato continue; 3341754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato Status status = dropbox->addFile(String16("incident"), filename.string(), 0); 3371754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato ALOGD("Incident report done. dropbox status=%s\n", status.toString8().string()); 3381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato if (!status.isOk()) { 3391754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return REPORT_NEEDS_DROPBOX; 3401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3411754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3421754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // If the status was ok, delete the file. If not, leave it around until the next 3431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // boot or the next checkin. If the directory gets too big older files will 3441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato // be rotated out. 3451754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato unlink(filename.string()); 3461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato } 3471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3481754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato closedir(dir); 3491754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 3501754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato return REPORT_FINISHED; 3511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato} 3521754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato 353