Home | History | Annotate | Download | only in src
      1 /*
      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 #define DEBUG false
     17 #include "Log.h"
     18 
     19 #include "Reporter.h"
     20 
     21 #include "incidentd_util.h"
     22 #include "Privacy.h"
     23 #include "PrivacyFilter.h"
     24 #include "proto_util.h"
     25 #include "report_directory.h"
     26 #include "section_list.h"
     27 
     28 #include <android-base/file.h>
     29 #include <android/os/DropBoxManager.h>
     30 #include <android/util/protobuf.h>
     31 #include <android/util/ProtoOutputStream.h>
     32 #include <private/android_filesystem_config.h>
     33 #include <utils/SystemClock.h>
     34 
     35 #include <dirent.h>
     36 #include <errno.h>
     37 #include <fcntl.h>
     38 #include <sys/stat.h>
     39 #include <sys/types.h>
     40 #include <string>
     41 #include <time.h>
     42 
     43 namespace android {
     44 namespace os {
     45 namespace incidentd {
     46 
     47 using namespace android::util;
     48 
     49 /**
     50  * The field id of the metadata section from
     51  *      frameworks/base/core/proto/android/os/incident.proto
     52  */
     53 const int FIELD_ID_METADATA = 2;
     54 
     55 IncidentMetadata_Destination privacy_policy_to_dest(uint8_t privacyPolicy) {
     56     switch (privacyPolicy) {
     57         case PRIVACY_POLICY_AUTOMATIC:
     58             return IncidentMetadata_Destination_AUTOMATIC;
     59         case PRIVACY_POLICY_EXPLICIT:
     60             return IncidentMetadata_Destination_EXPLICIT;
     61         case PRIVACY_POLICY_LOCAL:
     62             return IncidentMetadata_Destination_LOCAL;
     63         default:
     64             // Anything else reverts to automatic
     65             return IncidentMetadata_Destination_AUTOMATIC;
     66     }
     67 }
     68 
     69 
     70 static bool contains_section(const IncidentReportArgs& args, int sectionId) {
     71     return args.containsSection(sectionId, section_requires_specific_mention(sectionId));
     72 }
     73 
     74 static bool contains_section(const sp<ReportRequest>& args, int sectionId) {
     75     return args->containsSection(sectionId);
     76 }
     77 
     78 // ARGS must have a containsSection(int) method
     79 template <typename ARGS>
     80 void make_metadata(IncidentMetadata* result, const IncidentMetadata& full,
     81         int64_t reportId, int32_t privacyPolicy, ARGS args) {
     82     result->set_report_id(reportId);
     83     result->set_dest(privacy_policy_to_dest(privacyPolicy));
     84 
     85     size_t sectionCount = full.sections_size();
     86     for (int sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
     87         const IncidentMetadata::SectionStats& sectionStats = full.sections(sectionIndex);
     88         if (contains_section(args, sectionStats.id())) {
     89             *result->add_sections() = sectionStats;
     90         }
     91     }
     92 }
     93 
     94 // ================================================================================
     95 class StreamingFilterFd : public FilterFd {
     96 public:
     97     StreamingFilterFd(uint8_t privacyPolicy, int fd, const sp<ReportRequest>& request);
     98 
     99     virtual void onWriteError(status_t err);
    100 
    101 private:
    102     sp<ReportRequest> mRequest;
    103 };
    104 
    105 StreamingFilterFd::StreamingFilterFd(uint8_t privacyPolicy, int fd,
    106             const sp<ReportRequest>& request)
    107         :FilterFd(privacyPolicy, fd),
    108          mRequest(request) {
    109 }
    110 
    111 void StreamingFilterFd::onWriteError(status_t err) {
    112     mRequest->setStatus(err);
    113 }
    114 
    115 
    116 // ================================================================================
    117 class PersistedFilterFd : public FilterFd {
    118 public:
    119     PersistedFilterFd(uint8_t privacyPolicy, int fd, const sp<ReportFile>& reportFile);
    120 
    121     virtual void onWriteError(status_t err);
    122 
    123 private:
    124     sp<ReportFile> mReportFile;
    125 };
    126 
    127 PersistedFilterFd::PersistedFilterFd(uint8_t privacyPolicy, int fd,
    128             const sp<ReportFile>& reportFile)
    129         :FilterFd(privacyPolicy, fd),
    130          mReportFile(reportFile) {
    131 }
    132 
    133 void PersistedFilterFd::onWriteError(status_t err) {
    134     mReportFile->setWriteError(err);
    135 }
    136 
    137 
    138 // ================================================================================
    139 ReportRequest::ReportRequest(const IncidentReportArgs& a,
    140                              const sp<IIncidentReportStatusListener>& listener, int fd)
    141         :args(a),
    142          mListener(listener),
    143          mFd(fd),
    144          mIsStreaming(fd >= 0),
    145          mStatus(NO_ERROR) {
    146 }
    147 
    148 ReportRequest::~ReportRequest() {
    149     if (mIsStreaming && mFd >= 0) {
    150         // clean up the opened file descriptor
    151         close(mFd);
    152     }
    153 }
    154 
    155 bool ReportRequest::ok() {
    156     return mFd >= 0 && mStatus == NO_ERROR;
    157 }
    158 
    159 bool ReportRequest::containsSection(int sectionId) const {
    160     return args.containsSection(sectionId, section_requires_specific_mention(sectionId));
    161 }
    162 
    163 void ReportRequest::closeFd() {
    164     if (mIsStreaming && mFd >= 0) {
    165         close(mFd);
    166         mFd = -1;
    167     }
    168 }
    169 
    170 // ================================================================================
    171 ReportBatch::ReportBatch() {}
    172 
    173 ReportBatch::~ReportBatch() {}
    174 
    175 void ReportBatch::addPersistedReport(const IncidentReportArgs& args) {
    176     ComponentName component(args.receiverPkg(), args.receiverCls());
    177     map<ComponentName, sp<ReportRequest>>::iterator found = mPersistedRequests.find(component);
    178     if (found == mPersistedRequests.end()) {
    179         // not found
    180         mPersistedRequests[component] = new ReportRequest(args, nullptr, -1);
    181     } else {
    182         // found
    183         sp<ReportRequest> request = found->second;
    184         request->args.merge(args);
    185     }
    186 }
    187 
    188 void ReportBatch::addStreamingReport(const IncidentReportArgs& args,
    189         const sp<IIncidentReportStatusListener>& listener, int streamFd) {
    190     mStreamingRequests.push_back(new ReportRequest(args, listener, streamFd));
    191 }
    192 
    193 bool ReportBatch::empty() const {
    194     return mPersistedRequests.size() == 0 && mStreamingRequests.size() == 0;
    195 }
    196 
    197 sp<ReportRequest> ReportBatch::getPersistedRequest(const ComponentName& component) {
    198     map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.find(component);
    199     if (it != mPersistedRequests.find(component)) {
    200         return it->second;
    201     } else {
    202         return nullptr;
    203     }
    204 }
    205 
    206 void ReportBatch::forEachPersistedRequest(const function<void (const sp<ReportRequest>&)>& func) {
    207     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    208             it != mPersistedRequests.end(); it++) {
    209         func(it->second);
    210     }
    211 }
    212 
    213 void ReportBatch::forEachStreamingRequest(const function<void (const sp<ReportRequest>&)>& func) {
    214     for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
    215             request != mStreamingRequests.end(); request++) {
    216         func(*request);
    217     }
    218 }
    219 
    220 void ReportBatch::forEachListener(
    221         const function<void (const sp<IIncidentReportStatusListener>&)>& func) {
    222     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    223             it != mPersistedRequests.end(); it++) {
    224         sp<IIncidentReportStatusListener> listener = it->second->getListener();
    225         if (listener != nullptr) {
    226             func(listener);
    227         }
    228     }
    229     for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
    230             request != mStreamingRequests.end(); request++) {
    231         sp<IIncidentReportStatusListener> listener = (*request)->getListener();
    232         if (listener != nullptr) {
    233             func(listener);
    234         }
    235     }
    236 }
    237 
    238 void ReportBatch::forEachListener(int sectionId,
    239         const function<void (const sp<IIncidentReportStatusListener>&)>& func) {
    240     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    241             it != mPersistedRequests.end(); it++) {
    242         if (it->second->containsSection(sectionId)) {
    243             sp<IIncidentReportStatusListener> listener = it->second->getListener();
    244             if (listener != nullptr) {
    245                 func(listener);
    246             }
    247         }
    248     }
    249     for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
    250             request != mStreamingRequests.end(); request++) {
    251         if ((*request)->containsSection(sectionId)) {
    252             sp<IIncidentReportStatusListener> listener = (*request)->getListener();
    253             if (listener != nullptr) {
    254                 func(listener);
    255             }
    256         }
    257     }
    258 }
    259 
    260 void ReportBatch::getCombinedPersistedArgs(IncidentReportArgs* result) {
    261     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    262             it != mPersistedRequests.end(); it++) {
    263         result->merge(it->second->args);
    264     }
    265 }
    266 
    267 bool ReportBatch::containsSection(int sectionId) {
    268     // We don't cache this, because in case of error, we remove requests
    269     // from the batch, and this is easier than recomputing the set.
    270     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    271             it != mPersistedRequests.end(); it++) {
    272         if (it->second->containsSection(sectionId)) {
    273             return true;
    274         }
    275     }
    276     for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
    277             request != mStreamingRequests.end(); request++) {
    278         if ((*request)->containsSection(sectionId)) {
    279             return true;
    280         }
    281     }
    282     return false;
    283 }
    284 
    285 void ReportBatch::clearPersistedRequests() {
    286     mPersistedRequests.clear();
    287 }
    288 
    289 void ReportBatch::transferStreamingRequests(const sp<ReportBatch>& that) {
    290     for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
    291             request != mStreamingRequests.end(); request++) {
    292         that->mStreamingRequests.push_back(*request);
    293     }
    294     mStreamingRequests.clear();
    295 }
    296 
    297 void ReportBatch::transferPersistedRequests(const sp<ReportBatch>& that) {
    298     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    299             it != mPersistedRequests.end(); it++) {
    300         that->mPersistedRequests[it->first] = it->second;
    301     }
    302     mPersistedRequests.clear();
    303 }
    304 
    305 void ReportBatch::getFailedRequests(vector<sp<ReportRequest>>* requests) {
    306     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    307             it != mPersistedRequests.end(); it++) {
    308         if (it->second->getStatus() != NO_ERROR) {
    309             requests->push_back(it->second);
    310         }
    311     }
    312     for (vector<sp<ReportRequest>>::iterator request = mStreamingRequests.begin();
    313             request != mStreamingRequests.end(); request++) {
    314         if ((*request)->getStatus() != NO_ERROR) {
    315             requests->push_back(*request);
    316         }
    317     }
    318 }
    319 
    320 void ReportBatch::removeRequest(const sp<ReportRequest>& request) {
    321     for (map<ComponentName, sp<ReportRequest>>::iterator it = mPersistedRequests.begin();
    322             it != mPersistedRequests.end(); it++) {
    323         if (it->second == request) {
    324             mPersistedRequests.erase(it);
    325             return;
    326         }
    327     }
    328     for (vector<sp<ReportRequest>>::iterator it = mStreamingRequests.begin();
    329             it != mStreamingRequests.end(); it++) {
    330         if (*it == request) {
    331             mStreamingRequests.erase(it);
    332             return;
    333         }
    334     }
    335 }
    336 
    337 // ================================================================================
    338 ReportWriter::ReportWriter(const sp<ReportBatch>& batch)
    339         :mBatch(batch),
    340          mPersistedFile(),
    341          mMaxPersistedPrivacyPolicy(PRIVACY_POLICY_UNSET) {
    342 }
    343 
    344 ReportWriter::~ReportWriter() {
    345 }
    346 
    347 void ReportWriter::setPersistedFile(sp<ReportFile> file) {
    348     mPersistedFile = file;
    349 }
    350 
    351 void ReportWriter::setMaxPersistedPrivacyPolicy(uint8_t privacyPolicy) {
    352     mMaxPersistedPrivacyPolicy = privacyPolicy;
    353 }
    354 
    355 void ReportWriter::startSection(int sectionId) {
    356     mCurrentSectionId = sectionId;
    357     mSectionStartTimeMs = uptimeMillis();
    358 
    359     mSectionStatsCalledForSectionId = -1;
    360     mDumpSizeBytes = 0;
    361     mDumpDurationMs = 0;
    362     mSectionTimedOut = false;
    363     mSectionTruncated = false;
    364     mSectionBufferSuccess = false;
    365     mHadError = false;
    366     mSectionErrors.clear();
    367 
    368 }
    369 
    370 void ReportWriter::setSectionStats(const FdBuffer& buffer) {
    371     mSectionStatsCalledForSectionId = mCurrentSectionId;
    372     mDumpSizeBytes = buffer.size();
    373     mDumpDurationMs = buffer.durationMs();
    374     mSectionTimedOut = buffer.timedOut();
    375     mSectionTruncated = buffer.truncated();
    376     mSectionBufferSuccess = !buffer.timedOut() && !buffer.truncated();
    377 }
    378 
    379 void ReportWriter::endSection(IncidentMetadata::SectionStats* sectionMetadata) {
    380     long endTime = uptimeMillis();
    381 
    382     if (mSectionStatsCalledForSectionId != mCurrentSectionId) {
    383         ALOGW("setSectionStats not called for section %d", mCurrentSectionId);
    384     }
    385 
    386     sectionMetadata->set_id(mCurrentSectionId);
    387     sectionMetadata->set_success((!mHadError) && mSectionBufferSuccess);
    388     sectionMetadata->set_report_size_bytes(mMaxSectionDataFilteredSize);
    389     sectionMetadata->set_exec_duration_ms(endTime - mSectionStartTimeMs);
    390     sectionMetadata->set_dump_size_bytes(mDumpSizeBytes);
    391     sectionMetadata->set_dump_duration_ms(mDumpDurationMs);
    392     sectionMetadata->set_timed_out(mSectionTimedOut);
    393     sectionMetadata->set_is_truncated(mSectionTruncated);
    394     sectionMetadata->set_error_msg(mSectionErrors);
    395 }
    396 
    397 void ReportWriter::warning(const Section* section, status_t err, const char* format, ...) {
    398     va_list args;
    399     va_start(args, format);
    400     vflog(section, err, ANDROID_LOG_ERROR, "error", format, args);
    401     va_end(args);
    402 }
    403 
    404 void ReportWriter::error(const Section* section, status_t err, const char* format, ...) {
    405     va_list args;
    406     va_start(args, format);
    407     vflog(section, err, ANDROID_LOG_WARN, "warning", format, args);
    408     va_end(args);
    409 }
    410 
    411 void ReportWriter::vflog(const Section* section, status_t err, int level, const char* levelText,
    412         const char* format, va_list args) {
    413     const char* prefixFormat = "%s in section %d (%d) '%s': ";
    414     int prefixLen = snprintf(NULL, 0, prefixFormat, levelText, section->id,
    415             err, strerror(-err));
    416 
    417     va_list measureArgs;
    418     va_copy(measureArgs, args);
    419     int messageLen = vsnprintf(NULL, 0, format, args);
    420     va_end(measureArgs);
    421 
    422     char* line = (char*)malloc(prefixLen + messageLen + 1);
    423     if (line == NULL) {
    424         // All hope is lost, just give up.
    425         return;
    426     }
    427 
    428     sprintf(line, prefixFormat, levelText, section->id, err, strerror(-err));
    429 
    430     vsprintf(line + prefixLen, format, args);
    431 
    432     __android_log_write(level, LOG_TAG, line);
    433 
    434     if (mSectionErrors.length() == 0) {
    435         mSectionErrors = line;
    436     } else {
    437         mSectionErrors += '\n';
    438         mSectionErrors += line;
    439     }
    440 
    441     free(line);
    442 
    443     if (level >= ANDROID_LOG_ERROR) {
    444         mHadError = true;
    445     }
    446 }
    447 
    448 // Reads data from FdBuffer and writes it to the requests file descriptor.
    449 status_t ReportWriter::writeSection(const FdBuffer& buffer) {
    450     PrivacyFilter filter(mCurrentSectionId, get_privacy_of_section(mCurrentSectionId));
    451 
    452     // Add the fd for the persisted requests
    453     if (mPersistedFile != nullptr) {
    454         filter.addFd(new PersistedFilterFd(mMaxPersistedPrivacyPolicy,
    455                     mPersistedFile->getDataFileFd(), mPersistedFile));
    456     }
    457 
    458     // Add the fds for the streamed requests
    459     mBatch->forEachStreamingRequest([&filter, this](const sp<ReportRequest>& request) {
    460         if (request->ok()
    461                 && request->args.containsSection(mCurrentSectionId,
    462                     section_requires_specific_mention(mCurrentSectionId))) {
    463             filter.addFd(new StreamingFilterFd(request->args.getPrivacyPolicy(),
    464                         request->getFd(), request));
    465         }
    466     });
    467 
    468     return filter.writeData(buffer, PRIVACY_POLICY_LOCAL, &mMaxSectionDataFilteredSize);
    469 }
    470 
    471 
    472 // ================================================================================
    473 Reporter::Reporter(const sp<WorkDirectory>& workDirectory, const sp<ReportBatch>& batch)
    474         :mWorkDirectory(workDirectory),
    475          mWriter(batch),
    476          mBatch(batch) {
    477 }
    478 
    479 Reporter::~Reporter() {
    480 }
    481 
    482 void Reporter::runReport(size_t* reportByteSize) {
    483     status_t err = NO_ERROR;
    484 
    485     IncidentMetadata metadata;
    486     int persistedPrivacyPolicy = PRIVACY_POLICY_UNSET;
    487 
    488     (*reportByteSize) = 0;
    489 
    490     // Tell everyone that we're starting.
    491     ALOGI("Starting incident report");
    492     mBatch->forEachListener([](const auto& listener) { listener->onReportStarted(); });
    493 
    494     if (mBatch->hasPersistedReports()) {
    495         // Open a work file to contain the contents of all of the persisted reports.
    496         // For this block, if we can't initialize the report file for some reason,
    497         // then we will remove the persisted ReportRequests from the report, but
    498         // continue with the streaming ones.
    499         mPersistedFile = mWorkDirectory->createReportFile();
    500         ALOGI("Report will be persisted: envelope: %s  data: %s",
    501                 mPersistedFile->getEnvelopeFileName().c_str(),
    502                 mPersistedFile->getDataFileName().c_str());
    503 
    504         // Record all of the metadata to the persisted file's metadata file.
    505         // It will be read from there and reconstructed as the actual reports
    506         // are sent out.
    507         if (mPersistedFile != nullptr) {
    508             mBatch->forEachPersistedRequest([this, &persistedPrivacyPolicy](
    509                         const sp<ReportRequest>& request) {
    510                 mPersistedFile->addReport(request->args);
    511                 if (request->args.getPrivacyPolicy() < persistedPrivacyPolicy) {
    512                     persistedPrivacyPolicy = request->args.getPrivacyPolicy();
    513                 }
    514             });
    515             mPersistedFile->setMaxPersistedPrivacyPolicy(persistedPrivacyPolicy);
    516             err = mPersistedFile->saveEnvelope();
    517             if (err != NO_ERROR) {
    518                 mWorkDirectory->remove(mPersistedFile);
    519                 mPersistedFile = nullptr;
    520             }
    521             mWriter.setMaxPersistedPrivacyPolicy(persistedPrivacyPolicy);
    522         }
    523 
    524         if (mPersistedFile != nullptr) {
    525             err = mPersistedFile->startWritingDataFile();
    526             if (err != NO_ERROR) {
    527                 mWorkDirectory->remove(mPersistedFile);
    528                 mPersistedFile = nullptr;
    529             }
    530         }
    531 
    532         if (mPersistedFile != nullptr) {
    533             mWriter.setPersistedFile(mPersistedFile);
    534         } else {
    535             ALOGW("Error creating the persisted file, so clearing persisted reports.");
    536             // If we couldn't open the file (permissions err, etc), then
    537             // we still want to proceed with any streaming reports, but
    538             // cancel all of the persisted ones.
    539             mBatch->forEachPersistedRequest([](const sp<ReportRequest>& request) {
    540                 sp<IIncidentReportStatusListener> listener = request->getListener();
    541                 if (listener != nullptr) {
    542                     listener->onReportFailed();
    543                 }
    544             });
    545             mBatch->clearPersistedRequests();
    546         }
    547     }
    548 
    549     // If we have a persisted ID, then we allow all the readers to see that.  There's
    550     // enough in the data to allow for a join, and nothing in here that intrisincally
    551     // could ever prevent that, so just give them the ID.  If we don't have that then we
    552     // make and ID that's extremely likely to be unique, but clock resetting could allow
    553     // it to be duplicate.
    554     int64_t reportId;
    555     if (mPersistedFile != nullptr) {
    556         reportId = mPersistedFile->getTimestampNs();
    557     } else {
    558         struct timespec spec;
    559         clock_gettime(CLOCK_REALTIME, &spec);
    560         reportId = (spec.tv_sec) * 1000 + spec.tv_nsec;
    561     }
    562 
    563     // Write the incident report headers - each request gets its own headers.  It's different
    564     // from the other top-level fields in IncidentReport that are the sections where the rest
    565     // is all shared data (although with their own individual privacy filtering).
    566     mBatch->forEachStreamingRequest([](const sp<ReportRequest>& request) {
    567         const vector<vector<uint8_t>>& headers = request->args.headers();
    568         for (vector<vector<uint8_t>>::const_iterator buf = headers.begin(); buf != headers.end();
    569              buf++) {
    570             // If there was an error now, there will be an error later and we will remove
    571             // it from the list then.
    572             write_header_section(request->getFd(), buf->data(), buf->size());
    573         }
    574     });
    575 
    576     // If writing to any of the headers failed, we don't want to keep processing
    577     // sections for it.
    578     cancel_and_remove_failed_requests();
    579 
    580     // For each of the report fields, see if we need it, and if so, execute the command
    581     // and report to those that care that we're doing it.
    582     for (const Section** section = SECTION_LIST; *section; section++) {
    583         const int sectionId = (*section)->id;
    584 
    585         // If nobody wants this section, skip it.
    586         if (!mBatch->containsSection(sectionId)) {
    587             continue;
    588         }
    589 
    590         ALOGD("Start incident report section %d '%s'", sectionId, (*section)->name.string());
    591         IncidentMetadata::SectionStats* sectionMetadata = metadata.add_sections();
    592 
    593         // Notify listener of starting
    594         mBatch->forEachListener(sectionId, [sectionId](const auto& listener) {
    595             listener->onReportSectionStatus(
    596                     sectionId, IIncidentReportStatusListener::STATUS_STARTING);
    597         });
    598 
    599         // Go get the data and write it into the file descriptors.
    600         mWriter.startSection(sectionId);
    601         err = (*section)->Execute(&mWriter);
    602         mWriter.endSection(sectionMetadata);
    603 
    604         // Sections returning errors are fatal. Most errors should not be fatal.
    605         if (err != NO_ERROR) {
    606             mWriter.error((*section), err, "Section failed. Stopping report.");
    607             goto DONE;
    608         }
    609 
    610         // The returned max data size is used for throttling too many incident reports.
    611         (*reportByteSize) += sectionMetadata->report_size_bytes();
    612 
    613         // For any requests that failed during this section, remove them now.  We do this
    614         // before calling back about section finished, so listeners do not erroniously get the
    615         // impression that the section succeeded.  But we do it here instead of inside
    616         // writeSection so that the callback is done from a known context and not from the
    617         // bowels of a section, where changing the batch could cause odd errors.
    618         cancel_and_remove_failed_requests();
    619 
    620         // Notify listener of finishing
    621         mBatch->forEachListener(sectionId, [sectionId](const auto& listener) {
    622                 listener->onReportSectionStatus(
    623                         sectionId, IIncidentReportStatusListener::STATUS_FINISHED);
    624         });
    625 
    626         ALOGD("Finish incident report section %d '%s'", sectionId, (*section)->name.string());
    627     }
    628 
    629 DONE:
    630     // Finish up the persisted file.
    631     if (mPersistedFile != nullptr) {
    632         mPersistedFile->closeDataFile();
    633 
    634         // Set the stored metadata
    635         IncidentReportArgs combinedArgs;
    636         mBatch->getCombinedPersistedArgs(&combinedArgs);
    637         IncidentMetadata persistedMetadata;
    638         make_metadata(&persistedMetadata, metadata, mPersistedFile->getTimestampNs(),
    639                 persistedPrivacyPolicy, combinedArgs);
    640         mPersistedFile->setMetadata(persistedMetadata);
    641 
    642         mPersistedFile->markCompleted();
    643         err = mPersistedFile->saveEnvelope();
    644         if (err != NO_ERROR) {
    645             ALOGW("mPersistedFile->saveEnvelope returned %s. Won't send broadcast",
    646                     strerror(-err));
    647             // Abandon ship.
    648             mWorkDirectory->remove(mPersistedFile);
    649         }
    650     }
    651 
    652     // Write the metadata to the streaming ones
    653     mBatch->forEachStreamingRequest([reportId, &metadata](const sp<ReportRequest>& request) {
    654         IncidentMetadata streamingMetadata;
    655         make_metadata(&streamingMetadata, metadata, reportId,
    656                 request->args.getPrivacyPolicy(), request);
    657         status_t nonFatalErr = write_section(request->getFd(), FIELD_ID_METADATA,
    658                 streamingMetadata);
    659         if (nonFatalErr != NO_ERROR) {
    660             ALOGW("Error writing the metadata to streaming incident report.  This is the last"
    661                     " thing so we won't return an error: %s", strerror(nonFatalErr));
    662         }
    663     });
    664 
    665     // Finish up the streaming ones.
    666     mBatch->forEachStreamingRequest([](const sp<ReportRequest>& request) {
    667         request->closeFd();
    668     });
    669 
    670     // Tell the listeners that we're done.
    671     if (err == NO_ERROR) {
    672         mBatch->forEachListener([](const auto& listener) {
    673             listener->onReportFinished();
    674         });
    675     } else {
    676         mBatch->forEachListener([](const auto& listener) {
    677             listener->onReportFailed();
    678         });
    679     }
    680 
    681     ALOGI("Done taking incident report err=%s", strerror(-err));
    682 }
    683 
    684 void Reporter::cancel_and_remove_failed_requests() {
    685     // Handle a failure in the persisted file
    686     if (mPersistedFile != nullptr) {
    687         if (mPersistedFile->getWriteError() != NO_ERROR) {
    688             ALOGW("Error writing to the persisted file (%s). Closing it and canceling.",
    689                     strerror(-mPersistedFile->getWriteError()));
    690             mBatch->forEachPersistedRequest([this](const sp<ReportRequest>& request) {
    691                 sp<IIncidentReportStatusListener> listener = request->getListener();
    692                 if (listener != nullptr) {
    693                     listener->onReportFailed();
    694                 }
    695                 mBatch->removeRequest(request);
    696             });
    697             mWriter.setPersistedFile(nullptr);
    698             mPersistedFile->closeDataFile();
    699             mWorkDirectory->remove(mPersistedFile);
    700             mPersistedFile = nullptr;
    701         }
    702     }
    703 
    704     // Handle failures in the streaming files
    705     vector<sp<ReportRequest>> failed;
    706     mBatch->getFailedRequests(&failed);
    707     for (sp<ReportRequest>& request: failed) {
    708         ALOGW("Error writing to a request stream (%s). Closing it and canceling.",
    709                 strerror(-request->getStatus()));
    710         sp<IIncidentReportStatusListener> listener = request->getListener();
    711         if (listener != nullptr) {
    712             listener->onReportFailed();
    713         }
    714         request->closeFd();  // Will only close the streaming ones.
    715         mBatch->removeRequest(request);
    716     }
    717 }
    718 
    719 }  // namespace incidentd
    720 }  // namespace os
    721 }  // namespace android
    722