| OLD | NEW |
| 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 "net/proxy/proxy_config_service_linux.h" | 5 #include "net/proxy/proxy_config_service_linux.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #if defined(USE_GCONF) | 8 #if defined(USE_GCONF) |
| 9 #include <gconf/gconf-client.h> | 9 #include <gconf/gconf-client.h> |
| 10 #endif // defined(USE_GCONF) | 10 #endif // defined(USE_GCONF) |
| 11 #include <limits.h> | 11 #include <limits.h> |
| 12 #include <stdio.h> | 12 #include <stdio.h> |
| 13 #include <stdlib.h> | 13 #include <stdlib.h> |
| 14 #include <sys/inotify.h> | 14 #include <sys/inotify.h> |
| 15 #include <unistd.h> | 15 #include <unistd.h> |
| 16 | 16 |
| 17 #include <map> | 17 #include <map> |
| 18 #include <utility> | 18 #include <utility> |
| 19 | 19 |
| 20 #include "base/bind.h" | 20 #include "base/bind.h" |
| 21 #include "base/compiler_specific.h" | 21 #include "base/compiler_specific.h" |
| 22 #include "base/debug/leak_annotations.h" | 22 #include "base/debug/leak_annotations.h" |
| 23 #include "base/files/file_descriptor_watcher_posix.h" | 23 #include "base/files/file_descriptor_watcher_posix.h" |
| 24 #include "base/files/file_path.h" | 24 #include "base/files/file_path.h" |
| 25 #include "base/files/file_util.h" | 25 #include "base/files/file_util.h" |
| 26 #include "base/files/scoped_file.h" | 26 #include "base/files/scoped_file.h" |
| 27 #include "base/logging.h" | 27 #include "base/logging.h" |
| 28 #include "base/macros.h" | 28 #include "base/macros.h" |
| 29 #include "base/nix/xdg_util.h" | 29 #include "base/nix/xdg_util.h" |
| 30 #include "base/sequenced_task_runner.h" |
| 30 #include "base/single_thread_task_runner.h" | 31 #include "base/single_thread_task_runner.h" |
| 31 #include "base/strings/string_number_conversions.h" | 32 #include "base/strings/string_number_conversions.h" |
| 32 #include "base/strings/string_tokenizer.h" | 33 #include "base/strings/string_tokenizer.h" |
| 33 #include "base/strings/string_util.h" | 34 #include "base/strings/string_util.h" |
| 35 #include "base/task_scheduler/post_task.h" |
| 36 #include "base/task_scheduler/task_traits.h" |
| 34 #include "base/threading/thread_restrictions.h" | 37 #include "base/threading/thread_restrictions.h" |
| 35 #include "base/timer/timer.h" | 38 #include "base/timer/timer.h" |
| 36 #include "net/base/net_errors.h" | 39 #include "net/base/net_errors.h" |
| 37 #include "net/http/http_util.h" | 40 #include "net/http/http_util.h" |
| 38 #include "net/proxy/proxy_config.h" | 41 #include "net/proxy/proxy_config.h" |
| 39 #include "net/proxy/proxy_server.h" | 42 #include "net/proxy/proxy_server.h" |
| 40 #include "url/url_canon.h" | 43 #include "url/url_canon.h" |
| 41 | 44 |
| 42 #if defined(USE_GIO) | 45 #if defined(USE_GIO) |
| 43 #include "library_loaders/libgio.h" // nogncheck | 46 #include "library_loaders/libgio.h" // nogncheck |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 debounce_timer_(new base::OneShotTimer()) {} | 216 debounce_timer_(new base::OneShotTimer()) {} |
| 214 | 217 |
| 215 ~SettingGetterImplGConf() override { | 218 ~SettingGetterImplGConf() override { |
| 216 // client_ should have been released before now, from | 219 // client_ should have been released before now, from |
| 217 // Delegate::OnDestroy(), while running on the UI thread. However | 220 // Delegate::OnDestroy(), while running on the UI thread. However |
| 218 // on exiting the process, it may happen that Delegate::OnDestroy() | 221 // on exiting the process, it may happen that Delegate::OnDestroy() |
| 219 // task is left pending on the glib loop after the loop was quit, | 222 // task is left pending on the glib loop after the loop was quit, |
| 220 // and pending tasks may then be deleted without being run. | 223 // and pending tasks may then be deleted without being run. |
| 221 if (client_) { | 224 if (client_) { |
| 222 // gconf client was not cleaned up. | 225 // gconf client was not cleaned up. |
| 223 if (task_runner_->BelongsToCurrentThread()) { | 226 if (task_runner_->RunsTasksInCurrentSequence()) { |
| 224 // We are on the UI thread so we can clean it safely. This is | 227 // We are on the UI thread so we can clean it safely. This is |
| 225 // the case at least for ui_tests running under Valgrind in | 228 // the case at least for ui_tests running under Valgrind in |
| 226 // bug 16076. | 229 // bug 16076. |
| 227 VLOG(1) << "~SettingGetterImplGConf: releasing gconf client"; | 230 VLOG(1) << "~SettingGetterImplGConf: releasing gconf client"; |
| 228 ShutDown(); | 231 ShutDown(); |
| 229 } else { | 232 } else { |
| 230 // This is very bad! We are deleting the setting getter but we're not on | 233 // This is very bad! We are deleting the setting getter but we're not on |
| 231 // the UI thread. This is not supposed to happen: the setting getter is | 234 // the UI thread. This is not supposed to happen: the setting getter is |
| 232 // owned by the proxy config service's delegate, which is supposed to be | 235 // owned by the proxy config service's delegate, which is supposed to be |
| 233 // destroyed on the UI thread only. We will get change notifications to | 236 // destroyed on the UI thread only. We will get change notifications to |
| 234 // a deleted object if we continue here, so fail now. | 237 // a deleted object if we continue here, so fail now. |
| 235 LOG(FATAL) << "~SettingGetterImplGConf: deleting on wrong thread!"; | 238 LOG(FATAL) << "~SettingGetterImplGConf: deleting on wrong thread!"; |
| 236 } | 239 } |
| 237 } | 240 } |
| 238 DCHECK(!client_); | 241 DCHECK(!client_); |
| 239 } | 242 } |
| 240 | 243 |
| 241 bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner, | 244 bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner) |
| 242 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) | |
| 243 override { | 245 override { |
| 244 DCHECK(glib_task_runner->BelongsToCurrentThread()); | 246 DCHECK(glib_task_runner->RunsTasksInCurrentSequence()); |
| 245 DCHECK(!client_); | 247 DCHECK(!client_); |
| 246 DCHECK(!task_runner_.get()); | 248 DCHECK(!task_runner_.get()); |
| 247 task_runner_ = glib_task_runner; | 249 task_runner_ = glib_task_runner; |
| 248 | 250 |
| 249 client_ = gconf_client_get_default(); | 251 client_ = gconf_client_get_default(); |
| 250 if (!client_) { | 252 if (!client_) { |
| 251 // It's not clear whether/when this can return NULL. | 253 // It's not clear whether/when this can return NULL. |
| 252 LOG(ERROR) << "Unable to create a gconf client"; | 254 LOG(ERROR) << "Unable to create a gconf client"; |
| 253 task_runner_ = nullptr; | 255 task_runner_ = nullptr; |
| 254 return false; | 256 return false; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 274 if (added_system_proxy) | 276 if (added_system_proxy) |
| 275 gconf_client_remove_dir(client_, "/system/proxy", nullptr); | 277 gconf_client_remove_dir(client_, "/system/proxy", nullptr); |
| 276 g_object_unref(client_); | 278 g_object_unref(client_); |
| 277 client_ = nullptr; | 279 client_ = nullptr; |
| 278 task_runner_ = nullptr; | 280 task_runner_ = nullptr; |
| 279 return false; | 281 return false; |
| 280 } | 282 } |
| 281 | 283 |
| 282 void ShutDown() override { | 284 void ShutDown() override { |
| 283 if (client_) { | 285 if (client_) { |
| 284 DCHECK(task_runner_->BelongsToCurrentThread()); | 286 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 285 // We must explicitly disable gconf notifications here, because the gconf | 287 // We must explicitly disable gconf notifications here, because the gconf |
| 286 // client will be shared between all setting getters, and they do not all | 288 // client will be shared between all setting getters, and they do not all |
| 287 // have the same lifetimes. (For instance, incognito sessions get their | 289 // have the same lifetimes. (For instance, incognito sessions get their |
| 288 // own, which is destroyed when the session ends.) | 290 // own, which is destroyed when the session ends.) |
| 289 gconf_client_notify_remove(client_, system_http_proxy_id_); | 291 gconf_client_notify_remove(client_, system_http_proxy_id_); |
| 290 gconf_client_notify_remove(client_, system_proxy_id_); | 292 gconf_client_notify_remove(client_, system_proxy_id_); |
| 291 gconf_client_remove_dir(client_, "/system/http_proxy", nullptr); | 293 gconf_client_remove_dir(client_, "/system/http_proxy", nullptr); |
| 292 gconf_client_remove_dir(client_, "/system/proxy", nullptr); | 294 gconf_client_remove_dir(client_, "/system/proxy", nullptr); |
| 293 g_object_unref(client_); | 295 g_object_unref(client_); |
| 294 client_ = nullptr; | 296 client_ = nullptr; |
| 295 task_runner_ = nullptr; | 297 task_runner_ = nullptr; |
| 296 } | 298 } |
| 297 debounce_timer_.reset(); | 299 debounce_timer_.reset(); |
| 298 } | 300 } |
| 299 | 301 |
| 300 bool SetUpNotifications( | 302 bool SetUpNotifications( |
| 301 ProxyConfigServiceLinux::Delegate* delegate) override { | 303 ProxyConfigServiceLinux::Delegate* delegate) override { |
| 302 DCHECK(client_); | 304 DCHECK(client_); |
| 303 DCHECK(task_runner_->BelongsToCurrentThread()); | 305 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 304 GError* error = nullptr; | 306 GError* error = nullptr; |
| 305 notify_delegate_ = delegate; | 307 notify_delegate_ = delegate; |
| 306 // We have to keep track of the IDs returned by gconf_client_notify_add() so | 308 // We have to keep track of the IDs returned by gconf_client_notify_add() so |
| 307 // that we can remove them in ShutDown(). (Otherwise, notifications will be | 309 // that we can remove them in ShutDown(). (Otherwise, notifications will be |
| 308 // delivered to this object after it is deleted, which is bad, m'kay?) | 310 // delivered to this object after it is deleted, which is bad, m'kay?) |
| 309 system_proxy_id_ = gconf_client_notify_add(client_, "/system/proxy", | 311 system_proxy_id_ = gconf_client_notify_add(client_, "/system/proxy", |
| 310 OnGConfChangeNotification, this, | 312 OnGConfChangeNotification, this, |
| 311 nullptr, &error); | 313 nullptr, &error); |
| 312 if (!error) { | 314 if (!error) { |
| 313 system_http_proxy_id_ = gconf_client_notify_add( | 315 system_http_proxy_id_ = gconf_client_notify_add( |
| 314 client_, "/system/http_proxy", OnGConfChangeNotification, this, | 316 client_, "/system/http_proxy", OnGConfChangeNotification, this, |
| 315 nullptr, &error); | 317 nullptr, &error); |
| 316 } | 318 } |
| 317 if (!error) { | 319 if (!error) { |
| 318 // Simulate a change to avoid possibly losing updates before this point. | 320 // Simulate a change to avoid possibly losing updates before this point. |
| 319 OnChangeNotification(); | 321 OnChangeNotification(); |
| 320 return true; | 322 return true; |
| 321 } | 323 } |
| 322 | 324 |
| 323 LOG(ERROR) << "Error requesting gconf notifications: " << error->message; | 325 LOG(ERROR) << "Error requesting gconf notifications: " << error->message; |
| 324 g_error_free(error); | 326 g_error_free(error); |
| 325 ShutDown(); | 327 ShutDown(); |
| 326 return false; | 328 return false; |
| 327 } | 329 } |
| 328 | 330 |
| 329 const scoped_refptr<base::SingleThreadTaskRunner>& GetNotificationTaskRunner() | 331 const scoped_refptr<base::SequencedTaskRunner>& GetNotificationTaskRunner() |
| 330 override { | 332 override { |
| 331 return task_runner_; | 333 return task_runner_; |
| 332 } | 334 } |
| 333 | 335 |
| 334 ProxyConfigSource GetConfigSource() override { | 336 ProxyConfigSource GetConfigSource() override { |
| 335 return PROXY_CONFIG_SOURCE_GCONF; | 337 return PROXY_CONFIG_SOURCE_GCONF; |
| 336 } | 338 } |
| 337 | 339 |
| 338 bool GetString(StringSetting key, std::string* result) override { | 340 bool GetString(StringSetting key, std::string* result) override { |
| 339 switch (key) { | 341 switch (key) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 bool BypassListIsReversed() override { | 390 bool BypassListIsReversed() override { |
| 389 // This is a KDE-specific setting. | 391 // This is a KDE-specific setting. |
| 390 return false; | 392 return false; |
| 391 } | 393 } |
| 392 | 394 |
| 393 bool MatchHostsUsingSuffixMatching() override { return false; } | 395 bool MatchHostsUsingSuffixMatching() override { return false; } |
| 394 | 396 |
| 395 private: | 397 private: |
| 396 bool GetStringByPath(base::StringPiece key, std::string* result) { | 398 bool GetStringByPath(base::StringPiece key, std::string* result) { |
| 397 DCHECK(client_); | 399 DCHECK(client_); |
| 398 DCHECK(task_runner_->BelongsToCurrentThread()); | 400 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 399 GError* error = nullptr; | 401 GError* error = nullptr; |
| 400 gchar* value = gconf_client_get_string(client_, key.data(), &error); | 402 gchar* value = gconf_client_get_string(client_, key.data(), &error); |
| 401 if (HandleGError(error, key.data())) | 403 if (HandleGError(error, key.data())) |
| 402 return false; | 404 return false; |
| 403 if (!value) | 405 if (!value) |
| 404 return false; | 406 return false; |
| 405 *result = value; | 407 *result = value; |
| 406 g_free(value); | 408 g_free(value); |
| 407 return true; | 409 return true; |
| 408 } | 410 } |
| 409 bool GetBoolByPath(base::StringPiece key, bool* result) { | 411 bool GetBoolByPath(base::StringPiece key, bool* result) { |
| 410 DCHECK(client_); | 412 DCHECK(client_); |
| 411 DCHECK(task_runner_->BelongsToCurrentThread()); | 413 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 412 GError* error = nullptr; | 414 GError* error = nullptr; |
| 413 // We want to distinguish unset values from values defaulting to | 415 // We want to distinguish unset values from values defaulting to |
| 414 // false. For that we need to use the type-generic | 416 // false. For that we need to use the type-generic |
| 415 // gconf_client_get() rather than gconf_client_get_bool(). | 417 // gconf_client_get() rather than gconf_client_get_bool(). |
| 416 GConfValue* gconf_value = gconf_client_get(client_, key.data(), &error); | 418 GConfValue* gconf_value = gconf_client_get(client_, key.data(), &error); |
| 417 if (HandleGError(error, key.data())) | 419 if (HandleGError(error, key.data())) |
| 418 return false; | 420 return false; |
| 419 if (!gconf_value) { | 421 if (!gconf_value) { |
| 420 // Unset. | 422 // Unset. |
| 421 return false; | 423 return false; |
| 422 } | 424 } |
| 423 if (gconf_value->type != GCONF_VALUE_BOOL) { | 425 if (gconf_value->type != GCONF_VALUE_BOOL) { |
| 424 gconf_value_free(gconf_value); | 426 gconf_value_free(gconf_value); |
| 425 return false; | 427 return false; |
| 426 } | 428 } |
| 427 gboolean bool_value = gconf_value_get_bool(gconf_value); | 429 gboolean bool_value = gconf_value_get_bool(gconf_value); |
| 428 *result = static_cast<bool>(bool_value); | 430 *result = static_cast<bool>(bool_value); |
| 429 gconf_value_free(gconf_value); | 431 gconf_value_free(gconf_value); |
| 430 return true; | 432 return true; |
| 431 } | 433 } |
| 432 bool GetIntByPath(base::StringPiece key, int* result) { | 434 bool GetIntByPath(base::StringPiece key, int* result) { |
| 433 DCHECK(client_); | 435 DCHECK(client_); |
| 434 DCHECK(task_runner_->BelongsToCurrentThread()); | 436 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 435 GError* error = nullptr; | 437 GError* error = nullptr; |
| 436 int value = gconf_client_get_int(client_, key.data(), &error); | 438 int value = gconf_client_get_int(client_, key.data(), &error); |
| 437 if (HandleGError(error, key.data())) | 439 if (HandleGError(error, key.data())) |
| 438 return false; | 440 return false; |
| 439 // We don't bother to distinguish an unset value because callers | 441 // We don't bother to distinguish an unset value because callers |
| 440 // don't care. 0 is returned if unset. | 442 // don't care. 0 is returned if unset. |
| 441 *result = value; | 443 *result = value; |
| 442 return true; | 444 return true; |
| 443 } | 445 } |
| 444 bool GetStringListByPath(base::StringPiece key, | 446 bool GetStringListByPath(base::StringPiece key, |
| 445 std::vector<std::string>* result) { | 447 std::vector<std::string>* result) { |
| 446 DCHECK(client_); | 448 DCHECK(client_); |
| 447 DCHECK(task_runner_->BelongsToCurrentThread()); | 449 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 448 GError* error = nullptr; | 450 GError* error = nullptr; |
| 449 GSList* list = | 451 GSList* list = |
| 450 gconf_client_get_list(client_, key.data(), GCONF_VALUE_STRING, &error); | 452 gconf_client_get_list(client_, key.data(), GCONF_VALUE_STRING, &error); |
| 451 if (HandleGError(error, key.data())) | 453 if (HandleGError(error, key.data())) |
| 452 return false; | 454 return false; |
| 453 if (!list) | 455 if (!list) |
| 454 return false; | 456 return false; |
| 455 for (GSList *it = list; it; it = it->next) { | 457 for (GSList *it = list; it; it = it->next) { |
| 456 result->push_back(static_cast<char*>(it->data)); | 458 result->push_back(static_cast<char*>(it->data)); |
| 457 g_free(it->data); | 459 g_free(it->data); |
| 458 } | 460 } |
| 459 g_slist_free(list); | 461 g_slist_free(list); |
| 460 return true; | 462 return true; |
| 461 } | 463 } |
| 462 | 464 |
| 463 // Logs and frees a glib error. Returns false if there was no error | 465 // Logs and frees a glib error. Returns false if there was no error |
| 464 // (error is NULL). | 466 // (error is NULL). |
| 465 bool HandleGError(GError* error, base::StringPiece key) { | 467 bool HandleGError(GError* error, base::StringPiece key) { |
| 466 if (!error) | 468 if (!error) |
| 467 return false; | 469 return false; |
| 468 | 470 |
| 469 LOG(ERROR) << "Error getting gconf value for " << key << ": " | 471 LOG(ERROR) << "Error getting gconf value for " << key << ": " |
| 470 << error->message; | 472 << error->message; |
| 471 g_error_free(error); | 473 g_error_free(error); |
| 472 return true; | 474 return true; |
| 473 } | 475 } |
| 474 | 476 |
| 475 // This is the callback from the debounce timer. | 477 // This is the callback from the debounce timer. |
| 476 void OnDebouncedNotification() { | 478 void OnDebouncedNotification() { |
| 477 DCHECK(task_runner_->BelongsToCurrentThread()); | 479 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 478 CHECK(notify_delegate_); | 480 CHECK(notify_delegate_); |
| 479 // Forward to a method on the proxy config service delegate object. | 481 // Forward to a method on the proxy config service delegate object. |
| 480 notify_delegate_->OnCheckProxyConfigSettings(); | 482 notify_delegate_->OnCheckProxyConfigSettings(); |
| 481 } | 483 } |
| 482 | 484 |
| 483 void OnChangeNotification() { | 485 void OnChangeNotification() { |
| 484 // We don't use Reset() because the timer may not yet be running. | 486 // We don't use Reset() because the timer may not yet be running. |
| 485 // (In that case Stop() is a no-op.) | 487 // (In that case Stop() is a no-op.) |
| 486 debounce_timer_->Stop(); | 488 debounce_timer_->Stop(); |
| 487 debounce_timer_->Start(FROM_HERE, | 489 debounce_timer_->Start(FROM_HERE, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 505 // will need in order to later call gconf_client_notify_remove(). | 507 // will need in order to later call gconf_client_notify_remove(). |
| 506 guint system_proxy_id_; | 508 guint system_proxy_id_; |
| 507 guint system_http_proxy_id_; | 509 guint system_http_proxy_id_; |
| 508 | 510 |
| 509 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 511 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 510 std::unique_ptr<base::OneShotTimer> debounce_timer_; | 512 std::unique_ptr<base::OneShotTimer> debounce_timer_; |
| 511 | 513 |
| 512 // Task runner for the thread that we make gconf calls on. It should | 514 // Task runner for the thread that we make gconf calls on. It should |
| 513 // be the UI thread and all our methods should be called on this | 515 // be the UI thread and all our methods should be called on this |
| 514 // thread. Only for assertions. | 516 // thread. Only for assertions. |
| 515 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 517 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 516 | 518 |
| 517 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf); | 519 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf); |
| 518 }; | 520 }; |
| 519 #endif // defined(USE_GCONF) | 521 #endif // defined(USE_GCONF) |
| 520 | 522 |
| 521 #if defined(USE_GIO) | 523 #if defined(USE_GIO) |
| 522 const char kProxyGConfSchema[] = "org.gnome.system.proxy"; | 524 const char kProxyGConfSchema[] = "org.gnome.system.proxy"; |
| 523 | 525 |
| 524 // This setting getter uses gsettings, as used in most GNOME 3 desktops. | 526 // This setting getter uses gsettings, as used in most GNOME 3 desktops. |
| 525 class SettingGetterImplGSettings | 527 class SettingGetterImplGSettings |
| (...skipping 10 matching lines...) Expand all Loading... |
| 536 | 538 |
| 537 ~SettingGetterImplGSettings() override { | 539 ~SettingGetterImplGSettings() override { |
| 538 // client_ should have been released before now, from | 540 // client_ should have been released before now, from |
| 539 // Delegate::OnDestroy(), while running on the UI thread. However | 541 // Delegate::OnDestroy(), while running on the UI thread. However |
| 540 // on exiting the process, it may happen that | 542 // on exiting the process, it may happen that |
| 541 // Delegate::OnDestroy() task is left pending on the glib loop | 543 // Delegate::OnDestroy() task is left pending on the glib loop |
| 542 // after the loop was quit, and pending tasks may then be deleted | 544 // after the loop was quit, and pending tasks may then be deleted |
| 543 // without being run. | 545 // without being run. |
| 544 if (client_) { | 546 if (client_) { |
| 545 // gconf client was not cleaned up. | 547 // gconf client was not cleaned up. |
| 546 if (task_runner_->BelongsToCurrentThread()) { | 548 if (task_runner_->RunsTasksInCurrentSequence()) { |
| 547 // We are on the UI thread so we can clean it safely. This is | 549 // We are on the UI thread so we can clean it safely. This is |
| 548 // the case at least for ui_tests running under Valgrind in | 550 // the case at least for ui_tests running under Valgrind in |
| 549 // bug 16076. | 551 // bug 16076. |
| 550 VLOG(1) << "~SettingGetterImplGSettings: releasing gsettings client"; | 552 VLOG(1) << "~SettingGetterImplGSettings: releasing gsettings client"; |
| 551 ShutDown(); | 553 ShutDown(); |
| 552 } else { | 554 } else { |
| 553 LOG(WARNING) << "~SettingGetterImplGSettings: leaking gsettings client"; | 555 LOG(WARNING) << "~SettingGetterImplGSettings: leaking gsettings client"; |
| 554 client_ = nullptr; | 556 client_ = nullptr; |
| 555 } | 557 } |
| 556 } | 558 } |
| 557 DCHECK(!client_); | 559 DCHECK(!client_); |
| 558 } | 560 } |
| 559 | 561 |
| 560 bool SchemaExists(base::StringPiece schema_name) { | 562 bool SchemaExists(base::StringPiece schema_name) { |
| 561 const gchar* const* schemas = libgio_loader_.g_settings_list_schemas(); | 563 const gchar* const* schemas = libgio_loader_.g_settings_list_schemas(); |
| 562 while (*schemas) { | 564 while (*schemas) { |
| 563 if (!strcmp(schema_name.data(), static_cast<const char*>(*schemas))) | 565 if (!strcmp(schema_name.data(), static_cast<const char*>(*schemas))) |
| 564 return true; | 566 return true; |
| 565 schemas++; | 567 schemas++; |
| 566 } | 568 } |
| 567 return false; | 569 return false; |
| 568 } | 570 } |
| 569 | 571 |
| 570 // LoadAndCheckVersion() must be called *before* Init()! | 572 // LoadAndCheckVersion() must be called *before* Init()! |
| 571 bool LoadAndCheckVersion(base::Environment* env); | 573 bool LoadAndCheckVersion(base::Environment* env); |
| 572 | 574 |
| 573 bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner, | 575 bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner) |
| 574 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) | |
| 575 override { | 576 override { |
| 576 DCHECK(glib_task_runner->BelongsToCurrentThread()); | 577 DCHECK(glib_task_runner->RunsTasksInCurrentSequence()); |
| 577 DCHECK(!client_); | 578 DCHECK(!client_); |
| 578 DCHECK(!task_runner_.get()); | 579 DCHECK(!task_runner_.get()); |
| 579 | 580 |
| 580 if (!SchemaExists(kProxyGConfSchema) || | 581 if (!SchemaExists(kProxyGConfSchema) || |
| 581 !(client_ = libgio_loader_.g_settings_new(kProxyGConfSchema))) { | 582 !(client_ = libgio_loader_.g_settings_new(kProxyGConfSchema))) { |
| 582 // It's not clear whether/when this can return NULL. | 583 // It's not clear whether/when this can return NULL. |
| 583 LOG(ERROR) << "Unable to create a gsettings client"; | 584 LOG(ERROR) << "Unable to create a gsettings client"; |
| 584 return false; | 585 return false; |
| 585 } | 586 } |
| 586 task_runner_ = glib_task_runner; | 587 task_runner_ = glib_task_runner; |
| 587 // We assume these all work if the above call worked. | 588 // We assume these all work if the above call worked. |
| 588 http_client_ = libgio_loader_.g_settings_get_child(client_, "http"); | 589 http_client_ = libgio_loader_.g_settings_get_child(client_, "http"); |
| 589 https_client_ = libgio_loader_.g_settings_get_child(client_, "https"); | 590 https_client_ = libgio_loader_.g_settings_get_child(client_, "https"); |
| 590 ftp_client_ = libgio_loader_.g_settings_get_child(client_, "ftp"); | 591 ftp_client_ = libgio_loader_.g_settings_get_child(client_, "ftp"); |
| 591 socks_client_ = libgio_loader_.g_settings_get_child(client_, "socks"); | 592 socks_client_ = libgio_loader_.g_settings_get_child(client_, "socks"); |
| 592 DCHECK(http_client_ && https_client_ && ftp_client_ && socks_client_); | 593 DCHECK(http_client_ && https_client_ && ftp_client_ && socks_client_); |
| 593 return true; | 594 return true; |
| 594 } | 595 } |
| 595 | 596 |
| 596 void ShutDown() override { | 597 void ShutDown() override { |
| 597 if (client_) { | 598 if (client_) { |
| 598 DCHECK(task_runner_->BelongsToCurrentThread()); | 599 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 599 // This also disables gsettings notifications. | 600 // This also disables gsettings notifications. |
| 600 g_object_unref(socks_client_); | 601 g_object_unref(socks_client_); |
| 601 g_object_unref(ftp_client_); | 602 g_object_unref(ftp_client_); |
| 602 g_object_unref(https_client_); | 603 g_object_unref(https_client_); |
| 603 g_object_unref(http_client_); | 604 g_object_unref(http_client_); |
| 604 g_object_unref(client_); | 605 g_object_unref(client_); |
| 605 // We only need to null client_ because it's the only one that we check. | 606 // We only need to null client_ because it's the only one that we check. |
| 606 client_ = nullptr; | 607 client_ = nullptr; |
| 607 task_runner_ = nullptr; | 608 task_runner_ = nullptr; |
| 608 } | 609 } |
| 609 debounce_timer_.reset(); | 610 debounce_timer_.reset(); |
| 610 } | 611 } |
| 611 | 612 |
| 612 bool SetUpNotifications( | 613 bool SetUpNotifications( |
| 613 ProxyConfigServiceLinux::Delegate* delegate) override { | 614 ProxyConfigServiceLinux::Delegate* delegate) override { |
| 614 DCHECK(client_); | 615 DCHECK(client_); |
| 615 DCHECK(task_runner_->BelongsToCurrentThread()); | 616 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 616 notify_delegate_ = delegate; | 617 notify_delegate_ = delegate; |
| 617 // We could watch for the change-event signal instead of changed, but | 618 // We could watch for the change-event signal instead of changed, but |
| 618 // since we have to watch more than one object, we'd still have to | 619 // since we have to watch more than one object, we'd still have to |
| 619 // debounce change notifications. This is conceptually simpler. | 620 // debounce change notifications. This is conceptually simpler. |
| 620 g_signal_connect(G_OBJECT(client_), "changed", | 621 g_signal_connect(G_OBJECT(client_), "changed", |
| 621 G_CALLBACK(OnGSettingsChangeNotification), this); | 622 G_CALLBACK(OnGSettingsChangeNotification), this); |
| 622 g_signal_connect(G_OBJECT(http_client_), "changed", | 623 g_signal_connect(G_OBJECT(http_client_), "changed", |
| 623 G_CALLBACK(OnGSettingsChangeNotification), this); | 624 G_CALLBACK(OnGSettingsChangeNotification), this); |
| 624 g_signal_connect(G_OBJECT(https_client_), "changed", | 625 g_signal_connect(G_OBJECT(https_client_), "changed", |
| 625 G_CALLBACK(OnGSettingsChangeNotification), this); | 626 G_CALLBACK(OnGSettingsChangeNotification), this); |
| 626 g_signal_connect(G_OBJECT(ftp_client_), "changed", | 627 g_signal_connect(G_OBJECT(ftp_client_), "changed", |
| 627 G_CALLBACK(OnGSettingsChangeNotification), this); | 628 G_CALLBACK(OnGSettingsChangeNotification), this); |
| 628 g_signal_connect(G_OBJECT(socks_client_), "changed", | 629 g_signal_connect(G_OBJECT(socks_client_), "changed", |
| 629 G_CALLBACK(OnGSettingsChangeNotification), this); | 630 G_CALLBACK(OnGSettingsChangeNotification), this); |
| 630 // Simulate a change to avoid possibly losing updates before this point. | 631 // Simulate a change to avoid possibly losing updates before this point. |
| 631 OnChangeNotification(); | 632 OnChangeNotification(); |
| 632 return true; | 633 return true; |
| 633 } | 634 } |
| 634 | 635 |
| 635 const scoped_refptr<base::SingleThreadTaskRunner>& GetNotificationTaskRunner() | 636 const scoped_refptr<base::SequencedTaskRunner>& GetNotificationTaskRunner() |
| 636 override { | 637 override { |
| 637 return task_runner_; | 638 return task_runner_; |
| 638 } | 639 } |
| 639 | 640 |
| 640 ProxyConfigSource GetConfigSource() override { | 641 ProxyConfigSource GetConfigSource() override { |
| 641 return PROXY_CONFIG_SOURCE_GSETTINGS; | 642 return PROXY_CONFIG_SOURCE_GSETTINGS; |
| 642 } | 643 } |
| 643 | 644 |
| 644 bool GetString(StringSetting key, std::string* result) override { | 645 bool GetString(StringSetting key, std::string* result) override { |
| 645 DCHECK(client_); | 646 DCHECK(client_); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 // This is a KDE-specific setting. | 706 // This is a KDE-specific setting. |
| 706 return false; | 707 return false; |
| 707 } | 708 } |
| 708 | 709 |
| 709 bool MatchHostsUsingSuffixMatching() override { return false; } | 710 bool MatchHostsUsingSuffixMatching() override { return false; } |
| 710 | 711 |
| 711 private: | 712 private: |
| 712 bool GetStringByPath(GSettings* client, | 713 bool GetStringByPath(GSettings* client, |
| 713 base::StringPiece key, | 714 base::StringPiece key, |
| 714 std::string* result) { | 715 std::string* result) { |
| 715 DCHECK(task_runner_->BelongsToCurrentThread()); | 716 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 716 gchar* value = libgio_loader_.g_settings_get_string(client, key.data()); | 717 gchar* value = libgio_loader_.g_settings_get_string(client, key.data()); |
| 717 if (!value) | 718 if (!value) |
| 718 return false; | 719 return false; |
| 719 *result = value; | 720 *result = value; |
| 720 g_free(value); | 721 g_free(value); |
| 721 return true; | 722 return true; |
| 722 } | 723 } |
| 723 bool GetBoolByPath(GSettings* client, base::StringPiece key, bool* result) { | 724 bool GetBoolByPath(GSettings* client, base::StringPiece key, bool* result) { |
| 724 DCHECK(task_runner_->BelongsToCurrentThread()); | 725 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 725 *result = static_cast<bool>( | 726 *result = static_cast<bool>( |
| 726 libgio_loader_.g_settings_get_boolean(client, key.data())); | 727 libgio_loader_.g_settings_get_boolean(client, key.data())); |
| 727 return true; | 728 return true; |
| 728 } | 729 } |
| 729 bool GetIntByPath(GSettings* client, base::StringPiece key, int* result) { | 730 bool GetIntByPath(GSettings* client, base::StringPiece key, int* result) { |
| 730 DCHECK(task_runner_->BelongsToCurrentThread()); | 731 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 731 *result = libgio_loader_.g_settings_get_int(client, key.data()); | 732 *result = libgio_loader_.g_settings_get_int(client, key.data()); |
| 732 return true; | 733 return true; |
| 733 } | 734 } |
| 734 bool GetStringListByPath(GSettings* client, | 735 bool GetStringListByPath(GSettings* client, |
| 735 base::StringPiece key, | 736 base::StringPiece key, |
| 736 std::vector<std::string>* result) { | 737 std::vector<std::string>* result) { |
| 737 DCHECK(task_runner_->BelongsToCurrentThread()); | 738 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 738 gchar** list = libgio_loader_.g_settings_get_strv(client, key.data()); | 739 gchar** list = libgio_loader_.g_settings_get_strv(client, key.data()); |
| 739 if (!list) | 740 if (!list) |
| 740 return false; | 741 return false; |
| 741 for (size_t i = 0; list[i]; ++i) { | 742 for (size_t i = 0; list[i]; ++i) { |
| 742 result->push_back(static_cast<char*>(list[i])); | 743 result->push_back(static_cast<char*>(list[i])); |
| 743 g_free(list[i]); | 744 g_free(list[i]); |
| 744 } | 745 } |
| 745 g_free(list); | 746 g_free(list); |
| 746 return true; | 747 return true; |
| 747 } | 748 } |
| 748 | 749 |
| 749 // This is the callback from the debounce timer. | 750 // This is the callback from the debounce timer. |
| 750 void OnDebouncedNotification() { | 751 void OnDebouncedNotification() { |
| 751 DCHECK(task_runner_->BelongsToCurrentThread()); | 752 DCHECK(task_runner_->RunsTasksInCurrentSequence()); |
| 752 CHECK(notify_delegate_); | 753 CHECK(notify_delegate_); |
| 753 // Forward to a method on the proxy config service delegate object. | 754 // Forward to a method on the proxy config service delegate object. |
| 754 notify_delegate_->OnCheckProxyConfigSettings(); | 755 notify_delegate_->OnCheckProxyConfigSettings(); |
| 755 } | 756 } |
| 756 | 757 |
| 757 void OnChangeNotification() { | 758 void OnChangeNotification() { |
| 758 // We don't use Reset() because the timer may not yet be running. | 759 // We don't use Reset() because the timer may not yet be running. |
| 759 // (In that case Stop() is a no-op.) | 760 // (In that case Stop() is a no-op.) |
| 760 debounce_timer_->Stop(); | 761 debounce_timer_->Stop(); |
| 761 debounce_timer_->Start(FROM_HERE, | 762 debounce_timer_->Start(FROM_HERE, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 777 GSettings* http_client_; | 778 GSettings* http_client_; |
| 778 GSettings* https_client_; | 779 GSettings* https_client_; |
| 779 GSettings* ftp_client_; | 780 GSettings* ftp_client_; |
| 780 GSettings* socks_client_; | 781 GSettings* socks_client_; |
| 781 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 782 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 782 std::unique_ptr<base::OneShotTimer> debounce_timer_; | 783 std::unique_ptr<base::OneShotTimer> debounce_timer_; |
| 783 | 784 |
| 784 // Task runner for the thread that we make gsettings calls on. It should | 785 // Task runner for the thread that we make gsettings calls on. It should |
| 785 // be the UI thread and all our methods should be called on this | 786 // be the UI thread and all our methods should be called on this |
| 786 // thread. Only for assertions. | 787 // thread. Only for assertions. |
| 787 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 788 scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 788 | 789 |
| 789 LibGioLoader libgio_loader_; | 790 LibGioLoader libgio_loader_; |
| 790 | 791 |
| 791 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings); | 792 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings); |
| 792 }; | 793 }; |
| 793 | 794 |
| 794 bool SettingGetterImplGSettings::LoadAndCheckVersion( | 795 bool SettingGetterImplGSettings::LoadAndCheckVersion( |
| 795 base::Environment* env) { | 796 base::Environment* env) { |
| 796 // LoadAndCheckVersion() must be called *before* Init()! | 797 // LoadAndCheckVersion() must be called *before* Init()! |
| 797 DCHECK(!client_); | 798 DCHECK(!client_); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 // on exiting the process, it may happen that Delegate::OnDestroy() | 935 // on exiting the process, it may happen that Delegate::OnDestroy() |
| 935 // task is left pending on the file loop after the loop was quit, | 936 // task is left pending on the file loop after the loop was quit, |
| 936 // and pending tasks may then be deleted without being run. | 937 // and pending tasks may then be deleted without being run. |
| 937 // Here in the KDE version, we can safely close the file descriptor | 938 // Here in the KDE version, we can safely close the file descriptor |
| 938 // anyway. (Not that it really matters; the process is exiting.) | 939 // anyway. (Not that it really matters; the process is exiting.) |
| 939 if (inotify_fd_ >= 0) | 940 if (inotify_fd_ >= 0) |
| 940 ShutDown(); | 941 ShutDown(); |
| 941 DCHECK_LT(inotify_fd_, 0); | 942 DCHECK_LT(inotify_fd_, 0); |
| 942 } | 943 } |
| 943 | 944 |
| 944 bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner, | 945 bool Init(const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner) |
| 945 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) | |
| 946 override { | 946 override { |
| 947 // This has to be called on the UI thread (http://crbug.com/69057). | 947 // This has to be called on the UI thread (http://crbug.com/69057). |
| 948 base::ThreadRestrictions::ScopedAllowIO allow_io; | 948 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 949 DCHECK_LT(inotify_fd_, 0); | 949 DCHECK_LT(inotify_fd_, 0); |
| 950 inotify_fd_ = inotify_init(); | 950 inotify_fd_ = inotify_init(); |
| 951 if (inotify_fd_ < 0) { | 951 if (inotify_fd_ < 0) { |
| 952 PLOG(ERROR) << "inotify_init failed"; | 952 PLOG(ERROR) << "inotify_init failed"; |
| 953 return false; | 953 return false; |
| 954 } | 954 } |
| 955 if (!base::SetNonBlocking(inotify_fd_)) { | 955 if (!base::SetNonBlocking(inotify_fd_)) { |
| 956 PLOG(ERROR) << "base::SetNonBlocking failed"; | 956 PLOG(ERROR) << "base::SetNonBlocking failed"; |
| 957 close(inotify_fd_); | 957 close(inotify_fd_); |
| 958 inotify_fd_ = -1; | 958 inotify_fd_ = -1; |
| 959 return false; | 959 return false; |
| 960 } | 960 } |
| 961 file_task_runner_ = file_task_runner; | 961 |
| 962 constexpr base::TaskTraits kTraits = {base::TaskPriority::USER_VISIBLE, |
| 963 base::MayBlock()}; |
| 964 file_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(kTraits); |
| 965 |
| 962 // The initial read is done on the current thread, not | 966 // The initial read is done on the current thread, not |
| 963 // |file_task_runner_|, since we will need to have it for | 967 // |file_task_runner_|, since we will need to have it for |
| 964 // SetUpAndFetchInitialConfig(). | 968 // SetUpAndFetchInitialConfig(). |
| 965 UpdateCachedSettings(); | 969 UpdateCachedSettings(); |
| 966 return true; | 970 return true; |
| 967 } | 971 } |
| 968 | 972 |
| 969 void ShutDown() override { | 973 void ShutDown() override { |
| 970 if (inotify_fd_ >= 0) { | 974 if (inotify_fd_ >= 0) { |
| 971 ResetCachedSettings(); | 975 ResetCachedSettings(); |
| 972 inotify_watcher_.reset(); | 976 inotify_watcher_.reset(); |
| 973 close(inotify_fd_); | 977 close(inotify_fd_); |
| 974 inotify_fd_ = -1; | 978 inotify_fd_ = -1; |
| 975 } | 979 } |
| 976 debounce_timer_.reset(); | 980 debounce_timer_.reset(); |
| 977 } | 981 } |
| 978 | 982 |
| 979 bool SetUpNotifications( | 983 bool SetUpNotifications( |
| 980 ProxyConfigServiceLinux::Delegate* delegate) override { | 984 ProxyConfigServiceLinux::Delegate* delegate) override { |
| 981 DCHECK_GE(inotify_fd_, 0); | 985 DCHECK_GE(inotify_fd_, 0); |
| 982 DCHECK(file_task_runner_->BelongsToCurrentThread()); | 986 DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); |
| 983 // We can't just watch the kioslaverc file directly, since KDE will write | 987 // We can't just watch the kioslaverc file directly, since KDE will write |
| 984 // a new copy of it and then rename it whenever settings are changed and | 988 // a new copy of it and then rename it whenever settings are changed and |
| 985 // inotify watches inodes (so we'll be watching the old deleted file after | 989 // inotify watches inodes (so we'll be watching the old deleted file after |
| 986 // the first change, and it will never change again). So, we watch the | 990 // the first change, and it will never change again). So, we watch the |
| 987 // directory instead. We then act only on changes to the kioslaverc entry. | 991 // directory instead. We then act only on changes to the kioslaverc entry. |
| 988 // TODO(eroman): What if the file is deleted? (handle with IN_DELETE). | 992 // TODO(eroman): What if the file is deleted? (handle with IN_DELETE). |
| 989 if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(), | 993 if (inotify_add_watch(inotify_fd_, kde_config_dir_.value().c_str(), |
| 990 IN_MODIFY | IN_MOVED_TO) < 0) { | 994 IN_MODIFY | IN_MOVED_TO) < 0) { |
| 991 return false; | 995 return false; |
| 992 } | 996 } |
| 993 notify_delegate_ = delegate; | 997 notify_delegate_ = delegate; |
| 994 inotify_watcher_ = base::FileDescriptorWatcher::WatchReadable( | 998 inotify_watcher_ = base::FileDescriptorWatcher::WatchReadable( |
| 995 inotify_fd_, base::Bind(&SettingGetterImplKDE::OnChangeNotification, | 999 inotify_fd_, base::Bind(&SettingGetterImplKDE::OnChangeNotification, |
| 996 base::Unretained(this))); | 1000 base::Unretained(this))); |
| 997 // Simulate a change to avoid possibly losing updates before this point. | 1001 // Simulate a change to avoid possibly losing updates before this point. |
| 998 OnChangeNotification(); | 1002 OnChangeNotification(); |
| 999 return true; | 1003 return true; |
| 1000 } | 1004 } |
| 1001 | 1005 |
| 1002 const scoped_refptr<base::SingleThreadTaskRunner>& GetNotificationTaskRunner() | 1006 const scoped_refptr<base::SequencedTaskRunner>& GetNotificationTaskRunner() |
| 1003 override { | 1007 override { |
| 1004 return file_task_runner_; | 1008 return file_task_runner_; |
| 1005 } | 1009 } |
| 1006 | 1010 |
| 1007 ProxyConfigSource GetConfigSource() override { | 1011 ProxyConfigSource GetConfigSource() override { |
| 1008 return PROXY_CONFIG_SOURCE_KDE; | 1012 return PROXY_CONFIG_SOURCE_KDE; |
| 1009 } | 1013 } |
| 1010 | 1014 |
| 1011 bool GetString(StringSetting key, std::string* result) override { | 1015 bool GetString(StringSetting key, std::string* result) override { |
| 1012 string_map_type::iterator it = string_table_.find(key); | 1016 string_map_type::iterator it = string_table_.find(key); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 AddKDESetting(key, value); | 1256 AddKDESetting(key, value); |
| 1253 } | 1257 } |
| 1254 } | 1258 } |
| 1255 if (ferror(input.get())) | 1259 if (ferror(input.get())) |
| 1256 LOG(ERROR) << "error reading " << kioslaverc.value(); | 1260 LOG(ERROR) << "error reading " << kioslaverc.value(); |
| 1257 ResolveModeEffects(); | 1261 ResolveModeEffects(); |
| 1258 } | 1262 } |
| 1259 | 1263 |
| 1260 // This is the callback from the debounce timer. | 1264 // This is the callback from the debounce timer. |
| 1261 void OnDebouncedNotification() { | 1265 void OnDebouncedNotification() { |
| 1262 DCHECK(file_task_runner_->BelongsToCurrentThread()); | 1266 DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); |
| 1263 VLOG(1) << "inotify change notification for kioslaverc"; | 1267 VLOG(1) << "inotify change notification for kioslaverc"; |
| 1264 UpdateCachedSettings(); | 1268 UpdateCachedSettings(); |
| 1265 CHECK(notify_delegate_); | 1269 CHECK(notify_delegate_); |
| 1266 // Forward to a method on the proxy config service delegate object. | 1270 // Forward to a method on the proxy config service delegate object. |
| 1267 notify_delegate_->OnCheckProxyConfigSettings(); | 1271 notify_delegate_->OnCheckProxyConfigSettings(); |
| 1268 } | 1272 } |
| 1269 | 1273 |
| 1270 // Called by OnFileCanReadWithoutBlocking() on the file thread. Reads | 1274 // Called by OnFileCanReadWithoutBlocking() on the file thread. Reads |
| 1271 // from the inotify file descriptor and starts up a debounce timer if | 1275 // from the inotify file descriptor and starts up a debounce timer if |
| 1272 // an event for kioslaverc is seen. | 1276 // an event for kioslaverc is seen. |
| 1273 void OnChangeNotification() { | 1277 void OnChangeNotification() { |
| 1274 DCHECK_GE(inotify_fd_, 0); | 1278 DCHECK_GE(inotify_fd_, 0); |
| 1275 DCHECK(file_task_runner_->BelongsToCurrentThread()); | 1279 DCHECK(file_task_runner_->RunsTasksInCurrentSequence()); |
| 1276 char event_buf[(sizeof(inotify_event) + NAME_MAX + 1) * 4]; | 1280 char event_buf[(sizeof(inotify_event) + NAME_MAX + 1) * 4]; |
| 1277 bool kioslaverc_touched = false; | 1281 bool kioslaverc_touched = false; |
| 1278 ssize_t r; | 1282 ssize_t r; |
| 1279 while ((r = read(inotify_fd_, event_buf, sizeof(event_buf))) > 0) { | 1283 while ((r = read(inotify_fd_, event_buf, sizeof(event_buf))) > 0) { |
| 1280 // inotify returns variable-length structures, which is why we have | 1284 // inotify returns variable-length structures, which is why we have |
| 1281 // this strange-looking loop instead of iterating through an array. | 1285 // this strange-looking loop instead of iterating through an array. |
| 1282 char* event_ptr = event_buf; | 1286 char* event_ptr = event_buf; |
| 1283 while (event_ptr < event_buf + r) { | 1287 while (event_ptr < event_buf + r) { |
| 1284 inotify_event* event = reinterpret_cast<inotify_event*>(event_ptr); | 1288 inotify_event* event = reinterpret_cast<inotify_event*>(event_ptr); |
| 1285 // The kernel always feeds us whole events. | 1289 // The kernel always feeds us whole events. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 bool reversed_bypass_list_; | 1340 bool reversed_bypass_list_; |
| 1337 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since | 1341 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since |
| 1338 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the | 1342 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the |
| 1339 // same lifetime. | 1343 // same lifetime. |
| 1340 base::Environment* env_var_getter_; | 1344 base::Environment* env_var_getter_; |
| 1341 | 1345 |
| 1342 // We cache these settings whenever we re-read the kioslaverc file. | 1346 // We cache these settings whenever we re-read the kioslaverc file. |
| 1343 string_map_type string_table_; | 1347 string_map_type string_table_; |
| 1344 strings_map_type strings_table_; | 1348 strings_map_type strings_table_; |
| 1345 | 1349 |
| 1346 // Task runner of the file thread, for reading kioslaverc. If NULL, | 1350 // Task runner for doing blocking file IO on, as well as handling inotify |
| 1347 // just read it directly (for testing). We also handle inotify events | 1351 // events on. |
| 1348 // on this thread. | 1352 scoped_refptr<base::SequencedTaskRunner> file_task_runner_; |
| 1349 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; | |
| 1350 | 1353 |
| 1351 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplKDE); | 1354 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplKDE); |
| 1352 }; | 1355 }; |
| 1353 | 1356 |
| 1354 } // namespace | 1357 } // namespace |
| 1355 | 1358 |
| 1356 bool ProxyConfigServiceLinux::Delegate::GetProxyFromSettings( | 1359 bool ProxyConfigServiceLinux::Delegate::GetProxyFromSettings( |
| 1357 SettingGetter::StringSetting host_key, | 1360 SettingGetter::StringSetting host_key, |
| 1358 ProxyServer* result_server) { | 1361 ProxyServer* result_server) { |
| 1359 std::string host; | 1362 std::string host; |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 } | 1563 } |
| 1561 | 1564 |
| 1562 ProxyConfigServiceLinux::Delegate::Delegate( | 1565 ProxyConfigServiceLinux::Delegate::Delegate( |
| 1563 std::unique_ptr<base::Environment> env_var_getter, | 1566 std::unique_ptr<base::Environment> env_var_getter, |
| 1564 SettingGetter* setting_getter) | 1567 SettingGetter* setting_getter) |
| 1565 : env_var_getter_(std::move(env_var_getter)), | 1568 : env_var_getter_(std::move(env_var_getter)), |
| 1566 setting_getter_(setting_getter) {} | 1569 setting_getter_(setting_getter) {} |
| 1567 | 1570 |
| 1568 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( | 1571 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( |
| 1569 const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner, | 1572 const scoped_refptr<base::SingleThreadTaskRunner>& glib_task_runner, |
| 1570 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 1573 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) { |
| 1571 const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) { | |
| 1572 // We should be running on the default glib main loop thread right | 1574 // We should be running on the default glib main loop thread right |
| 1573 // now. gconf can only be accessed from this thread. | 1575 // now. gconf can only be accessed from this thread. |
| 1574 DCHECK(glib_task_runner->BelongsToCurrentThread()); | 1576 DCHECK(glib_task_runner->RunsTasksInCurrentSequence()); |
| 1575 glib_task_runner_ = glib_task_runner; | 1577 glib_task_runner_ = glib_task_runner; |
| 1576 io_task_runner_ = io_task_runner; | 1578 io_task_runner_ = io_task_runner; |
| 1577 | 1579 |
| 1578 // If we are passed a NULL |io_task_runner| or |file_task_runner|, then we | 1580 // If we are passed a NULL |io_task_runner|, then don't set up proxy |
| 1579 // don't set up proxy setting change notifications. This should not be the | 1581 // setting change notifications. This should not be the usual case but is |
| 1580 // usual case but is intended to/ simplify test setups. | 1582 // intended to/ simplify test setups. |
| 1581 if (!io_task_runner_.get() || !file_task_runner.get()) | 1583 if (!io_task_runner_.get()) |
| 1582 VLOG(1) << "Monitoring of proxy setting changes is disabled"; | 1584 VLOG(1) << "Monitoring of proxy setting changes is disabled"; |
| 1583 | 1585 |
| 1584 // Fetch and cache the current proxy config. The config is left in | 1586 // Fetch and cache the current proxy config. The config is left in |
| 1585 // cached_config_, where GetLatestProxyConfig() running on the IO thread | 1587 // cached_config_, where GetLatestProxyConfig() running on the IO thread |
| 1586 // will expect to find it. This is safe to do because we return | 1588 // will expect to find it. This is safe to do because we return |
| 1587 // before this ProxyConfigServiceLinux is passed on to | 1589 // before this ProxyConfigServiceLinux is passed on to |
| 1588 // the ProxyService. | 1590 // the ProxyService. |
| 1589 | 1591 |
| 1590 // Note: It would be nice to prioritize environment variables | 1592 // Note: It would be nice to prioritize environment variables |
| 1591 // and only fall back to gconf if env vars were unset. But | 1593 // and only fall back to gconf if env vars were unset. But |
| 1592 // gnome-terminal "helpfully" sets http_proxy and no_proxy, and it | 1594 // gnome-terminal "helpfully" sets http_proxy and no_proxy, and it |
| 1593 // does so even if the proxy mode is set to auto, which would | 1595 // does so even if the proxy mode is set to auto, which would |
| 1594 // mislead us. | 1596 // mislead us. |
| 1595 | 1597 |
| 1596 bool got_config = false; | 1598 bool got_config = false; |
| 1597 if (setting_getter_ && | 1599 if (setting_getter_ && setting_getter_->Init(glib_task_runner) && |
| 1598 setting_getter_->Init(glib_task_runner, file_task_runner) && | |
| 1599 GetConfigFromSettings(&cached_config_)) { | 1600 GetConfigFromSettings(&cached_config_)) { |
| 1600 cached_config_.set_id(1); // Mark it as valid. | 1601 cached_config_.set_id(1); // Mark it as valid. |
| 1601 cached_config_.set_source(setting_getter_->GetConfigSource()); | 1602 cached_config_.set_source(setting_getter_->GetConfigSource()); |
| 1602 VLOG(1) << "Obtained proxy settings from " | 1603 VLOG(1) << "Obtained proxy settings from " |
| 1603 << ProxyConfigSourceToString(cached_config_.source()); | 1604 << ProxyConfigSourceToString(cached_config_.source()); |
| 1604 | 1605 |
| 1605 // If gconf proxy mode is "none", meaning direct, then we take | 1606 // If gconf proxy mode is "none", meaning direct, then we take |
| 1606 // that to be a valid config and will not check environment | 1607 // that to be a valid config and will not check environment |
| 1607 // variables. The alternative would have been to look for a proxy | 1608 // variables. The alternative would have been to look for a proxy |
| 1608 // whereever we can find one. | 1609 // whereever we can find one. |
| 1609 got_config = true; | 1610 got_config = true; |
| 1610 | 1611 |
| 1611 // Keep a copy of the config for use from this thread for | 1612 // Keep a copy of the config for use from this thread for |
| 1612 // comparison with updated settings when we get notifications. | 1613 // comparison with updated settings when we get notifications. |
| 1613 reference_config_ = cached_config_; | 1614 reference_config_ = cached_config_; |
| 1614 reference_config_.set_id(1); // Mark it as valid. | 1615 reference_config_.set_id(1); // Mark it as valid. |
| 1615 | 1616 |
| 1616 // We only set up notifications if we have IO and file loops available. | 1617 // We only set up notifications if we have IO and file loops available. |
| 1617 // We do this after getting the initial configuration so that we don't have | 1618 // We do this after getting the initial configuration so that we don't have |
| 1618 // to worry about cancelling it if the initial fetch above fails. Note that | 1619 // to worry about cancelling it if the initial fetch above fails. Note that |
| 1619 // setting up notifications has the side effect of simulating a change, so | 1620 // setting up notifications has the side effect of simulating a change, so |
| 1620 // that we won't lose any updates that may have happened after the initial | 1621 // that we won't lose any updates that may have happened after the initial |
| 1621 // fetch and before setting up notifications. We'll detect the common case | 1622 // fetch and before setting up notifications. We'll detect the common case |
| 1622 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it. | 1623 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it. |
| 1623 if (io_task_runner.get() && file_task_runner.get()) { | 1624 if (io_task_runner.get()) { |
| 1624 scoped_refptr<base::SingleThreadTaskRunner> required_loop = | 1625 scoped_refptr<base::SequencedTaskRunner> required_loop = |
| 1625 setting_getter_->GetNotificationTaskRunner(); | 1626 setting_getter_->GetNotificationTaskRunner(); |
| 1626 if (!required_loop.get() || required_loop->BelongsToCurrentThread()) { | 1627 if (!required_loop.get() || required_loop->RunsTasksInCurrentSequence()) { |
| 1627 // In this case we are already on an acceptable thread. | 1628 // In this case we are already on an acceptable thread. |
| 1628 SetUpNotifications(); | 1629 SetUpNotifications(); |
| 1629 } else { | 1630 } else { |
| 1630 // Post a task to set up notifications. We don't wait for success. | 1631 // Post a task to set up notifications. We don't wait for success. |
| 1631 required_loop->PostTask(FROM_HERE, base::Bind( | 1632 required_loop->PostTask(FROM_HERE, base::Bind( |
| 1632 &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this)); | 1633 &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this)); |
| 1633 } | 1634 } |
| 1634 } | 1635 } |
| 1635 } | 1636 } |
| 1636 | 1637 |
| 1637 if (!got_config) { | 1638 if (!got_config) { |
| 1638 // We fall back on environment variables. | 1639 // We fall back on environment variables. |
| 1639 // | 1640 // |
| 1640 // Consulting environment variables doesn't need to be done from the | 1641 // Consulting environment variables doesn't need to be done from the |
| 1641 // default glib main loop, but it's a tiny enough amount of work. | 1642 // default glib main loop, but it's a tiny enough amount of work. |
| 1642 if (GetConfigFromEnv(&cached_config_)) { | 1643 if (GetConfigFromEnv(&cached_config_)) { |
| 1643 cached_config_.set_source(PROXY_CONFIG_SOURCE_ENV); | 1644 cached_config_.set_source(PROXY_CONFIG_SOURCE_ENV); |
| 1644 cached_config_.set_id(1); // Mark it as valid. | 1645 cached_config_.set_id(1); // Mark it as valid. |
| 1645 VLOG(1) << "Obtained proxy settings from environment variables"; | 1646 VLOG(1) << "Obtained proxy settings from environment variables"; |
| 1646 } | 1647 } |
| 1647 } | 1648 } |
| 1648 } | 1649 } |
| 1649 | 1650 |
| 1650 // Depending on the SettingGetter in use, this method will be called | 1651 // Depending on the SettingGetter in use, this method will be called |
| 1651 // on either the UI thread (GConf) or the file thread (KDE). | 1652 // on either the UI thread (GConf) or the file thread (KDE). |
| 1652 void ProxyConfigServiceLinux::Delegate::SetUpNotifications() { | 1653 void ProxyConfigServiceLinux::Delegate::SetUpNotifications() { |
| 1653 scoped_refptr<base::SingleThreadTaskRunner> required_loop = | 1654 scoped_refptr<base::SequencedTaskRunner> required_loop = |
| 1654 setting_getter_->GetNotificationTaskRunner(); | 1655 setting_getter_->GetNotificationTaskRunner(); |
| 1655 DCHECK(!required_loop.get() || required_loop->BelongsToCurrentThread()); | 1656 DCHECK(!required_loop.get() || required_loop->RunsTasksInCurrentSequence()); |
| 1656 if (!setting_getter_->SetUpNotifications(this)) | 1657 if (!setting_getter_->SetUpNotifications(this)) |
| 1657 LOG(ERROR) << "Unable to set up proxy configuration change notifications"; | 1658 LOG(ERROR) << "Unable to set up proxy configuration change notifications"; |
| 1658 } | 1659 } |
| 1659 | 1660 |
| 1660 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) { | 1661 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) { |
| 1661 observers_.AddObserver(observer); | 1662 observers_.AddObserver(observer); |
| 1662 } | 1663 } |
| 1663 | 1664 |
| 1664 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) { | 1665 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) { |
| 1665 observers_.RemoveObserver(observer); | 1666 observers_.RemoveObserver(observer); |
| 1666 } | 1667 } |
| 1667 | 1668 |
| 1668 ProxyConfigService::ConfigAvailability | 1669 ProxyConfigService::ConfigAvailability |
| 1669 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig( | 1670 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig( |
| 1670 ProxyConfig* config) { | 1671 ProxyConfig* config) { |
| 1671 // This is called from the IO thread. | 1672 // This is called from the IO thread. |
| 1672 DCHECK(!io_task_runner_.get() || | 1673 DCHECK(!io_task_runner_.get() || |
| 1673 io_task_runner_->BelongsToCurrentThread()); | 1674 io_task_runner_->RunsTasksInCurrentSequence()); |
| 1674 | 1675 |
| 1675 // Simply return the last proxy configuration that glib_default_loop | 1676 // Simply return the last proxy configuration that glib_default_loop |
| 1676 // notified us of. | 1677 // notified us of. |
| 1677 if (cached_config_.is_valid()) { | 1678 if (cached_config_.is_valid()) { |
| 1678 *config = cached_config_; | 1679 *config = cached_config_; |
| 1679 } else { | 1680 } else { |
| 1680 *config = ProxyConfig::CreateDirect(); | 1681 *config = ProxyConfig::CreateDirect(); |
| 1681 config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED); | 1682 config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED); |
| 1682 } | 1683 } |
| 1683 | 1684 |
| 1684 // We return CONFIG_VALID to indicate that *config was filled in. It is always | 1685 // We return CONFIG_VALID to indicate that *config was filled in. It is always |
| 1685 // going to be available since we initialized eagerly on the UI thread. | 1686 // going to be available since we initialized eagerly on the UI thread. |
| 1686 // TODO(eroman): do lazy initialization instead, so we no longer need | 1687 // TODO(eroman): do lazy initialization instead, so we no longer need |
| 1687 // to construct ProxyConfigServiceLinux on the UI thread. | 1688 // to construct ProxyConfigServiceLinux on the UI thread. |
| 1688 // In which case, we may return false here. | 1689 // In which case, we may return false here. |
| 1689 return CONFIG_VALID; | 1690 return CONFIG_VALID; |
| 1690 } | 1691 } |
| 1691 | 1692 |
| 1692 // Depending on the SettingGetter in use, this method will be called | 1693 // Depending on the SettingGetter in use, this method will be called |
| 1693 // on either the UI thread (GConf) or the file thread (KDE). | 1694 // on either the UI thread (GConf) or the file thread (KDE). |
| 1694 void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() { | 1695 void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() { |
| 1695 scoped_refptr<base::SingleThreadTaskRunner> required_loop = | 1696 scoped_refptr<base::SequencedTaskRunner> required_loop = |
| 1696 setting_getter_->GetNotificationTaskRunner(); | 1697 setting_getter_->GetNotificationTaskRunner(); |
| 1697 DCHECK(!required_loop.get() || required_loop->BelongsToCurrentThread()); | 1698 DCHECK(!required_loop.get() || required_loop->RunsTasksInCurrentSequence()); |
| 1698 ProxyConfig new_config; | 1699 ProxyConfig new_config; |
| 1699 bool valid = GetConfigFromSettings(&new_config); | 1700 bool valid = GetConfigFromSettings(&new_config); |
| 1700 if (valid) | 1701 if (valid) |
| 1701 new_config.set_id(1); // mark it as valid | 1702 new_config.set_id(1); // mark it as valid |
| 1702 | 1703 |
| 1703 // See if it is different from what we had before. | 1704 // See if it is different from what we had before. |
| 1704 if (new_config.is_valid() != reference_config_.is_valid() || | 1705 if (new_config.is_valid() != reference_config_.is_valid() || |
| 1705 !new_config.Equals(reference_config_)) { | 1706 !new_config.Equals(reference_config_)) { |
| 1706 // Post a task to the IO thread with the new configuration, so it can | 1707 // Post a task to the IO thread with the new configuration, so it can |
| 1707 // update |cached_config_|. | 1708 // update |cached_config_|. |
| 1708 io_task_runner_->PostTask(FROM_HERE, base::Bind( | 1709 io_task_runner_->PostTask(FROM_HERE, base::Bind( |
| 1709 &ProxyConfigServiceLinux::Delegate::SetNewProxyConfig, | 1710 &ProxyConfigServiceLinux::Delegate::SetNewProxyConfig, |
| 1710 this, new_config)); | 1711 this, new_config)); |
| 1711 // Update the thread-private copy in |reference_config_| as well. | 1712 // Update the thread-private copy in |reference_config_| as well. |
| 1712 reference_config_ = new_config; | 1713 reference_config_ = new_config; |
| 1713 } else { | 1714 } else { |
| 1714 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing."; | 1715 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing."; |
| 1715 } | 1716 } |
| 1716 } | 1717 } |
| 1717 | 1718 |
| 1718 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig( | 1719 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig( |
| 1719 const ProxyConfig& new_config) { | 1720 const ProxyConfig& new_config) { |
| 1720 DCHECK(io_task_runner_->BelongsToCurrentThread()); | 1721 DCHECK(io_task_runner_->RunsTasksInCurrentSequence()); |
| 1721 VLOG(1) << "Proxy configuration changed"; | 1722 VLOG(1) << "Proxy configuration changed"; |
| 1722 cached_config_ = new_config; | 1723 cached_config_ = new_config; |
| 1723 for (auto& observer : observers_) | 1724 for (auto& observer : observers_) |
| 1724 observer.OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID); | 1725 observer.OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID); |
| 1725 } | 1726 } |
| 1726 | 1727 |
| 1727 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() { | 1728 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() { |
| 1728 if (!setting_getter_) | 1729 if (!setting_getter_) |
| 1729 return; | 1730 return; |
| 1730 | 1731 |
| 1731 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = | 1732 scoped_refptr<base::SequencedTaskRunner> shutdown_loop = |
| 1732 setting_getter_->GetNotificationTaskRunner(); | 1733 setting_getter_->GetNotificationTaskRunner(); |
| 1733 if (!shutdown_loop.get() || shutdown_loop->BelongsToCurrentThread()) { | 1734 if (!shutdown_loop.get() || shutdown_loop->RunsTasksInCurrentSequence()) { |
| 1734 // Already on the right thread, call directly. | 1735 // Already on the right thread, call directly. |
| 1735 // This is the case for the unittests. | 1736 // This is the case for the unittests. |
| 1736 OnDestroy(); | 1737 OnDestroy(); |
| 1737 } else { | 1738 } else { |
| 1738 // Post to shutdown thread. Note that on browser shutdown, we may quit | 1739 // Post to shutdown thread. Note that on browser shutdown, we may quit |
| 1739 // this MessageLoop and exit the program before ever running this. | 1740 // this MessageLoop and exit the program before ever running this. |
| 1740 shutdown_loop->PostTask(FROM_HERE, base::Bind( | 1741 shutdown_loop->PostTask(FROM_HERE, base::Bind( |
| 1741 &ProxyConfigServiceLinux::Delegate::OnDestroy, this)); | 1742 &ProxyConfigServiceLinux::Delegate::OnDestroy, this)); |
| 1742 } | 1743 } |
| 1743 } | 1744 } |
| 1744 void ProxyConfigServiceLinux::Delegate::OnDestroy() { | 1745 void ProxyConfigServiceLinux::Delegate::OnDestroy() { |
| 1745 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = | 1746 scoped_refptr<base::SequencedTaskRunner> shutdown_loop = |
| 1746 setting_getter_->GetNotificationTaskRunner(); | 1747 setting_getter_->GetNotificationTaskRunner(); |
| 1747 DCHECK(!shutdown_loop.get() || shutdown_loop->BelongsToCurrentThread()); | 1748 DCHECK(!shutdown_loop.get() || shutdown_loop->RunsTasksInCurrentSequence()); |
| 1748 setting_getter_->ShutDown(); | 1749 setting_getter_->ShutDown(); |
| 1749 } | 1750 } |
| 1750 | 1751 |
| 1751 ProxyConfigServiceLinux::ProxyConfigServiceLinux() | 1752 ProxyConfigServiceLinux::ProxyConfigServiceLinux() |
| 1752 : delegate_(new Delegate(base::Environment::Create())) { | 1753 : delegate_(new Delegate(base::Environment::Create())) { |
| 1753 } | 1754 } |
| 1754 | 1755 |
| 1755 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() { | 1756 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() { |
| 1756 delegate_->PostDestroyTask(); | 1757 delegate_->PostDestroyTask(); |
| 1757 } | 1758 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1772 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { | 1773 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { |
| 1773 delegate_->RemoveObserver(observer); | 1774 delegate_->RemoveObserver(observer); |
| 1774 } | 1775 } |
| 1775 | 1776 |
| 1776 ProxyConfigService::ConfigAvailability | 1777 ProxyConfigService::ConfigAvailability |
| 1777 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { | 1778 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { |
| 1778 return delegate_->GetLatestProxyConfig(config); | 1779 return delegate_->GetLatestProxyConfig(config); |
| 1779 } | 1780 } |
| 1780 | 1781 |
| 1781 } // namespace net | 1782 } // namespace net |
| OLD | NEW |