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

Side by Side Diff: chrome/browser/data_usage/tab_id_provider.cc

Issue 1421983002: Include tab IDs when reporting data use accounting. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@data_use_scoped_vector
Patch Set: Fixed external_data_use_observer test Created 5 years, 1 month 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/data_usage/tab_id_provider.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/task_runner.h"
16 #include "base/task_runner_util.h"
17
18 namespace chrome_browser_data_usage {
19
20 namespace {
21
22 // Convenience typedefs for clarity.
23 typedef base::Callback<int32_t(void)> TabIdGetter;
24 typedef base::Callback<void(int32_t)> TabIdCallback;
25
26 } // namespace
27
28 // Object that can run a list of callbacks that take tab IDs. New callbacks
29 // can only be added before it starts running the callbacks. Callbacks added
30 // will each be run exactly once.
31 class TabIdProvider::CallbackRunner {
32 public:
33 CallbackRunner() : is_done_(false), weak_ptr_factory_(this) {}
34
35 ~CallbackRunner() {
36 // Ensure that no callbacks are abandoned without being run.
37 if (!is_done_)
38 RunAll(-1);
39 }
40
41 // Adds a new callback to be run later. New callbacks must not be added after
42 // RunAll has been called.
43 void AddCallback(const TabIdCallback& callback) {
44 DCHECK(thread_checker_.CalledOnValidThread());
45 DCHECK(!is_done_);
46 callbacks_.push_back(callback);
47 }
48
49 // Runs all the callbacks in the order that they were added. This method must
50 // not be called more than once.
51 void RunAll(int32_t tab_id) {
52 DCHECK(thread_checker_.CalledOnValidThread());
53 DCHECK(!is_done_);
54 is_done_ = true;
55 // It's safe to run the |callbacks_| while iterating through them because
56 // |callbacks_| can no longer be modified at this point, so it's impossible
57 // for one of the |callbacks_| to add more callbacks to this CallbackRunner.
58 for (const auto& callback : callbacks_)
59 callback.Run(tab_id);
60 callbacks_.clear();
61 }
62
63 base::WeakPtr<CallbackRunner> GetWeakPtr() {
64 DCHECK(thread_checker_.CalledOnValidThread());
65 return weak_ptr_factory_.GetWeakPtr();
66 }
67
68 private:
69 base::ThreadChecker thread_checker_;
70 bool is_done_;
71 std::vector<TabIdCallback> callbacks_;
72 base::WeakPtrFactory<CallbackRunner> weak_ptr_factory_;
73
74 DISALLOW_COPY_AND_ASSIGN(CallbackRunner);
75 };
76
77 TabIdProvider::TabIdProvider(base::TaskRunner* task_runner,
78 const tracked_objects::Location& from_here,
79 const TabIdGetter& tab_id_getter)
80 : is_tab_id_ready_(false), tab_id_(-1), weak_ptr_factory_(this) {
81 scoped_ptr<CallbackRunner> callback_runner(new CallbackRunner());
82 weak_callback_runner_ = callback_runner->GetWeakPtr();
83 callback_runner->AddCallback(
84 base::Bind(&TabIdProvider::OnTabIdReady, GetWeakPtr()));
85
86 // The posted task takes ownership of |callback_runner|. If the task fails to
87 // be posted, then the destructor of |callback_runner| will pass a tab ID of
88 // -1 to OnTabIdReady, so that case doesn't need to be explicitly handled
89 // here.
90 base::PostTaskAndReplyWithResult(
91 task_runner, from_here, tab_id_getter,
92 base::Bind(&CallbackRunner::RunAll,
93 base::Owned(callback_runner.release())));
94 }
95
96 TabIdProvider::~TabIdProvider() {}
97
98 void TabIdProvider::ProvideTabId(const TabIdCallback& callback) {
99 DCHECK(thread_checker_.CalledOnValidThread());
100 if (is_tab_id_ready_) {
101 callback.Run(tab_id_);
102 return;
103 }
104 if (weak_callback_runner_) {
105 weak_callback_runner_->AddCallback(callback);
106 return;
107 }
108 // If no cached tab ID is available and |weak_callback_runner_| has been
109 // destroyed, pass a tab ID of -1 to the callback indicating that no tab was
110 // found.
111 callback.Run(-1);
112 }
113
114 base::WeakPtr<TabIdProvider> TabIdProvider::GetWeakPtr() {
115 DCHECK(thread_checker_.CalledOnValidThread());
116 return weak_ptr_factory_.GetWeakPtr();
117 }
118
119 // static
120 const void* TabIdProvider::kUserDataKey =
121 static_cast<void*>(&TabIdProvider::kUserDataKey);
122
123 void TabIdProvider::OnTabIdReady(int32_t tab_id) {
124 DCHECK(thread_checker_.CalledOnValidThread());
125 DCHECK(!is_tab_id_ready_);
126 tab_id_ = tab_id;
127 is_tab_id_ready_ = true;
128 }
129
130 } // namespace chrome_browser_data_usage
OLDNEW
« no previous file with comments | « chrome/browser/data_usage/tab_id_provider.h ('k') | chrome/browser/data_usage/tab_id_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698