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

Side by Side Diff: chrome/browser/chromeos/network_message_observer.cc

Issue 10407080: Add NetworkNotificationView to tray_network. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Set id string, icon, title in NetworkMessageNotification constructor Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/chromeos/network_message_observer.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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/network_message_observer.h" 5 #include "chrome/browser/chromeos/network_message_observer.h"
6 6
7 #include "ash/ash_switches.h"
7 #include "ash/shell.h" 8 #include "ash/shell.h"
8 #include "ash/shell_delegate.h" 9 #include "ash/shell_delegate.h"
10 #include "ash/system/network/network_observer.h"
11 #include "ash/system/tray/system_tray.h"
9 #include "base/bind.h" 12 #include "base/bind.h"
10 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/command_line.h"
11 #include "base/stl_util.h" 15 #include "base/stl_util.h"
12 #include "base/string_number_conversions.h" 16 #include "base/string_number_conversions.h"
13 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
14 #include "chrome/browser/chromeos/cros/cros_library.h" 18 #include "chrome/browser/chromeos/cros/cros_library.h"
15 #include "chrome/browser/chromeos/cros/network_library.h" 19 #include "chrome/browser/chromeos/cros/network_library.h"
16 #include "chrome/browser/chromeos/notifications/balloon_view_host_chromeos.h" 20 #include "chrome/browser/chromeos/notifications/balloon_view_host_chromeos.h"
21 #include "chrome/browser/chromeos/notifications/system_notification.h"
17 #include "chrome/browser/prefs/pref_service.h" 22 #include "chrome/browser/prefs/pref_service.h"
18 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/profiles/profile_manager.h" 24 #include "chrome/browser/profiles/profile_manager.h"
20 #include "chrome/browser/ui/browser.h" 25 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_finder.h" 26 #include "chrome/browser/ui/browser_finder.h"
22 #include "chrome/common/pref_names.h" 27 #include "chrome/common/pref_names.h"
23 #include "chrome/common/time_format.h" 28 #include "chrome/common/time_format.h"
24 #include "grit/generated_resources.h" 29 #include "grit/generated_resources.h"
25 #include "grit/theme_resources.h" 30 #include "grit/theme_resources.h"
26 #include "ui/base/l10n/l10n_util.h" 31 #include "ui/base/l10n/l10n_util.h"
27 32
28 namespace { 33 namespace {
29 34
30 // Returns prefs::kShowPlanNotifications in the profile of the last active 35 // Returns prefs::kShowPlanNotifications in the profile of the last active
31 // browser. If there is no active browser, returns true. 36 // browser. If there is no active browser, returns true.
32 bool ShouldShowMobilePlanNotifications() { 37 bool ShouldShowMobilePlanNotifications() {
33 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord(); 38 Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
34 PrefService* prefs = profile->GetPrefs(); 39 PrefService* prefs = profile->GetPrefs();
35 return prefs->GetBoolean(prefs::kShowPlanNotifications); 40 return prefs->GetBoolean(prefs::kShowPlanNotifications);
36 } 41 }
37 42
38 } // namespace 43 } // namespace
39 44
40 namespace chromeos { 45 namespace chromeos {
41 46
42 NetworkMessageObserver::NetworkMessageObserver(Profile* profile) 47 class NetworkMessageNotification : public ash::NetworkTrayDelegate {
43 : notification_connection_error_(profile, "network_connection.chromeos", 48 public:
44 IDR_NOTIFICATION_NETWORK_FAILED, 49 NetworkMessageNotification(Profile* profile,
45 l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE)), 50 ash::NetworkObserver::ErrorType error_type)
46 notification_low_data_(profile, "network_low_data.chromeos", 51 : error_type_(error_type) {
47 IDR_NOTIFICATION_BARS_CRITICAL, 52 std::string id;
48 l10n_util::GetStringUTF16(IDS_NETWORK_LOW_DATA_TITLE)), 53 int icon_id = 0;
49 notification_no_data_(profile, "network_no_data.chromeos", 54 switch (error_type) {
50 IDR_NOTIFICATION_BARS_EMPTY, 55 case ash::NetworkObserver::ERROR_CONNECT_FAILED:
51 l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE)) { 56 id = "network_connection.chromeos";
57 icon_id = IDR_NOTIFICATION_NETWORK_FAILED;
58 title_ = l10n_util::GetStringUTF16(IDS_NETWORK_CONNECTION_ERROR_TITLE);
59 break;
60 case ash::NetworkObserver::ERROR_DATA_LOW:
61 id = "network_low_data.chromeos";
62 icon_id = IDR_NOTIFICATION_BARS_CRITICAL;
63 title_ = l10n_util::GetStringUTF16(IDS_NETWORK_LOW_DATA_TITLE);
64 break;
65 case ash::NetworkObserver::ERROR_DATA_NONE:
66 id = "network_no_data.chromeos";
67 icon_id = IDR_NOTIFICATION_BARS_EMPTY;
68 title_ = l10n_util::GetStringUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE);
69 break;
70 default:
71 NOTREACHED();
Greg Spencer (Chromium) 2012/05/23 19:00:28 Wouldn't you want to move this NOTREACHED() outsid
stevenjb 2012/05/23 19:21:52 Yes, good point. Fixed.
72 }
73 if (!CommandLine::ForCurrentProcess()->HasSwitch(
74 ash::switches::kAshNotify) && !id.empty()) {
75 system_notification_.reset(
76 new SystemNotification(profile, id, icon_id, title_));
77 }
78 }
79
80 // Overridden from ash::NetworkTrayDelegate:
81 virtual void NotificationLinkClicked() {
82 base::ListValue empty_value;
83 if (!callback_.is_null())
84 callback_.Run(&empty_value);
85 }
86
87 void Hide() {
88 if (system_notification_.get()) {
89 system_notification_->Hide();
90 } else {
91 ash::Shell::GetInstance()->tray()->network_observer()->
92 ClearNetworkError(error_type_);
93 }
94 }
95
96 void SetTitle(const string16& title) {
97 title_ = title;
98 if (system_notification_.get()) {
99 system_notification_->set_title(title);
100 }
101 }
102
103 void Show(const string16& message,
104 const string16& link_text,
105 const BalloonViewHost::MessageCallback& callback,
106 bool urgent, bool sticky) {
107 if (system_notification_.get()) {
108 system_notification_->Show(message, link_text, callback, urgent, sticky);
109 } else {
110 callback_ = callback;
111 ash::Shell::GetInstance()->tray()->network_observer()->
112 SetNetworkError(this, error_type_, title_, message, link_text);
113 }
114 }
115
116 void ShowAlways(const string16& message,
117 const string16& link_text,
118 const BalloonViewHost::MessageCallback& callback,
119 bool urgent, bool sticky) {
120 if (system_notification_.get()) {
121 // Hide if already shown to force show it in case user has closed it.
122 if (system_notification_->visible())
123 system_notification_->Hide();
124 }
125 Show(message, link_text, callback, urgent, sticky);
126 }
127
128 private:
129 string16 title_;
130 scoped_ptr<SystemNotification> system_notification_;
131 ash::NetworkObserver::ErrorType error_type_;
132 BalloonViewHost::MessageCallback callback_;
133 };
134
135 NetworkMessageObserver::NetworkMessageObserver(Profile* profile) {
136 notification_connection_error_.reset(
137 new NetworkMessageNotification(
138 profile, ash::NetworkObserver::ERROR_CONNECT_FAILED));
139 notification_low_data_.reset(
140 new NetworkMessageNotification(
141 profile,
142 ash::NetworkObserver::ERROR_DATA_LOW));
143 notification_no_data_.reset(
144 new NetworkMessageNotification(
145 profile,
146 ash::NetworkObserver::ERROR_DATA_NONE));
52 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); 147 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary();
53 OnNetworkManagerChanged(netlib); 148 OnNetworkManagerChanged(netlib);
54 // Note that this gets added as a NetworkManagerObserver, 149 // Note that this gets added as a NetworkManagerObserver,
55 // CellularDataPlanObserver, and UserActionObserver in 150 // CellularDataPlanObserver, and UserActionObserver in
56 // startup_browser_creator.cc 151 // startup_browser_creator.cc
57 } 152 }
58 153
59 NetworkMessageObserver::~NetworkMessageObserver() { 154 NetworkMessageObserver::~NetworkMessageObserver() {
60 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary(); 155 NetworkLibrary* netlib = CrosLibrary::Get()->GetNetworkLibrary();
61 netlib->RemoveNetworkManagerObserver(this); 156 netlib->RemoveNetworkManagerObserver(this);
62 netlib->RemoveCellularDataPlanObserver(this); 157 netlib->RemoveCellularDataPlanObserver(this);
63 netlib->RemoveUserActionObserver(this); 158 netlib->RemoveUserActionObserver(this);
64 notification_connection_error_.Hide(); 159 notification_connection_error_->Hide();
65 notification_low_data_.Hide(); 160 notification_low_data_->Hide();
66 notification_no_data_.Hide(); 161 notification_no_data_->Hide();
67 } 162 }
68 163
69 // static 164 // static
70 bool NetworkMessageObserver::IsApplicableBackupPlan( 165 bool NetworkMessageObserver::IsApplicableBackupPlan(
71 const CellularDataPlan* plan, const CellularDataPlan* other_plan) { 166 const CellularDataPlan* plan, const CellularDataPlan* other_plan) {
72 // By applicable plan, we mean that the other plan has data AND the timeframe 167 // By applicable plan, we mean that the other plan has data AND the timeframe
73 // will apply: (unlimited OR used bytes < max bytes) AND 168 // will apply: (unlimited OR used bytes < max bytes) AND
74 // ((start time - 1 sec) <= end time of currently active plan). 169 // ((start time - 1 sec) <= end time of currently active plan).
75 // In other words, there is data available and there is no gap of more than a 170 // In other words, there is data available and there is no gap of more than a
76 // second in time between the old plan and the new plan. 171 // second in time between the old plan and the new plan.
(...skipping 13 matching lines...) Expand all
90 ProfileManager::GetDefaultProfileOrOffTheRecord()); 185 ProfileManager::GetDefaultProfileOrOffTheRecord());
91 chromeos::NetworkLibrary* lib = 186 chromeos::NetworkLibrary* lib =
92 chromeos::CrosLibrary::Get()->GetNetworkLibrary(); 187 chromeos::CrosLibrary::Get()->GetNetworkLibrary();
93 const chromeos::CellularNetwork* cellular = lib->cellular_network(); 188 const chromeos::CellularNetwork* cellular = lib->cellular_network();
94 if (!cellular) 189 if (!cellular)
95 return; 190 return;
96 browser->ShowSingletonTab(GURL(cellular->payment_url())); 191 browser->ShowSingletonTab(GURL(cellular->payment_url()));
97 } 192 }
98 193
99 void NetworkMessageObserver::InitNewPlan(const CellularDataPlan* plan) { 194 void NetworkMessageObserver::InitNewPlan(const CellularDataPlan* plan) {
100 notification_low_data_.Hide(); 195 notification_low_data_->Hide();
101 notification_no_data_.Hide(); 196 notification_no_data_->Hide();
102 if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { 197 if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) {
103 notification_no_data_.set_title( 198 notification_no_data_->SetTitle(
104 l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_EXPIRED_TITLE, 199 l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_EXPIRED_TITLE,
105 ASCIIToUTF16(plan->plan_name))); 200 ASCIIToUTF16(plan->plan_name)));
106 notification_low_data_.set_title( 201 notification_low_data_->SetTitle(
107 l10n_util::GetStringFUTF16(IDS_NETWORK_NEARING_EXPIRATION_TITLE, 202 l10n_util::GetStringFUTF16(IDS_NETWORK_NEARING_EXPIRATION_TITLE,
108 ASCIIToUTF16(plan->plan_name))); 203 ASCIIToUTF16(plan->plan_name)));
109 } else { 204 } else {
110 notification_no_data_.set_title( 205 notification_no_data_->SetTitle(
111 l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE, 206 l10n_util::GetStringFUTF16(IDS_NETWORK_OUT_OF_DATA_TITLE,
112 ASCIIToUTF16(plan->plan_name))); 207 ASCIIToUTF16(plan->plan_name)));
113 notification_low_data_.set_title( 208 notification_low_data_->SetTitle(
114 l10n_util::GetStringFUTF16(IDS_NETWORK_LOW_DATA_TITLE, 209 l10n_util::GetStringFUTF16(IDS_NETWORK_LOW_DATA_TITLE,
115 ASCIIToUTF16(plan->plan_name))); 210 ASCIIToUTF16(plan->plan_name)));
116 } 211 }
117 } 212 }
118 213
119 void NetworkMessageObserver::ShowNeedsPlanNotification( 214 void NetworkMessageObserver::ShowNeedsPlanNotification(
120 const CellularNetwork* cellular) { 215 const CellularNetwork* cellular) {
121 notification_no_data_.set_title( 216 notification_no_data_->SetTitle(
122 l10n_util::GetStringFUTF16(IDS_NETWORK_NO_DATA_PLAN_TITLE, 217 l10n_util::GetStringFUTF16(IDS_NETWORK_NO_DATA_PLAN_TITLE,
123 UTF8ToUTF16(cellular->name()))); 218 UTF8ToUTF16(cellular->name())));
124 notification_no_data_.Show( 219 notification_no_data_->Show(
125 l10n_util::GetStringFUTF16( 220 l10n_util::GetStringFUTF16(
126 IDS_NETWORK_NO_DATA_PLAN_MESSAGE, 221 IDS_NETWORK_NO_DATA_PLAN_MESSAGE,
127 UTF8ToUTF16(cellular->name())), 222 UTF8ToUTF16(cellular->name())),
128 l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE), 223 l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE),
129 base::Bind(&NetworkMessageObserver::OpenMobileSetupPage, AsWeakPtr()), 224 base::Bind(&NetworkMessageObserver::OpenMobileSetupPage, AsWeakPtr()),
130 false, false); 225 false, false);
131 } 226 }
132 227
133 void NetworkMessageObserver::ShowNoDataNotification( 228 void NetworkMessageObserver::ShowNoDataNotification(
134 CellularDataPlanType plan_type) { 229 CellularDataPlanType plan_type) {
135 notification_low_data_.Hide(); // Hide previous low data notification. 230 notification_low_data_->Hide(); // Hide previous low data notification.
136 string16 message = plan_type == CELLULAR_DATA_PLAN_UNLIMITED ? 231 string16 message = plan_type == CELLULAR_DATA_PLAN_UNLIMITED ?
137 TimeFormat::TimeRemaining(base::TimeDelta()) : 232 TimeFormat::TimeRemaining(base::TimeDelta()) :
138 l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_REMAINING_MESSAGE, 233 l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_REMAINING_MESSAGE,
139 ASCIIToUTF16("0")); 234 ASCIIToUTF16("0"));
140 notification_no_data_.Show(message, 235 notification_no_data_->Show(message,
141 l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE), 236 l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE),
142 base::Bind(&NetworkMessageObserver::OpenMobileSetupPage, AsWeakPtr()), 237 base::Bind(&NetworkMessageObserver::OpenMobileSetupPage, AsWeakPtr()),
143 false, false); 238 false, false);
144 } 239 }
145 240
146 void NetworkMessageObserver::ShowLowDataNotification( 241 void NetworkMessageObserver::ShowLowDataNotification(
147 const CellularDataPlan* plan) { 242 const CellularDataPlan* plan) {
148 string16 message; 243 string16 message;
149 if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) { 244 if (plan->plan_type == CELLULAR_DATA_PLAN_UNLIMITED) {
150 message = plan->GetPlanExpiration(); 245 message = plan->GetPlanExpiration();
151 } else { 246 } else {
152 int64 remaining_mbytes = plan->remaining_data() / (1024 * 1024); 247 int64 remaining_mbytes = plan->remaining_data() / (1024 * 1024);
153 message = l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_REMAINING_MESSAGE, 248 message = l10n_util::GetStringFUTF16(IDS_NETWORK_DATA_REMAINING_MESSAGE,
154 UTF8ToUTF16(base::Int64ToString(remaining_mbytes))); 249 UTF8ToUTF16(base::Int64ToString(remaining_mbytes)));
155 } 250 }
156 notification_low_data_.Show(message, 251 notification_low_data_->Show(message,
157 l10n_util::GetStringUTF16(IDS_NETWORK_MORE_INFO_MESSAGE), 252 l10n_util::GetStringUTF16(IDS_NETWORK_MORE_INFO_MESSAGE),
158 base::Bind(&NetworkMessageObserver::OpenMoreInfoPage, AsWeakPtr()), 253 base::Bind(&NetworkMessageObserver::OpenMoreInfoPage, AsWeakPtr()),
159 false, false); 254 false, false);
160 } 255 }
161 256
162 void NetworkMessageObserver::OnNetworkManagerChanged(NetworkLibrary* cros) { 257 void NetworkMessageObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
163 const Network* new_failed_network = NULL; 258 const Network* new_failed_network = NULL;
164 // Check to see if we have any newly failed networks. 259 // Check to see if we have any newly failed networks.
165 for (WifiNetworkVector::const_iterator it = cros->wifi_networks().begin(); 260 for (WifiNetworkVector::const_iterator it = cros->wifi_networks().begin();
166 it != cros->wifi_networks().end(); it++) { 261 it != cros->wifi_networks().end(); it++) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 const VirtualNetwork* net = *it; 296 const VirtualNetwork* net = *it;
202 if (net->notify_failure()) { 297 if (net->notify_failure()) {
203 new_failed_network = net; 298 new_failed_network = net;
204 break; // There should only be one failed network. 299 break; // There should only be one failed network.
205 } 300 }
206 } 301 }
207 } 302 }
208 303
209 // Show connection error notification if necessary. 304 // Show connection error notification if necessary.
210 if (new_failed_network) { 305 if (new_failed_network) {
211 // Hide if already shown to force show it in case user has closed it. 306 notification_connection_error_->ShowAlways(
212 if (notification_connection_error_.visible()) 307 l10n_util::GetStringFUTF16(
213 notification_connection_error_.Hide(); 308 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_DETAILS,
214 notification_connection_error_.Show(l10n_util::GetStringFUTF16( 309 UTF8ToUTF16(new_failed_network->name()),
215 IDS_NETWORK_CONNECTION_ERROR_MESSAGE_WITH_DETAILS, 310 UTF8ToUTF16(new_failed_network->GetErrorString())),
216 UTF8ToUTF16(new_failed_network->name()), 311 string16(), BalloonViewHost::MessageCallback(), false, false);
217 UTF8ToUTF16(new_failed_network->GetErrorString())), false, false);
218 } 312 }
219 } 313 }
220 314
221 void NetworkMessageObserver::OnCellularDataPlanChanged(NetworkLibrary* cros) { 315 void NetworkMessageObserver::OnCellularDataPlanChanged(NetworkLibrary* cros) {
222 if (!ShouldShowMobilePlanNotifications()) 316 if (!ShouldShowMobilePlanNotifications())
223 return; 317 return;
224 const CellularNetwork* cellular = cros->cellular_network(); 318 const CellularNetwork* cellular = cros->cellular_network();
225 if (!cellular || !cellular->SupportsDataPlan()) 319 if (!cellular || !cellular->SupportsDataPlan())
226 return; 320 return;
227 321
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 if (!new_plan && (cellular_data_left_ != CellularNetwork::DATA_VERY_LOW)) 365 if (!new_plan && (cellular_data_left_ != CellularNetwork::DATA_VERY_LOW))
272 ShowLowDataNotification(current_plan); 366 ShowLowDataNotification(current_plan);
273 } 367 }
274 368
275 SaveLastCellularInfo(cellular, current_plan); 369 SaveLastCellularInfo(cellular, current_plan);
276 } 370 }
277 371
278 void NetworkMessageObserver::OnConnectionInitiated(NetworkLibrary* cros, 372 void NetworkMessageObserver::OnConnectionInitiated(NetworkLibrary* cros,
279 const Network* network) { 373 const Network* network) {
280 // If user initiated any network connection, we hide the error notification. 374 // If user initiated any network connection, we hide the error notification.
281 notification_connection_error_.Hide(); 375 notification_connection_error_->Hide();
282 } 376 }
283 377
284 void NetworkMessageObserver::SaveLastCellularInfo( 378 void NetworkMessageObserver::SaveLastCellularInfo(
285 const CellularNetwork* cellular, const CellularDataPlan* plan) { 379 const CellularNetwork* cellular, const CellularDataPlan* plan) {
286 DCHECK(cellular); 380 DCHECK(cellular);
287 cellular_service_path_ = cellular->service_path(); 381 cellular_service_path_ = cellular->service_path();
288 cellular_data_left_ = cellular->data_left(); 382 cellular_data_left_ = cellular->data_left();
289 if (plan) { 383 if (plan) {
290 cellular_data_plan_unique_id_ = plan->GetUniqueIdentifier(); 384 cellular_data_plan_unique_id_ = plan->GetUniqueIdentifier();
291 cellular_data_plan_type_ = plan->plan_type; 385 cellular_data_plan_type_ = plan->plan_type;
292 } else { 386 } else {
293 cellular_data_plan_unique_id_ = std::string(); 387 cellular_data_plan_unique_id_ = std::string();
294 cellular_data_plan_type_ = CELLULAR_DATA_PLAN_UNKNOWN; 388 cellular_data_plan_type_ = CELLULAR_DATA_PLAN_UNKNOWN;
295 } 389 }
296 } 390 }
297 391
298 } // namespace chromeos 392 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/network_message_observer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698