blob: 269f4a83025b64546087eb6d4c7624f2edf1473b [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/forensics/crash_reports/reporting_policy_watcher.h"
#include <lib/syslog/cpp/macros.h>
namespace forensics {
namespace crash_reports {
std::string ToString(const ReportingPolicy policy) {
switch (policy) {
case ReportingPolicy::kUndecided:
return "UNDECIDED";
case ReportingPolicy::kArchive:
return "ARCHIVE";
case ReportingPolicy::kDoNotFileAndDelete:
return "DO_NOT_FILE_AND_DELETE";
case ReportingPolicy::kUpload:
return "UPLOAD";
}
}
ReportingPolicyWatcher::ReportingPolicyWatcher(const ReportingPolicy policy) : policy_(policy) {}
void ReportingPolicyWatcher::OnPolicyChange(::fit::function<void(ReportingPolicy)> on_change) {
callbacks_.push_back(std::move(on_change));
}
void ReportingPolicyWatcher::SetPolicy(const ReportingPolicy policy) {
if (policy_ == policy) {
return;
}
FX_LOGS(INFO) << "Reporting policy changed from " << ToString(policy_) << " to "
<< ToString(policy);
policy_ = policy;
for (const auto& on_change : callbacks_) {
on_change(policy_);
}
}
UserReportingPolicyWatcher::UserReportingPolicyWatcher(
async_dispatcher_t* dispatcher, std::shared_ptr<sys::ServiceDirectory> services)
: ReportingPolicyWatcher(ReportingPolicy::kUndecided),
dispatcher_(dispatcher),
services_(std::move(services)),
watch_backoff_(/*initial_delay=*/zx::min(1), /*retry_factor=*/2u, /*max_delay=*/zx::hour(1)) {
privacy_settings_.set_error_handler([this](const zx_status_t status) {
FX_PLOGS(WARNING, status) << "Lost connection to fuchsia.settings.Privacy";
SetPolicy(ReportingPolicy::kUndecided);
watch_task_.PostDelayed(dispatcher_, watch_backoff_.GetNext());
});
Watch();
}
void UserReportingPolicyWatcher::Watch() {
if (!privacy_settings_.is_bound()) {
services_->Connect(privacy_settings_.NewRequest());
}
privacy_settings_->Watch([this](const fuchsia::settings::PrivacySettings settings) {
watch_backoff_.Reset();
if (!settings.has_user_data_sharing_consent()) {
SetPolicy(ReportingPolicy::kUndecided);
} else if (settings.user_data_sharing_consent()) {
SetPolicy(ReportingPolicy::kUpload);
} else {
SetPolicy(ReportingPolicy::kDoNotFileAndDelete);
}
// Watch for the next update, following the hanging-get pattern.
Watch();
});
}
} // namespace crash_reports
} // namespace forensics