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

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 comments, moved unittests 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 54%
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..f57dd5048c7f982a2576819435f7ff2ecab33706 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,20 @@
-// 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.h"
tbansal1 2016/07/15 16:26:30 why is the include to e_d_u_o needed? If it is onl
Raj 2016/07/15 18:54:41 Done.
#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 +22,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,33 +66,6 @@ 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() {
int32_t duration_seconds = -1;
@@ -121,79 +99,53 @@ int64_t GetMinBytes() {
} // namespace
// static
-const char ExternalDataUseObserver::kExternalDataUseObserverFieldTrial[] =
- "ExternalDataUseObserver";
+const size_t ExternalDataUseReporter::kMaxBufferSize = 100;
-// 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()),
+ExternalDataUseReporter::ExternalDataUseReporter(
+ 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),
+#if defined(OS_ANDROID)
+ app_state_listener_(new base::android::ApplicationStatusListener(
+ base::Bind(&ExternalDataUseReporter::OnApplicationStateChange,
+ base::Unretained(this)))),
+#endif
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())),
-#if defined(OS_ANDROID)
- app_state_listener_(new base::android::ApplicationStatusListener(
- base::Bind(&ExternalDataUseObserver::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_);
+ base::TimeDelta::FromMilliseconds(GetDataReportSubmitTimeoutMsec())) {
DCHECK(last_data_report_submitted_ticks_.is_null());
+ // Detach from current thread since rest of DataUseTabModel lives on the UI
+ // thread and the current thread may not be UI thread..
+ thread_checker_.DetachFromThread();
+}
- 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 +167,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 +205,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 +226,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 +271,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 +286,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 +305,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