Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bf3aa69 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 9552483 from ba75fbf7 to udc-release

Change-Id: I450b5be01aed6b09779af437c8ea5d36410f8879
parents b0ba2136 ba75fbf7
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@ static binder::Status exception(uint32_t code, const std::string& msg,
    exit(0);
}

[[noreturn]] static void* dumpstate_thread_retrieve(void* data) {
    std::unique_ptr<DumpstateInfo> ds_info(static_cast<DumpstateInfo*>(data));
    ds_info->ds->Retrieve(ds_info->calling_uid, ds_info->calling_package);
    MYLOGD("Finished retrieving a bugreport. Exiting.\n");
    exit(0);
}

[[noreturn]] static void signalErrorAndExit(sp<IDumpstateListener> listener, int error_code) {
    listener->onError(error_code);
    exit(0);
@@ -192,6 +199,41 @@ binder::Status DumpstateService::cancelBugreport(int32_t calling_uid,
    return binder::Status::ok();
}

binder::Status DumpstateService::retrieveBugreport(
    int32_t calling_uid, const std::string& calling_package,
    android::base::unique_fd bugreport_fd,
    const std::string& bugreport_file,
    const sp<IDumpstateListener>& listener) {

    ds_ = &(Dumpstate::GetInstance());
    DumpstateInfo* ds_info = new DumpstateInfo();
    ds_info->ds = ds_;
    ds_info->calling_uid = calling_uid;
    ds_info->calling_package = calling_package;
    ds_->listener_ = listener;
    std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
    // Use a /dev/null FD when initializing options since none is provided.
    android::base::unique_fd devnull_fd(
        TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));

    options->Initialize(Dumpstate::BugreportMode::BUGREPORT_DEFAULT,
                        0, bugreport_fd, devnull_fd, false);

    if (bugreport_fd.get() == -1) {
        MYLOGE("Invalid filedescriptor");
        signalErrorAndExit(listener, IDumpstateListener::BUGREPORT_ERROR_INVALID_INPUT);
    }
    ds_->SetOptions(std::move(options));
    ds_->path_ = bugreport_file;
    pthread_t thread;
    status_t err = pthread_create(&thread, nullptr, dumpstate_thread_retrieve, ds_info);
    if (err != 0) {
        MYLOGE("Could not create a thread");
        signalErrorAndExit(listener, IDumpstateListener::BUGREPORT_ERROR_RUNTIME_ERROR);
    }
    return binder::Status::ok();
}

status_t DumpstateService::dump(int fd, const Vector<String16>&) {
    std::lock_guard<std::mutex> lock(lock_);
    if (ds_ == nullptr) {
+7 −0
Original line number Diff line number Diff line
@@ -46,6 +46,13 @@ class DumpstateService : public BinderService<DumpstateService>, public BnDumpst
                                  int bugreport_flags, const sp<IDumpstateListener>& listener,
                                  bool is_screenshot_requested) override;

    binder::Status retrieveBugreport(int32_t calling_uid,
                                     const std::string& calling_package,
                                     android::base::unique_fd bugreport_fd,
                                     const std::string& bugreport_file,
                                     const sp<IDumpstateListener>& listener)
                                     override;

    binder::Status cancelBugreport(int32_t calling_uid,
                                   const std::string& calling_package) override;

+22 −1
Original line number Diff line number Diff line
@@ -50,7 +50,10 @@ interface IDumpstate {
    const int BUGREPORT_MODE_DEFAULT = 6;

    // Use pre-dumped data.
    const int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = 1;
    const int BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA = 0x1;

    // Defer user consent.
    const int BUGREPORT_FLAG_DEFER_CONSENT = 0x2;

    /**
     * Speculatively pre-dumps UI data for a bugreport request that might come later.
@@ -100,4 +103,22 @@ interface IDumpstate {
     * @param callingPackage package of the original application that requested the cancellation.
     */
    void cancelBugreport(int callingUid, @utf8InCpp String callingPackage);

    /**
     * Retrieves a previously generated bugreport.
     *
     * <p>The caller must have previously generated a bugreport using
     * {@link #startBugreport} with the {@link BUGREPORT_FLAG_DEFER_CONSENT}
     * flag set.
     *
     * @param callingUid UID of the original application that requested the report.
     * @param callingPackage package of the original application that requested the report.
     * @param bugreportFd the file to which the zipped bugreport should be written
     * @param bugreportFile the path of the bugreport file
     * @param listener callback for updates; optional
     */
    void retrieveBugreport(int callingUid, @utf8InCpp String callingPackage,
                           FileDescriptor bugreportFd,
                           @utf8InCpp String bugreportFile,
                           IDumpstateListener listener);
}
+6 −1
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@ interface IDumpstateListener {
    /* There is currently a bugreport running. The caller should try again later. */
    const int BUGREPORT_ERROR_ANOTHER_REPORT_IN_PROGRESS = 5;

    /* There is no bugreport to retrieve for the given caller. */
    const int BUGREPORT_ERROR_NO_BUGREPORT_TO_RETRIEVE = 6;

    /**
     * Called on an error condition with one of the error codes listed above.
     */
@@ -57,8 +60,10 @@ interface IDumpstateListener {

    /**
     * Called when taking bugreport finishes successfully.
     *
     * @param bugreportFile The location of the bugreport file
     */
    oneway void onFinished();
    oneway void onFinished(@utf8InCpp String bugreportFile);

    /**
     * Called when screenshot is taken.
+72 −8
Original line number Diff line number Diff line
@@ -2825,6 +2825,7 @@ void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode,
                                        const android::base::unique_fd& screenshot_fd_in,
                                        bool is_screenshot_requested) {
    this->use_predumped_ui_data = bugreport_flags & BugreportFlag::BUGREPORT_USE_PREDUMPED_UI_DATA;
    this->is_consent_deferred = bugreport_flags & BugreportFlag::BUGREPORT_FLAG_DEFER_CONSENT;
    // Duplicate the fds because the passed in fds don't outlive the binder transaction.
    bugreport_fd.reset(fcntl(bugreport_fd_in.get(), F_DUPFD_CLOEXEC, 0));
    screenshot_fd.reset(fcntl(screenshot_fd_in.get(), F_DUPFD_CLOEXEC, 0));
@@ -2907,10 +2908,64 @@ void Dumpstate::Initialize() {

Dumpstate::RunStatus Dumpstate::Run(int32_t calling_uid, const std::string& calling_package) {
    Dumpstate::RunStatus status = RunInternal(calling_uid, calling_package);
    HandleRunStatus(status);
    return status;
}

Dumpstate::RunStatus Dumpstate::Retrieve(int32_t calling_uid, const std::string& calling_package) {
    Dumpstate::RunStatus status = RetrieveInternal(calling_uid, calling_package);
    HandleRunStatus(status);
    return status;
}

Dumpstate::RunStatus  Dumpstate::RetrieveInternal(int32_t calling_uid,
                                                  const std::string& calling_package) {
  consent_callback_ = new ConsentCallback();
  const String16 incidentcompanion("incidentcompanion");
  sp<android::IBinder> ics(
      defaultServiceManager()->checkService(incidentcompanion));
  android::String16 package(calling_package.c_str());
  if (ics != nullptr) {
    MYLOGD("Checking user consent via incidentcompanion service\n");
    android::interface_cast<android::os::IIncidentCompanion>(ics)->authorizeReport(
        calling_uid, package, String16(), String16(),
        0x1 /* FLAG_CONFIRMATION_DIALOG */, consent_callback_.get());
  } else {
    MYLOGD(
        "Unable to check user consent; incidentcompanion service unavailable\n");
    return RunStatus::USER_CONSENT_TIMED_OUT;
  }
  UserConsentResult consent_result = consent_callback_->getResult();
  int timeout_ms = 30 * 1000;
  while (consent_result == UserConsentResult::UNAVAILABLE &&
      consent_callback_->getElapsedTimeMs() < timeout_ms) {
    sleep(1);
    consent_result = consent_callback_->getResult();
  }
  if (consent_result == UserConsentResult::DENIED) {
    return RunStatus::USER_CONSENT_DENIED;
  }
  if (consent_result == UserConsentResult::UNAVAILABLE) {
    MYLOGD("Canceling user consent request via incidentcompanion service\n");
    android::interface_cast<android::os::IIncidentCompanion>(ics)->cancelAuthorization(
        consent_callback_.get());
    return RunStatus::USER_CONSENT_TIMED_OUT;
  }

  bool copy_succeeded =
      android::os::CopyFileToFd(path_, options_->bugreport_fd.get());
  if (copy_succeeded) {
    android::os::UnlinkAndLogOnError(path_);
  }
  return copy_succeeded ? Dumpstate::RunStatus::OK
                        : Dumpstate::RunStatus::ERROR;
}

