Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Unified Diff: chrome/browser/android/data_usage/external_data_use_reporter.cc

Issue 2145863002: Separate data use reporting logic in ExternalDataUseObserver (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed nits Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/data_usage/external_data_use_reporter.cc
diff --git a/chrome/browser/android/data_usage/external_data_use_observer.cc b/chrome/browser/android/data_usage/external_data_use_reporter.cc
similarity index 51%
copy from chrome/browser/android/data_usage/external_data_use_observer.cc
copy to chrome/browser/android/data_usage/external_data_use_reporter.cc
index 36d3c860696f824c193bcb56a3c77f97804bc704..898a7cbe485388776e0531c15ae2837a965f9b03 100644
--- a/chrome/browser/android/data_usage/external_data_use_observer.cc
+++ b/chrome/browser/android/data_usage/external_data_use_reporter.cc
@@ -1,23 +1,19 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright 2016 The Chromium 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 "chrome/browser/android/data_usage/external_data_use_observer.h"
+#include "chrome/browser/android/data_usage/external_data_use_reporter.h"
#include <utility>
-#include "base/containers/hash_tables.h"
-#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_macros.h"
-#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
-#include "base/task_runner_util.h"
+#include "chrome/browser/android/data_usage/data_use_tab_model.h"
#include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h"
#include "components/data_usage/core/data_use.h"
#include "components/variations/variations_associated_data.h"
-#include "content/public/browser/browser_thread.h"
namespace chrome {
@@ -25,33 +21,41 @@ namespace android {
namespace {
+// Default duration after which a pending data use report is considered timed
+// out. May be overridden by the field trial.
+const int kDefaultDataUseReportSubmitTimeoutMsec = 60 * 2 * 1000; // 2 minutes.
+
+// Default value of the minimum number of bytes that should be buffered before
+// a data use report is submitted. May be overridden by the field trial.
+const int64_t kDefaultDataUseReportMinBytes = 100 * 1024; // 100 KB.
+
// Record the result of data use report submission. |bytes| is the sum of send
// and received bytes in the report.
void RecordDataUsageReportSubmission(
- ExternalDataUseObserver::DataUsageReportSubmissionResult result,
+ ExternalDataUseReporter::DataUsageReportSubmissionResult result,
int64_t bytes) {
DCHECK_LE(0, bytes);
UMA_HISTOGRAM_ENUMERATION(
"DataUsage.ReportSubmissionResult", result,
- ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_MAX);
+ ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_MAX);
// Cap to the maximum sample value.
const int32_t bytes_capped = bytes <= base::HistogramBase::kSampleType_MAX - 1
? bytes
: base::HistogramBase::kSampleType_MAX - 1;
switch (result) {
- case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL:
+ case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL:
UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Successful",
bytes_capped);
break;
- case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_FAILED:
+ case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_FAILED:
UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Failed",
bytes_capped);
break;
- case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT:
+ case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT:
UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.TimedOut",
bytes_capped);
break;
- case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_LOST:
+ case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_LOST:
UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Lost",
bytes_capped);
break;
@@ -61,40 +65,12 @@ void RecordDataUsageReportSubmission(
}
}
-// Default duration after which matching rules are periodically fetched. May be
-// overridden by the field trial.
-const int kDefaultFetchMatchingRulesDurationSeconds = 60 * 15; // 15 minutes.
-
-// Default duration after which a pending data use report is considered timed
-// out. May be overridden by the field trial.
-const int kDefaultDataUseReportSubmitTimeoutMsec = 60 * 2 * 1000; // 2 minutes.
-
-// Default value of the minimum number of bytes that should be buffered before
-// a data use report is submitted. May be overridden by the field trial.
-const int64_t kDefaultDataUseReportMinBytes = 100 * 1024; // 100 KB.
-
-// Populates various parameters from the values specified in the field trial.
-int32_t GetFetchMatchingRulesDurationSeconds() {
- int32_t duration_seconds = -1;
- const std::string variation_value = variations::GetVariationParamValue(
- chrome::android::ExternalDataUseObserver::
- kExternalDataUseObserverFieldTrial,
- "fetch_matching_rules_duration_seconds");
- if (!variation_value.empty() &&
- base::StringToInt(variation_value, &duration_seconds)) {
- DCHECK_LE(0, duration_seconds);
- return duration_seconds;
- }
- return kDefaultFetchMatchingRulesDurationSeconds;
-}
-
-// Populates various parameters from the values specified in the field trial.
-int32_t GetDataReportSubmitTimeoutMsec() {
+// Populates various parameters from the values specified in the field trial
+// |field_trial|.
+int32_t GetDataReportSubmitTimeoutMsec(const char* field_trial) {
int32_t duration_seconds = -1;
const std::string variation_value = variations::GetVariationParamValue(
- chrome::android::ExternalDataUseObserver::
- kExternalDataUseObserverFieldTrial,
- "data_report_submit_timeout_msec");
+ field_trial, "data_report_submit_timeout_msec");
if (!variation_value.empty() &&
base::StringToInt(variation_value, &duration_seconds)) {
DCHECK_LE(0, duration_seconds);
@@ -103,13 +79,12 @@ int32_t GetDataReportSubmitTimeoutMsec() {
return kDefaultDataUseReportSubmitTimeoutMsec;
}
-// Populates various parameters from the values specified in the field trial.
-int64_t GetMinBytes() {
+// Populates various parameters from the values specified in the field trial
+// |field_trial|.
+int64_t GetMinBytes(const char* field_trial) {
int64_t min_bytes = -1;
const std::string variation_value = variations::GetVariationParamValue(
- chrome::android::ExternalDataUseObserver::
- kExternalDataUseObserverFieldTrial,
- "data_use_report_min_bytes");
+ field_trial, "data_use_report_min_bytes");
if (!variation_value.empty() &&
base::StringToInt64(variation_value, &min_bytes)) {
DCHECK_LE(0, min_bytes);
@@ -121,79 +96,58 @@ int64_t GetMinBytes() {
} // namespace
// static
-const char ExternalDataUseObserver::kExternalDataUseObserverFieldTrial[] =
- "ExternalDataUseObserver";
-
-// static
-const size_t ExternalDataUseObserver::kMaxBufferSize = 100;
-
-ExternalDataUseObserver::ExternalDataUseObserver(
- data_usage::DataUseAggregator* data_use_aggregator,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
- const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
- : data_use_aggregator_(data_use_aggregator),
- external_data_use_observer_bridge_(new ExternalDataUseObserverBridge()),
- data_use_tab_model_(new DataUseTabModel()),
+const size_t ExternalDataUseReporter::kMaxBufferSize = 100;
+
+ExternalDataUseReporter::ExternalDataUseReporter(
+ const char* field_trial,
+ DataUseTabModel* data_use_tab_model,
+ ExternalDataUseObserverBridge* external_data_use_observer_bridge)
+ : external_data_use_observer_bridge_(external_data_use_observer_bridge),
+ data_use_tab_model_(data_use_tab_model),
last_data_report_submitted_ticks_(base::TimeTicks()),
pending_report_bytes_(0),
- ui_task_runner_(ui_task_runner),
previous_report_time_(base::Time::Now()),
- last_matching_rules_fetch_time_(base::TimeTicks::Now()),
total_bytes_buffered_(0),
- fetch_matching_rules_duration_(
- base::TimeDelta::FromSeconds(GetFetchMatchingRulesDurationSeconds())),
- data_use_report_min_bytes_(GetMinBytes()),
- data_report_submit_timeout_(
- base::TimeDelta::FromMilliseconds(GetDataReportSubmitTimeoutMsec())),
+ data_use_report_min_bytes_(GetMinBytes(field_trial)),
+ data_report_submit_timeout_(base::TimeDelta::FromMilliseconds(
+ GetDataReportSubmitTimeoutMsec(field_trial))) {
+ DCHECK(last_data_report_submitted_ticks_.is_null());
+ // Detach from current thread since rest of ExternalDataUseReporter lives on
+ // the UI thread and the current thread may not be UI thread..
+ thread_checker_.DetachFromThread();
+}
+
+void ExternalDataUseReporter::InitOnUIThread() {
+ DCHECK(thread_checker_.CalledOnValidThread());
#if defined(OS_ANDROID)
- app_state_listener_(new base::android::ApplicationStatusListener(
- base::Bind(&ExternalDataUseObserver::OnApplicationStateChange,
- base::Unretained(this)))),
+ app_state_listener_.reset(new base::android::ApplicationStatusListener(
+ base::Bind(&ExternalDataUseReporter::OnApplicationStateChange,
+ base::Unretained(this))));
#endif
- registered_as_data_use_observer_(false),
- weak_factory_(this) {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
- DCHECK(data_use_aggregator_);
- DCHECK(io_task_runner);
- DCHECK(ui_task_runner_);
- DCHECK(last_data_report_submitted_ticks_.is_null());
+}
- ui_task_runner_->PostTask(FROM_HERE,
- base::Bind(&DataUseTabModel::InitOnUIThread,
- base::Unretained(data_use_tab_model_),
- external_data_use_observer_bridge_));
-
- // Initialize the ExternalDataUseObserverBridge object. It is okay to use
- // base::Unretained here since |external_data_use_observer_bridge_| is owned
- // by |this|, and is destroyed on UI thread when |this| is destroyed.
- ui_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&ExternalDataUseObserverBridge::Init,
- base::Unretained(external_data_use_observer_bridge_),
- io_task_runner, GetWeakPtr(), data_use_tab_model_));
+ExternalDataUseReporter::~ExternalDataUseReporter() {
+ DCHECK(thread_checker_.CalledOnValidThread());
}
-ExternalDataUseObserver::~ExternalDataUseObserver() {
+void ExternalDataUseReporter::OnDataUse(const data_usage::DataUse& data_use) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (registered_as_data_use_observer_)
- data_use_aggregator_->RemoveObserver(this);
+ const base::Time now_time = base::Time::Now();
+ DataUseTabModel::TrackingInfo tracking_info;
- // Delete |data_use_tab_model_| on the UI thread. |data_use_tab_model_| should
- // be deleted before |external_data_use_observer_bridge_|.
- if (!ui_task_runner_->DeleteSoon(FROM_HERE, data_use_tab_model_)) {
- NOTIMPLEMENTED() << " DataUseTabModel was not deleted successfully";
+ if (!data_use_tab_model_->GetTrackingInfoForTabAtTime(
+ data_use.tab_id, data_use.request_start, &tracking_info)) {
+ return;
}
- // Delete |external_data_use_observer_bridge_| on the UI thread.
- if (!ui_task_runner_->DeleteSoon(FROM_HERE,
- external_data_use_observer_bridge_)) {
- NOTIMPLEMENTED()
- << " ExternalDataUseObserverBridge was not deleted successfully";
- }
+ BufferDataUseReport(data_use, tracking_info.label, tracking_info.tag,
+ previous_report_time_, now_time);
+ SubmitBufferedDataUseReport(false);
+ previous_report_time_ = now_time;
}
-void ExternalDataUseObserver::OnReportDataUseDone(bool success) {
+void ExternalDataUseReporter::OnReportDataUseDone(bool success) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!last_data_report_submitted_ticks_.is_null());
@@ -215,89 +169,20 @@ void ExternalDataUseObserver::OnReportDataUseDone(bool success) {
}
#if defined(OS_ANDROID)
-void ExternalDataUseObserver::OnApplicationStateChange(
+void ExternalDataUseReporter::OnApplicationStateChange(
base::android::ApplicationState new_state) {
DCHECK(thread_checker_.CalledOnValidThread());
+
+ // TODO(rajendrant): When Chromium is backgrounded, only one data use report
+ // is submitted since the external API only supports one pending report
+ // submission. Once the external API supports submitting multiple reports
+ // in one call, all reports should be submitted immediately.
if (new_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES)
SubmitBufferedDataUseReport(true);
}
#endif
-void ExternalDataUseObserver::OnDataUse(const data_usage::DataUse& data_use) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(registered_as_data_use_observer_);
-
- const base::TimeTicks now_ticks = base::TimeTicks::Now();
- const base::Time now_time = base::Time::Now();
-
- // If the time when the matching rules were last fetched is more than
- // |fetch_matching_rules_duration_|, fetch them again.
- if (now_ticks - last_matching_rules_fetch_time_ >=
- fetch_matching_rules_duration_) {
- FetchMatchingRules();
- }
-
- std::unique_ptr<DataUseTabModel::TrackingInfo> tracking_info(
- new DataUseTabModel::TrackingInfo());
-
- content::BrowserThread::PostTaskAndReplyWithResult(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(&DataUseTabModel::GetTrackingInfoForTabAtTime,
- base::Unretained(data_use_tab_model_), data_use.tab_id,
- data_use.request_start, tracking_info.get()),
- base::Bind(&ExternalDataUseObserver::DataUseTrackingInfoRetrieved,
- GetWeakPtr(), data_use, previous_report_time_, now_time,
- base::Owned(tracking_info.release())));
-
- previous_report_time_ = now_time;
-}
-
-void ExternalDataUseObserver::ShouldRegisterAsDataUseObserver(
- bool should_register) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (registered_as_data_use_observer_ == should_register)
- return;
-
- if (!registered_as_data_use_observer_ && should_register)
- data_use_aggregator_->AddObserver(this);
-
- if (registered_as_data_use_observer_ && !should_register)
- data_use_aggregator_->RemoveObserver(this);
-
- registered_as_data_use_observer_ = should_register;
-}
-
-void ExternalDataUseObserver::FetchMatchingRules() {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- last_matching_rules_fetch_time_ = base::TimeTicks::Now();
-
- // It is okay to use base::Unretained here since
- // |external_data_use_observer_bridge_| is owned by |this|, and is destroyed
- // on UI thread when |this| is destroyed.
- ui_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&ExternalDataUseObserverBridge::FetchMatchingRules,
- base::Unretained(external_data_use_observer_bridge_)));
-}
-
-void ExternalDataUseObserver::DataUseTrackingInfoRetrieved(
- const data_usage::DataUse& data_use,
- const base::Time& start_time,
- const base::Time& end_time,
- const DataUseTabModel::TrackingInfo* tracking_info,
- bool tracking_info_valid) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- if (!tracking_info_valid)
- return;
-
- BufferDataUseReport(data_use, tracking_info->label, tracking_info->tag,
- start_time, end_time);
- SubmitBufferedDataUseReport(false);
-}
-
-void ExternalDataUseObserver::BufferDataUseReport(
+void ExternalDataUseReporter::BufferDataUseReport(
const data_usage::DataUse& data_use,
const std::string& label,
const std::string& tag,
@@ -322,7 +207,8 @@ void ExternalDataUseObserver::BufferDataUseReport(
buffered_data_reports_.find(data_use_report_key);
if (it == buffered_data_reports_.end()) {
// Limit the buffer size.
- if (buffered_data_reports_.size() == kMaxBufferSize) {
+ if (buffered_data_reports_.size() ==
+ ExternalDataUseReporter::kMaxBufferSize) {
RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_LOST,
data_use.rx_bytes + data_use.tx_bytes);
return;
@@ -342,10 +228,11 @@ void ExternalDataUseObserver::BufferDataUseReport(
total_bytes_buffered_ += (data_use.rx_bytes + data_use.tx_bytes);
DCHECK_LT(0U, buffered_data_reports_.size());
- DCHECK_LE(buffered_data_reports_.size(), kMaxBufferSize);
+ DCHECK_LE(buffered_data_reports_.size(),
+ ExternalDataUseReporter::kMaxBufferSize);
}
-void ExternalDataUseObserver::SubmitBufferedDataUseReport(bool immediate) {
+void ExternalDataUseReporter::SubmitBufferedDataUseReport(bool immediate) {
DCHECK(thread_checker_.CalledOnValidThread());
const base::TimeTicks ticks_now = base::TimeTicks::Now();
@@ -386,29 +273,12 @@ void ExternalDataUseObserver::SubmitBufferedDataUseReport(bool immediate) {
buffered_data_reports_.erase(it);
total_bytes_buffered_ -= (report.bytes_downloaded + report.bytes_uploaded);
- // It is okay to use base::Unretained here since
- // |external_data_use_observer_bridge_| is owned by |this|, and is destroyed
- // on UI thread when |this| is destroyed.
- ui_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&ExternalDataUseObserverBridge::ReportDataUse,
- base::Unretained(external_data_use_observer_bridge_),
- key.label, key.tag, key.connection_type, key.mcc_mnc,
- report.start_time, report.end_time, report.bytes_downloaded,
- report.bytes_uploaded));
-}
-
-base::WeakPtr<ExternalDataUseObserver> ExternalDataUseObserver::GetWeakPtr() {
- DCHECK(thread_checker_.CalledOnValidThread());
- return weak_factory_.GetWeakPtr();
-}
-
-DataUseTabModel* ExternalDataUseObserver::GetDataUseTabModel() const {
- DCHECK(thread_checker_.CalledOnValidThread());
- return data_use_tab_model_;
+ external_data_use_observer_bridge_->ReportDataUse(
+ key.label, key.tag, key.connection_type, key.mcc_mnc, report.start_time,
+ report.end_time, report.bytes_downloaded, report.bytes_uploaded);
}
-ExternalDataUseObserver::DataUseReportKey::DataUseReportKey(
+ExternalDataUseReporter::DataUseReportKey::DataUseReportKey(
const std::string& label,
const std::string& tag,
net::NetworkChangeNotifier::ConnectionType connection_type,
@@ -418,17 +288,16 @@ ExternalDataUseObserver::DataUseReportKey::DataUseReportKey(
connection_type(connection_type),
mcc_mnc(mcc_mnc) {}
-ExternalDataUseObserver::DataUseReportKey::DataUseReportKey(
- const ExternalDataUseObserver::DataUseReportKey& other) =
- default;
+ExternalDataUseReporter::DataUseReportKey::DataUseReportKey(
+ const ExternalDataUseReporter::DataUseReportKey& other) = default;
-bool ExternalDataUseObserver::DataUseReportKey::operator==(
+bool ExternalDataUseReporter::DataUseReportKey::operator==(
const DataUseReportKey& other) const {
return label == other.label && tag == other.tag &&
connection_type == other.connection_type && mcc_mnc == other.mcc_mnc;
}
-ExternalDataUseObserver::DataUseReport::DataUseReport(
+ExternalDataUseReporter::DataUseReport::DataUseReport(
const base::Time& start_time,
const base::Time& end_time,
int64_t bytes_downloaded,
@@ -438,7 +307,7 @@ ExternalDataUseObserver::DataUseReport::DataUseReport(
bytes_downloaded(bytes_downloaded),
bytes_uploaded(bytes_uploaded) {}
-size_t ExternalDataUseObserver::DataUseReportKeyHash::operator()(
+size_t ExternalDataUseReporter::DataUseReportKeyHash::operator()(
const DataUseReportKey& k) const {
// The hash is computed by hashing individual variables and combining them
// using prime numbers. Prime numbers are used for multiplication because the

Powered by Google App Engine
This is Rietveld 408576698