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

Side by Side Diff: content/browser/time_zone_monitor_linux.cc

Issue 2353283002: [TimeZoneMonitor] Decouple //content/browser/time_zone_monitor* to //device/. (Closed)
Patch Set: Do not set output_name in gn Created 4 years, 2 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 | « content/browser/time_zone_monitor_chromeos.cc ('k') | content/browser/time_zone_monitor_mac.mm » ('j') | 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 2014 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 "content/browser/time_zone_monitor.h"
6
7 #include <stddef.h>
8 #include <stdlib.h>
9
10 #include <vector>
11
12 #include "base/bind.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_path_watcher.h"
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/sequenced_task_runner.h"
18 #include "base/stl_util.h"
19 #include "base/threading/thread_restrictions.h"
20 #include "base/threading/thread_task_runner_handle.h"
21 #include "build/build_config.h"
22
23 #if !defined(OS_CHROMEOS)
24
25 namespace content {
26
27 namespace {
28 class TimeZoneMonitorLinuxImpl;
29 } // namespace
30
31 class TimeZoneMonitorLinux : public TimeZoneMonitor {
32 public:
33 TimeZoneMonitorLinux(
34 scoped_refptr<base::SequencedTaskRunner> file_task_runner);
35 ~TimeZoneMonitorLinux() override;
36
37 void NotifyClientsFromImpl() { NotifyClients(); }
38
39 private:
40 scoped_refptr<TimeZoneMonitorLinuxImpl> impl_;
41
42 DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorLinux);
43 };
44
45 namespace {
46
47 // FilePathWatcher needs to run on the FILE thread, but TimeZoneMonitor runs
48 // on the UI thread. TimeZoneMonitorLinuxImpl is the bridge between these
49 // threads.
50 class TimeZoneMonitorLinuxImpl
51 : public base::RefCountedThreadSafe<TimeZoneMonitorLinuxImpl> {
52 public:
53 explicit TimeZoneMonitorLinuxImpl(
54 TimeZoneMonitorLinux* owner,
55 scoped_refptr<base::SequencedTaskRunner> file_task_runner)
56 : base::RefCountedThreadSafe<TimeZoneMonitorLinuxImpl>(),
57 file_path_watchers_(),
58 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
59 file_task_runner_(file_task_runner),
60 owner_(owner) {
61 DCHECK(main_task_runner_->RunsTasksOnCurrentThread());
62 file_task_runner_->PostTask(
63 FROM_HERE,
64 base::Bind(&TimeZoneMonitorLinuxImpl::StartWatchingOnFileThread, this));
65 }
66
67 void StopWatching() {
68 DCHECK(main_task_runner_->RunsTasksOnCurrentThread());
69 owner_ = NULL;
70 file_task_runner_->PostTask(
71 FROM_HERE,
72 base::Bind(&TimeZoneMonitorLinuxImpl::StopWatchingOnFileThread, this));
73 }
74
75 private:
76 friend class base::RefCountedThreadSafe<TimeZoneMonitorLinuxImpl>;
77
78 ~TimeZoneMonitorLinuxImpl() {
79 DCHECK(!owner_);
80 base::STLDeleteElements(&file_path_watchers_);
81 }
82
83 void StartWatchingOnFileThread() {
84 base::ThreadRestrictions::AssertIOAllowed();
85 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
86
87 // There is no true standard for where time zone information is actually
88 // stored. glibc uses /etc/localtime, uClibc uses /etc/TZ, and some older
89 // systems store the name of the time zone file within /usr/share/zoneinfo
90 // in /etc/timezone. Different libraries and custom builds may mean that
91 // still more paths are used. Just watch all three of these paths, because
92 // false positives are harmless, assuming the false positive rate is
93 // reasonable.
94 const char* const kFilesToWatch[] = {
95 "/etc/localtime",
96 "/etc/timezone",
97 "/etc/TZ",
98 };
99
100 for (size_t index = 0; index < arraysize(kFilesToWatch); ++index) {
101 file_path_watchers_.push_back(new base::FilePathWatcher());
102 file_path_watchers_.back()->Watch(
103 base::FilePath(kFilesToWatch[index]),
104 false,
105 base::Bind(&TimeZoneMonitorLinuxImpl::OnTimeZoneFileChanged, this));
106 }
107 }
108
109 void StopWatchingOnFileThread() {
110 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
111 base::STLDeleteElements(&file_path_watchers_);
112 }
113
114 void OnTimeZoneFileChanged(const base::FilePath& path, bool error) {
115 DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
116 main_task_runner_->PostTask(
117 FROM_HERE,
118 base::Bind(&TimeZoneMonitorLinuxImpl::OnTimeZoneFileChangedOnUIThread,
119 this));
120 }
121
122 void OnTimeZoneFileChangedOnUIThread() {
123 DCHECK(main_task_runner_->RunsTasksOnCurrentThread());
124 if (owner_) {
125 owner_->NotifyClientsFromImpl();
126 }
127 }
128
129 std::vector<base::FilePathWatcher*> file_path_watchers_;
130
131 scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
132 scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
133 TimeZoneMonitorLinux* owner_;
134
135 DISALLOW_COPY_AND_ASSIGN(TimeZoneMonitorLinuxImpl);
136 };
137
138 } // namespace
139
140 TimeZoneMonitorLinux::TimeZoneMonitorLinux(
141 scoped_refptr<base::SequencedTaskRunner> file_task_runner)
142 : TimeZoneMonitor(), impl_() {
143 // If the TZ environment variable is set, its value specifies the time zone
144 // specification, and it's pointless to monitor any files in /etc for
145 // changes because such changes would have no effect on the TZ environment
146 // variable and thus the interpretation of the local time zone in the
147 // or renderer processes.
148 //
149 // The system-specific format for the TZ environment variable beginning with
150 // a colon is implemented by glibc as the path to a time zone data file, and
151 // it would be possible to monitor this file for changes if a TZ variable of
152 // this format was encountered, but this is not necessary: when loading a
153 // time zone specification in this way, glibc does not reload the file when
154 // it changes, so it's pointless to respond to a notification that it has
155 // changed.
156 if (!getenv("TZ")) {
157 impl_ = new TimeZoneMonitorLinuxImpl(this, file_task_runner);
158 }
159 }
160
161 TimeZoneMonitorLinux::~TimeZoneMonitorLinux() {
162 if (impl_.get()) {
163 impl_->StopWatching();
164 }
165 }
166
167 // static
168 std::unique_ptr<TimeZoneMonitor> TimeZoneMonitor::Create(
169 scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
170 return std::unique_ptr<TimeZoneMonitor>(
171 new TimeZoneMonitorLinux(file_task_runner));
172 }
173
174 } // namespace content
175
176 #endif // !OS_CHROMEOS
OLDNEW
« no previous file with comments | « content/browser/time_zone_monitor_chromeos.cc ('k') | content/browser/time_zone_monitor_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698