void Dumpstate::HandleRunStatus(Dumpstate::RunStatus status) {
      if (listener_ != nullptr) {
        switch (status) {
            case Dumpstate::RunStatus::OK:
                listener_->onFinished();
                listener_->onFinished(path_.c_str());
                break;
            case Dumpstate::RunStatus::HELP:
                break;
@@ -2928,9 +2983,7 @@ Dumpstate::RunStatus Dumpstate::Run(int32_t calling_uid, const std::string& call
                break;
        }
    }
    return status;
}

void Dumpstate::Cancel() {
    CleanupTmpFiles();
    android::os::UnlinkAndLogOnError(log_path_);
@@ -3181,7 +3234,7 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid,

    // Share the final file with the caller if the user has consented or Shell is the caller.
    Dumpstate::RunStatus status = Dumpstate::RunStatus::OK;
    if (CalledByApi()) {
    if (CalledByApi() && !options_->is_consent_deferred) {
        status = CopyBugreportIfUserConsented(calling_uid);
        if (status != Dumpstate::RunStatus::OK &&
            status != Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT) {
@@ -3270,6 +3323,15 @@ void Dumpstate::MaybeSnapshotUiTraces() {
        return;
    }

    // Include the proto logging from WMShell.
    RunCommand(
        // Empty name because it's not intended to be classified as a bugreport section.
        // Actual logging files can be found as "/data/misc/wmtrace/shell_log.winscope"
        // in the bugreport.
        "", {"dumpsys", "activity", "service", "SystemUIService",
             "WMShell", "protolog", "save-for-bugreport"},
        CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build());

    // Currently WindowManagerService and InputMethodManagerSerivice support WinScope protocol.
    for (const auto& service : {"input_method", "window"}) {
        RunCommand(
@@ -3326,9 +3388,11 @@ void Dumpstate::onUiIntensiveBugreportDumpsFinished(int32_t calling_uid) {
}

void Dumpstate::MaybeCheckUserConsent(int32_t calling_uid, const std::string& calling_package) {
    if (multiuser_get_app_id(calling_uid) == AID_SHELL || !CalledByApi()) {
        // No need to get consent for shell triggered dumpstates, or not through
        // bugreporting API (i.e. no fd to copy back).
    if (multiuser_get_app_id(calling_uid) == AID_SHELL ||
        !CalledByApi() || options_->is_consent_deferred) {
        // No need to get consent for shell triggered dumpstates, or not
        // through bugreporting API (i.e. no fd to copy back), or when consent
        // is deferred.
        return;
    }
    consent_callback_ = new ConsentCallback();
Loading