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

Side by Side Diff: chromeos/dbus/metronome_client.cc

Issue 935933002: Adds metronome time sync dbus client (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adds a command line flag to use a timer-based fake implementation Created 5 years, 9 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 unified diff | Download patch
« no previous file with comments | « chromeos/dbus/metronome_client.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "chromeos/dbus/metronome_client.h"
6
7 #include "base/bind.h"
8 #include "base/rand_util.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/observer_list.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
15 #include "chromeos/chromeos_switches.h"
16 #include "dbus/bus.h"
17 #include "dbus/message.h"
18 #include "dbus/object_path.h"
19 #include "dbus/object_proxy.h"
20
21 // TODO(benchan): Move these DBus constants to system_api.
22 namespace metronome {
23
24 const char kMetronomeInterface[] = "org.chromium.Metronome";
25 const char kMetronomeServiceName[] = "org.chromium.Metronome";
26 const char kMetronomeServicePath[] = "/org/chromium/Metronome";
27 const char kTimestampUpdatedSignal[] = "TimestampUpdated";
28
29 } // namespace metronome
30
31 namespace chromeos {
32
33 namespace {
34
35 ////////////////////////////////////////////////////////////////////////////////
36
37 // The MetronomeClient implementation.
38 class MetronomeClientImpl : public MetronomeClient {
39 public:
40 MetronomeClientImpl()
41 : proxy_(nullptr), signal_connected_(false), weak_ptr_factory_(this) {}
42
43 ~MetronomeClientImpl() override {}
44
45 // MetronomeClient:
46 void AddObserver(Observer* observer) override;
47 void RemoveObserver(Observer* observer) override;
48
49 protected:
50 // DBusClient:
51 void Init(dbus::Bus* bus) override;
52
53 private:
54 // Handles TimestampUpdated signal and notifies |observers_|.
55 void OnTimestampUpdated(dbus::Signal* signal);
56
57 // Handles the result of signal connection setup.
58 void OnSignalConnected(const std::string& interface,
59 const std::string& signal,
60 bool succeeded);
61
62 dbus::ObjectProxy* proxy_;
63
64 // True when |proxy_| has been connected.
65 bool signal_connected_;
66
67 // List of observers interested in event notifications from us.
68 ObserverList<Observer> observers_;
69
70 // Note: This should remain the last member so it'll be destroyed and
71 // invalidate its weak pointers before any other members are destroyed.
72 base::WeakPtrFactory<MetronomeClientImpl> weak_ptr_factory_;
73
74 DISALLOW_COPY_AND_ASSIGN(MetronomeClientImpl);
75 };
76
77 void MetronomeClientImpl::AddObserver(Observer* observer) {
78 DCHECK(observer);
79 if (!signal_connected_) {
80 signal_connected_ = true;
81 proxy_->ConnectToSignal(metronome::kMetronomeInterface,
82 metronome::kTimestampUpdatedSignal,
83 base::Bind(&MetronomeClientImpl::OnTimestampUpdated,
84 weak_ptr_factory_.GetWeakPtr()),
85 base::Bind(&MetronomeClientImpl::OnSignalConnected,
86 weak_ptr_factory_.GetWeakPtr()));
87 }
88 observers_.AddObserver(observer);
89 }
90
91 void MetronomeClientImpl::RemoveObserver(Observer* observer) {
92 DCHECK(observer);
93 observers_.RemoveObserver(observer);
94 }
95
96 void MetronomeClientImpl::Init(dbus::Bus* bus) {
97 proxy_ =
98 bus->GetObjectProxy(metronome::kMetronomeServiceName,
99 dbus::ObjectPath(metronome::kMetronomeServicePath));
100 }
101
102 void MetronomeClientImpl::OnTimestampUpdated(dbus::Signal* signal) {
103 dbus::MessageReader reader(signal);
104 uint64 beacon_timestamp = 0;
105 uint64 local_timestamp = 0;
106 if (!reader.PopUint64(&beacon_timestamp) ||
107 !reader.PopUint64(&local_timestamp)) {
108 LOG(ERROR) << "Invalid signal: " << signal->ToString();
109 return;
110 }
111 FOR_EACH_OBSERVER(Observer, observers_,
112 OnTimestampUpdated(beacon_timestamp, local_timestamp));
113 }
114
115 void MetronomeClientImpl::OnSignalConnected(const std::string& interface,
116 const std::string& signal,
117 bool succeeded) {
118 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " << signal
119 << " failed.";
120 }
121
122 ////////////////////////////////////////////////////////////////////////////////
123
124 // A fake implementation of MetronomeClient. It does not provide true
125 // synchronization and only exists to exercise the interfaces.
126 class MetronomeClientFakeImpl : public MetronomeClient {
127 public:
128 MetronomeClientFakeImpl()
129 : random_offset_(base::RandInt(-1000000, 1000000)) {}
130
131 ~MetronomeClientFakeImpl() override { beacon_timer_.Stop(); }
132
133 // MetronomeClient:
134 void AddObserver(Observer* observer) override {
135 DCHECK(observer);
136 observers_.AddObserver(observer);
137 }
138
139 void RemoveObserver(Observer* observer) override {
140 DCHECK(observer);
141 observers_.RemoveObserver(observer);
142 }
143
144 // DBusClient:
145 void Init(dbus::Bus* bus) override {
146 beacon_timer_.Start(FROM_HERE,
147 base::TimeDelta::FromMilliseconds(1000),
148 this,
149 &MetronomeClientFakeImpl::UpdateBeacon);
150 }
151
152 private:
153 void UpdateBeacon() {
154 base::Time now_time = base::Time::Now();
155 base::TimeTicks now_ticks = base::TimeTicks::Now();
156 uint64 fake_beacon_timestamp = now_time.ToInternalValue() +
157 base::RandInt(-1000, 1000);
158 uint64 fake_local_timestamp = now_ticks.ToInternalValue() + random_offset_ +
159 base::RandInt(-1000, 1000);
160 FOR_EACH_OBSERVER(
161 Observer, observers_,
162 OnTimestampUpdated(fake_beacon_timestamp, fake_local_timestamp));
163 }
164
165 int64 random_offset_;
166 base::RepeatingTimer<MetronomeClientFakeImpl> beacon_timer_;
167
168 // List of observers interested in event notifications from us.
169 ObserverList<Observer> observers_;
170
171 DISALLOW_COPY_AND_ASSIGN(MetronomeClientFakeImpl);
172 };
173
174 ////////////////////////////////////////////////////////////////////////////////
175
176 // A stub implementation of MetronomeClient. It allows unit tests to complete.
177 class MetronomeClientStubImpl : public MetronomeClient {
178 public:
179 MetronomeClientStubImpl() {}
180 ~MetronomeClientStubImpl() override {}
181
182 // MetronomeClient:
183 void AddObserver(Observer* observer) override {}
184 void RemoveObserver(Observer* observer) override {}
185
186 // DBusClient:
187 void Init(dbus::Bus* bus) override {}
188
189 private:
190 DISALLOW_COPY_AND_ASSIGN(MetronomeClientStubImpl);
191 };
192
193 } // namespace
194
195 ////////////////////////////////////////////////////////////////////////////////
196
197 MetronomeClient::MetronomeClient() {
198 }
199
200 MetronomeClient::~MetronomeClient() {
201 }
202
203 // static
204 MetronomeClient* MetronomeClient::Create(DBusClientImplementationType type) {
205 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
206 return new MetronomeClientImpl();
207 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
208
209 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
210 switches::kTestMetronomeTimer)) {
211 return new MetronomeClientFakeImpl();
212 }
213 return new MetronomeClientStubImpl();
214 }
215
216 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/dbus/metronome_client.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698