| 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 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #if defined(USE_GCONF) | 9 #if defined(USE_GCONF) |
| 10 #include <gconf/gconf-client.h> | 10 #include <gconf/gconf-client.h> |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 // have the same lifetimes. (For instance, incognito sessions get their | 278 // have the same lifetimes. (For instance, incognito sessions get their |
| 279 // own, which is destroyed when the session ends.) | 279 // own, which is destroyed when the session ends.) |
| 280 gconf_client_notify_remove(client_, system_http_proxy_id_); | 280 gconf_client_notify_remove(client_, system_http_proxy_id_); |
| 281 gconf_client_notify_remove(client_, system_proxy_id_); | 281 gconf_client_notify_remove(client_, system_proxy_id_); |
| 282 gconf_client_remove_dir(client_, "/system/http_proxy", NULL); | 282 gconf_client_remove_dir(client_, "/system/http_proxy", NULL); |
| 283 gconf_client_remove_dir(client_, "/system/proxy", NULL); | 283 gconf_client_remove_dir(client_, "/system/proxy", NULL); |
| 284 g_object_unref(client_); | 284 g_object_unref(client_); |
| 285 client_ = NULL; | 285 client_ = NULL; |
| 286 task_runner_ = NULL; | 286 task_runner_ = NULL; |
| 287 } | 287 } |
| 288 debounce_timer_.reset(); |
| 288 } | 289 } |
| 289 | 290 |
| 290 virtual bool SetUpNotifications( | 291 virtual bool SetUpNotifications( |
| 291 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { | 292 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { |
| 292 DCHECK(client_); | 293 DCHECK(client_); |
| 293 DCHECK(task_runner_->BelongsToCurrentThread()); | 294 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 294 GError* error = NULL; | 295 GError* error = NULL; |
| 295 notify_delegate_ = delegate; | 296 notify_delegate_ = delegate; |
| 296 // We have to keep track of the IDs returned by gconf_client_notify_add() so | 297 // We have to keep track of the IDs returned by gconf_client_notify_add() so |
| 297 // that we can remove them in ShutDown(). (Otherwise, notifications will be | 298 // that we can remove them in ShutDown(). (Otherwise, notifications will be |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 | 466 |
| 466 // This is the callback from the debounce timer. | 467 // This is the callback from the debounce timer. |
| 467 void OnDebouncedNotification() { | 468 void OnDebouncedNotification() { |
| 468 DCHECK(task_runner_->BelongsToCurrentThread()); | 469 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 469 CHECK(notify_delegate_); | 470 CHECK(notify_delegate_); |
| 470 // Forward to a method on the proxy config service delegate object. | 471 // Forward to a method on the proxy config service delegate object. |
| 471 notify_delegate_->OnCheckProxyConfigSettings(); | 472 notify_delegate_->OnCheckProxyConfigSettings(); |
| 472 } | 473 } |
| 473 | 474 |
| 474 void OnChangeNotification() { | 475 void OnChangeNotification() { |
| 476 if (!debounce_timer_.get()) |
| 477 debounce_timer_.reset(new base::OneShotTimer<SettingGetterImplGConf>()); |
| 475 // We don't use Reset() because the timer may not yet be running. | 478 // We don't use Reset() because the timer may not yet be running. |
| 476 // (In that case Stop() is a no-op.) | 479 // (In that case Stop() is a no-op.) |
| 477 debounce_timer_.Stop(); | 480 debounce_timer_->Stop(); |
| 478 debounce_timer_.Start(FROM_HERE, | 481 debounce_timer_->Start(FROM_HERE, |
| 479 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), | 482 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), |
| 480 this, &SettingGetterImplGConf::OnDebouncedNotification); | 483 this, &SettingGetterImplGConf::OnDebouncedNotification); |
| 481 } | 484 } |
| 482 | 485 |
| 483 // gconf notification callback, dispatched on the default glib main loop. | 486 // gconf notification callback, dispatched on the default glib main loop. |
| 484 static void OnGConfChangeNotification(GConfClient* client, guint cnxn_id, | 487 static void OnGConfChangeNotification(GConfClient* client, guint cnxn_id, |
| 485 GConfEntry* entry, gpointer user_data) { | 488 GConfEntry* entry, gpointer user_data) { |
| 486 VLOG(1) << "gconf change notification for key " | 489 VLOG(1) << "gconf change notification for key " |
| 487 << gconf_entry_get_key(entry); | 490 << gconf_entry_get_key(entry); |
| 488 // We don't track which key has changed, just that something did change. | 491 // We don't track which key has changed, just that something did change. |
| 489 SettingGetterImplGConf* setting_getter = | 492 SettingGetterImplGConf* setting_getter = |
| 490 reinterpret_cast<SettingGetterImplGConf*>(user_data); | 493 reinterpret_cast<SettingGetterImplGConf*>(user_data); |
| 491 setting_getter->OnChangeNotification(); | 494 setting_getter->OnChangeNotification(); |
| 492 } | 495 } |
| 493 | 496 |
| 494 GConfClient* client_; | 497 GConfClient* client_; |
| 495 // These ids are the values returned from gconf_client_notify_add(), which we | 498 // These ids are the values returned from gconf_client_notify_add(), which we |
| 496 // will need in order to later call gconf_client_notify_remove(). | 499 // will need in order to later call gconf_client_notify_remove(). |
| 497 guint system_proxy_id_; | 500 guint system_proxy_id_; |
| 498 guint system_http_proxy_id_; | 501 guint system_http_proxy_id_; |
| 499 | 502 |
| 500 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 503 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 501 base::OneShotTimer<SettingGetterImplGConf> debounce_timer_; | 504 scoped_ptr<base::OneShotTimer<SettingGetterImplGConf> > debounce_timer_; |
| 502 | 505 |
| 503 // Task runner for the thread that we make gconf calls on. It should | 506 // Task runner for the thread that we make gconf calls on. It should |
| 504 // be the UI thread and all our methods should be called on this | 507 // be the UI thread and all our methods should be called on this |
| 505 // thread. Only for assertions. | 508 // thread. Only for assertions. |
| 506 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 509 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 507 | 510 |
| 508 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf); | 511 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGConf); |
| 509 }; | 512 }; |
| 510 #endif // defined(USE_GCONF) | 513 #endif // defined(USE_GCONF) |
| 511 | 514 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 // This also disables gsettings notifications. | 606 // This also disables gsettings notifications. |
| 604 g_object_unref(socks_client_); | 607 g_object_unref(socks_client_); |
| 605 g_object_unref(ftp_client_); | 608 g_object_unref(ftp_client_); |
| 606 g_object_unref(https_client_); | 609 g_object_unref(https_client_); |
| 607 g_object_unref(http_client_); | 610 g_object_unref(http_client_); |
| 608 g_object_unref(client_); | 611 g_object_unref(client_); |
| 609 // We only need to null client_ because it's the only one that we check. | 612 // We only need to null client_ because it's the only one that we check. |
| 610 client_ = NULL; | 613 client_ = NULL; |
| 611 task_runner_ = NULL; | 614 task_runner_ = NULL; |
| 612 } | 615 } |
| 616 debounce_timer_.reset(); |
| 613 } | 617 } |
| 614 | 618 |
| 615 virtual bool SetUpNotifications( | 619 virtual bool SetUpNotifications( |
| 616 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { | 620 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { |
| 617 DCHECK(client_); | 621 DCHECK(client_); |
| 618 DCHECK(task_runner_->BelongsToCurrentThread()); | 622 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 619 notify_delegate_ = delegate; | 623 notify_delegate_ = delegate; |
| 620 // We could watch for the change-event signal instead of changed, but | 624 // We could watch for the change-event signal instead of changed, but |
| 621 // since we have to watch more than one object, we'd still have to | 625 // since we have to watch more than one object, we'd still have to |
| 622 // debounce change notifications. This is conceptually simpler. | 626 // debounce change notifications. This is conceptually simpler. |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 | 784 |
| 781 // This is the callback from the debounce timer. | 785 // This is the callback from the debounce timer. |
| 782 void OnDebouncedNotification() { | 786 void OnDebouncedNotification() { |
| 783 DCHECK(task_runner_->BelongsToCurrentThread()); | 787 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 784 CHECK(notify_delegate_); | 788 CHECK(notify_delegate_); |
| 785 // Forward to a method on the proxy config service delegate object. | 789 // Forward to a method on the proxy config service delegate object. |
| 786 notify_delegate_->OnCheckProxyConfigSettings(); | 790 notify_delegate_->OnCheckProxyConfigSettings(); |
| 787 } | 791 } |
| 788 | 792 |
| 789 void OnChangeNotification() { | 793 void OnChangeNotification() { |
| 794 if (!debounce_timer_.get()) |
| 795 debounce_timer_.reset( |
| 796 new base::OneShotTimer<SettingGetterImplGSettings>()); |
| 790 // We don't use Reset() because the timer may not yet be running. | 797 // We don't use Reset() because the timer may not yet be running. |
| 791 // (In that case Stop() is a no-op.) | 798 // (In that case Stop() is a no-op.) |
| 792 debounce_timer_.Stop(); | 799 debounce_timer_->Stop(); |
| 793 debounce_timer_.Start(FROM_HERE, | 800 debounce_timer_->Start(FROM_HERE, |
| 794 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), | 801 base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), |
| 795 this, &SettingGetterImplGSettings::OnDebouncedNotification); | 802 this, &SettingGetterImplGSettings::OnDebouncedNotification); |
| 796 } | 803 } |
| 797 | 804 |
| 798 // gsettings notification callback, dispatched on the default glib main loop. | 805 // gsettings notification callback, dispatched on the default glib main loop. |
| 799 static void OnGSettingsChangeNotification(GSettings* client, gchar* key, | 806 static void OnGSettingsChangeNotification(GSettings* client, gchar* key, |
| 800 gpointer user_data) { | 807 gpointer user_data) { |
| 801 VLOG(1) << "gsettings change notification for key " << key; | 808 VLOG(1) << "gsettings change notification for key " << key; |
| 802 // We don't track which key has changed, just that something did change. | 809 // We don't track which key has changed, just that something did change. |
| 803 SettingGetterImplGSettings* setting_getter = | 810 SettingGetterImplGSettings* setting_getter = |
| 804 reinterpret_cast<SettingGetterImplGSettings*>(user_data); | 811 reinterpret_cast<SettingGetterImplGSettings*>(user_data); |
| 805 setting_getter->OnChangeNotification(); | 812 setting_getter->OnChangeNotification(); |
| 806 } | 813 } |
| 807 | 814 |
| 808 GSettings* client_; | 815 GSettings* client_; |
| 809 GSettings* http_client_; | 816 GSettings* http_client_; |
| 810 GSettings* https_client_; | 817 GSettings* https_client_; |
| 811 GSettings* ftp_client_; | 818 GSettings* ftp_client_; |
| 812 GSettings* socks_client_; | 819 GSettings* socks_client_; |
| 813 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 820 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 814 base::OneShotTimer<SettingGetterImplGSettings> debounce_timer_; | 821 scoped_ptr<base::OneShotTimer<SettingGetterImplGSettings> > debounce_timer_; |
| 815 | 822 |
| 816 // Task runner for the thread that we make gsettings calls on. It should | 823 // Task runner for the thread that we make gsettings calls on. It should |
| 817 // be the UI thread and all our methods should be called on this | 824 // be the UI thread and all our methods should be called on this |
| 818 // thread. Only for assertions. | 825 // thread. Only for assertions. |
| 819 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 826 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 820 | 827 |
| 821 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings); | 828 DISALLOW_COPY_AND_ASSIGN(SettingGetterImplGSettings); |
| 822 }; | 829 }; |
| 823 | 830 |
| 824 bool SettingGetterImplGSettings::LoadAndCheckVersion( | 831 bool SettingGetterImplGSettings::LoadAndCheckVersion( |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 return true; | 1011 return true; |
| 1005 } | 1012 } |
| 1006 | 1013 |
| 1007 virtual void ShutDown() OVERRIDE { | 1014 virtual void ShutDown() OVERRIDE { |
| 1008 if (inotify_fd_ >= 0) { | 1015 if (inotify_fd_ >= 0) { |
| 1009 ResetCachedSettings(); | 1016 ResetCachedSettings(); |
| 1010 inotify_watcher_.StopWatchingFileDescriptor(); | 1017 inotify_watcher_.StopWatchingFileDescriptor(); |
| 1011 close(inotify_fd_); | 1018 close(inotify_fd_); |
| 1012 inotify_fd_ = -1; | 1019 inotify_fd_ = -1; |
| 1013 } | 1020 } |
| 1021 debounce_timer_.reset(); |
| 1014 } | 1022 } |
| 1015 | 1023 |
| 1016 virtual bool SetUpNotifications( | 1024 virtual bool SetUpNotifications( |
| 1017 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { | 1025 ProxyConfigServiceLinux::Delegate* delegate) OVERRIDE { |
| 1018 DCHECK(inotify_fd_ >= 0); | 1026 DCHECK(inotify_fd_ >= 0); |
| 1019 DCHECK(MessageLoop::current() == file_loop_); | 1027 DCHECK(MessageLoop::current() == file_loop_); |
| 1020 // We can't just watch the kioslaverc file directly, since KDE will write | 1028 // We can't just watch the kioslaverc file directly, since KDE will write |
| 1021 // a new copy of it and then rename it whenever settings are changed and | 1029 // a new copy of it and then rename it whenever settings are changed and |
| 1022 // inotify watches inodes (so we'll be watching the old deleted file after | 1030 // inotify watches inodes (so we'll be watching the old deleted file after |
| 1023 // the first change, and it will never change again). So, we watch the | 1031 // the first change, and it will never change again). So, we watch the |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 // would be forever ready to read. Close it and stop watching instead. | 1363 // would be forever ready to read. Close it and stop watching instead. |
| 1356 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!"; | 1364 LOG(ERROR) << "inotify failure; no longer watching kioslaverc!"; |
| 1357 inotify_watcher_.StopWatchingFileDescriptor(); | 1365 inotify_watcher_.StopWatchingFileDescriptor(); |
| 1358 close(inotify_fd_); | 1366 close(inotify_fd_); |
| 1359 inotify_fd_ = -1; | 1367 inotify_fd_ = -1; |
| 1360 } | 1368 } |
| 1361 } | 1369 } |
| 1362 if (kioslaverc_touched) { | 1370 if (kioslaverc_touched) { |
| 1363 // We don't use Reset() because the timer may not yet be running. | 1371 // We don't use Reset() because the timer may not yet be running. |
| 1364 // (In that case Stop() is a no-op.) | 1372 // (In that case Stop() is a no-op.) |
| 1365 debounce_timer_.Stop(); | 1373 if (!debounce_timer_.get()) |
| 1366 debounce_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( | 1374 debounce_timer_.reset(new base::OneShotTimer<SettingGetterImplKDE>()); |
| 1375 debounce_timer_->Stop(); |
| 1376 debounce_timer_->Start(FROM_HERE, base::TimeDelta::FromMilliseconds( |
| 1367 kDebounceTimeoutMilliseconds), this, | 1377 kDebounceTimeoutMilliseconds), this, |
| 1368 &SettingGetterImplKDE::OnDebouncedNotification); | 1378 &SettingGetterImplKDE::OnDebouncedNotification); |
| 1369 } | 1379 } |
| 1370 } | 1380 } |
| 1371 | 1381 |
| 1372 typedef std::map<StringSetting, std::string> string_map_type; | 1382 typedef std::map<StringSetting, std::string> string_map_type; |
| 1373 typedef std::map<StringListSetting, | 1383 typedef std::map<StringListSetting, |
| 1374 std::vector<std::string> > strings_map_type; | 1384 std::vector<std::string> > strings_map_type; |
| 1375 | 1385 |
| 1376 int inotify_fd_; | 1386 int inotify_fd_; |
| 1377 base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_; | 1387 base::MessagePumpLibevent::FileDescriptorWatcher inotify_watcher_; |
| 1378 ProxyConfigServiceLinux::Delegate* notify_delegate_; | 1388 ProxyConfigServiceLinux::Delegate* notify_delegate_; |
| 1379 base::OneShotTimer<SettingGetterImplKDE> debounce_timer_; | 1389 scoped_ptr<base::OneShotTimer<SettingGetterImplKDE> > debounce_timer_; |
| 1380 FilePath kde_config_dir_; | 1390 FilePath kde_config_dir_; |
| 1381 bool indirect_manual_; | 1391 bool indirect_manual_; |
| 1382 bool auto_no_pac_; | 1392 bool auto_no_pac_; |
| 1383 bool reversed_bypass_list_; | 1393 bool reversed_bypass_list_; |
| 1384 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since | 1394 // We don't own |env_var_getter_|. It's safe to hold a pointer to it, since |
| 1385 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the | 1395 // both it and us are owned by ProxyConfigServiceLinux::Delegate, and have the |
| 1386 // same lifetime. | 1396 // same lifetime. |
| 1387 base::Environment* env_var_getter_; | 1397 base::Environment* env_var_getter_; |
| 1388 | 1398 |
| 1389 // We cache these settings whenever we re-read the kioslaverc file. | 1399 // We cache these settings whenever we re-read the kioslaverc file. |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 setting_getter_.reset(new SettingGetterImplKDE(env_var_getter)); | 1607 setting_getter_.reset(new SettingGetterImplKDE(env_var_getter)); |
| 1598 break; | 1608 break; |
| 1599 case base::nix::DESKTOP_ENVIRONMENT_XFCE: | 1609 case base::nix::DESKTOP_ENVIRONMENT_XFCE: |
| 1600 case base::nix::DESKTOP_ENVIRONMENT_OTHER: | 1610 case base::nix::DESKTOP_ENVIRONMENT_OTHER: |
| 1601 break; | 1611 break; |
| 1602 } | 1612 } |
| 1603 } | 1613 } |
| 1604 | 1614 |
| 1605 ProxyConfigServiceLinux::Delegate::Delegate( | 1615 ProxyConfigServiceLinux::Delegate::Delegate( |
| 1606 base::Environment* env_var_getter, SettingGetter* setting_getter) | 1616 base::Environment* env_var_getter, SettingGetter* setting_getter) |
| 1607 : env_var_getter_(env_var_getter), setting_getter_(setting_getter) { | 1617 : env_var_getter_(env_var_getter), setting_getter_(setting_getter), |
| 1618 finished_initialization_(false) { |
| 1608 } | 1619 } |
| 1609 | 1620 |
| 1610 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( | 1621 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( |
| 1611 base::SingleThreadTaskRunner* glib_thread_task_runner, | 1622 base::SingleThreadTaskRunner* glib_thread_task_runner, |
| 1612 base::SingleThreadTaskRunner* io_thread_task_runner, | 1623 base::SingleThreadTaskRunner* io_thread_task_runner, |
| 1613 MessageLoopForIO* file_loop) { | 1624 MessageLoopForIO* file_loop) { |
| 1625 DCHECK(io_thread_task_runner->BelongsToCurrentThread()); |
| 1626 |
| 1627 glib_thread_task_runner_ = glib_thread_task_runner; |
| 1628 io_thread_task_runner_ = io_thread_task_runner; |
| 1629 |
| 1630 glib_thread_task_runner->PostTask(FROM_HERE, base::Bind( |
| 1631 &Delegate::SetUpAndFetchInitialConfigOnUIThread, |
| 1632 this, |
| 1633 file_loop)); |
| 1634 } |
| 1635 |
| 1636 void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfigOnUIThread( |
| 1637 MessageLoopForIO* file_loop) { |
| 1614 // We should be running on the default glib main loop thread right | 1638 // We should be running on the default glib main loop thread right |
| 1615 // now. gconf can only be accessed from this thread. | 1639 // now. gconf can only be accessed from this thread. |
| 1616 DCHECK(glib_thread_task_runner->BelongsToCurrentThread()); | 1640 DCHECK(glib_thread_task_runner_->BelongsToCurrentThread()); |
| 1617 glib_thread_task_runner_ = glib_thread_task_runner; | |
| 1618 io_thread_task_runner_ = io_thread_task_runner; | |
| 1619 | 1641 |
| 1620 // If we are passed a NULL |io_thread_task_runner| or |file_loop|, | 1642 // If we are passed a NULL |io_thread_task_runner| or |file_loop|, |
| 1621 // then we don't set up proxy setting change notifications. This | 1643 // then we don't set up proxy setting change notifications. This |
| 1622 // should not be the usual case but is intended to simplify test | 1644 // should not be the usual case but is intended to simplify test |
| 1623 // setups. | 1645 // setups. |
| 1624 if (!io_thread_task_runner_ || !file_loop) | 1646 if (!io_thread_task_runner_ || !file_loop) |
| 1625 VLOG(1) << "Monitoring of proxy setting changes is disabled"; | 1647 VLOG(1) << "Monitoring of proxy setting changes is disabled"; |
| 1626 | 1648 |
| 1627 // Fetch and cache the current proxy config. The config is left in | 1649 // Fetch and cache the current proxy config. The config is left in |
| 1628 // cached_config_, where GetLatestProxyConfig() running on the IO thread | 1650 // cached_config_, where GetLatestProxyConfig() running on the IO thread |
| 1629 // will expect to find it. This is safe to do because we return | 1651 // will expect to find it. This is safe to do because we return |
| 1630 // before this ProxyConfigServiceLinux is passed on to | 1652 // before this ProxyConfigServiceLinux is passed on to |
| 1631 // the ProxyService. | 1653 // the ProxyService. |
| 1632 | 1654 |
| 1633 // Note: It would be nice to prioritize environment variables | 1655 // Note: It would be nice to prioritize environment variables |
| 1634 // and only fall back to gconf if env vars were unset. But | 1656 // and only fall back to gconf if env vars were unset. But |
| 1635 // gnome-terminal "helpfully" sets http_proxy and no_proxy, and it | 1657 // gnome-terminal "helpfully" sets http_proxy and no_proxy, and it |
| 1636 // does so even if the proxy mode is set to auto, which would | 1658 // does so even if the proxy mode is set to auto, which would |
| 1637 // mislead us. | 1659 // mislead us. |
| 1638 | 1660 |
| 1639 bool got_config = false; | 1661 bool got_config = false; |
| 1640 if (setting_getter_.get() && | 1662 if (setting_getter_.get() && |
| 1641 setting_getter_->Init(glib_thread_task_runner, file_loop) && | 1663 setting_getter_->Init(glib_thread_task_runner_, file_loop) && |
| 1642 GetConfigFromSettings(&cached_config_)) { | 1664 GetConfigFromSettings(&reference_config_)) { |
| 1643 cached_config_.set_id(1); // Mark it as valid. | 1665 reference_config_.set_id(1); // Mark it as valid. |
| 1644 cached_config_.set_source(setting_getter_->GetConfigSource()); | 1666 reference_config_.set_source(setting_getter_->GetConfigSource()); |
| 1645 VLOG(1) << "Obtained proxy settings from " | 1667 VLOG(1) << "Obtained proxy settings from " |
| 1646 << ProxyConfigSourceToString(cached_config_.source()); | 1668 << ProxyConfigSourceToString(reference_config_.source()); |
| 1647 | 1669 |
| 1648 // If gconf proxy mode is "none", meaning direct, then we take | 1670 // If gconf proxy mode is "none", meaning direct, then we take |
| 1649 // that to be a valid config and will not check environment | 1671 // that to be a valid config and will not check environment |
| 1650 // variables. The alternative would have been to look for a proxy | 1672 // variables. The alternative would have been to look for a proxy |
| 1651 // whereever we can find one. | 1673 // whereever we can find one. |
| 1652 got_config = true; | 1674 got_config = true; |
| 1653 | 1675 |
| 1654 // Keep a copy of the config for use from this thread for | |
| 1655 // comparison with updated settings when we get notifications. | |
| 1656 reference_config_ = cached_config_; | |
| 1657 reference_config_.set_id(1); // Mark it as valid. | |
| 1658 | |
| 1659 // We only set up notifications if we have IO and file loops available. | 1676 // We only set up notifications if we have IO and file loops available. |
| 1660 // We do this after getting the initial configuration so that we don't have | 1677 // We do this after getting the initial configuration so that we don't have |
| 1661 // to worry about cancelling it if the initial fetch above fails. Note that | 1678 // to worry about cancelling it if the initial fetch above fails. Note that |
| 1662 // setting up notifications has the side effect of simulating a change, so | 1679 // setting up notifications has the side effect of simulating a change, so |
| 1663 // that we won't lose any updates that may have happened after the initial | 1680 // that we won't lose any updates that may have happened after the initial |
| 1664 // fetch and before setting up notifications. We'll detect the common case | 1681 // fetch and before setting up notifications. We'll detect the common case |
| 1665 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it. | 1682 // of no changes in OnCheckProxyConfigSettings() (or sooner) and ignore it. |
| 1666 if (io_thread_task_runner && file_loop) { | 1683 if (io_thread_task_runner_ && file_loop) { |
| 1667 scoped_refptr<base::SingleThreadTaskRunner> required_loop = | 1684 scoped_refptr<base::SingleThreadTaskRunner> required_loop = |
| 1668 setting_getter_->GetNotificationTaskRunner(); | 1685 setting_getter_->GetNotificationTaskRunner(); |
| 1669 if (!required_loop || required_loop->BelongsToCurrentThread()) { | 1686 if (!required_loop || required_loop->BelongsToCurrentThread()) { |
| 1670 // In this case we are already on an acceptable thread. | 1687 // In this case we are already on an acceptable thread. |
| 1671 SetUpNotifications(); | 1688 SetUpNotifications(); |
| 1672 } else { | 1689 } else { |
| 1673 // Post a task to set up notifications. We don't wait for success. | 1690 // Post a task to set up notifications. We don't wait for success. |
| 1674 required_loop->PostTask(FROM_HERE, base::Bind( | 1691 required_loop->PostTask(FROM_HERE, base::Bind( |
| 1675 &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this)); | 1692 &ProxyConfigServiceLinux::Delegate::SetUpNotifications, this)); |
| 1676 } | 1693 } |
| 1677 } | 1694 } |
| 1678 } | 1695 } |
| 1679 | 1696 |
| 1680 if (!got_config) { | 1697 if (!got_config) { |
| 1681 // We fall back on environment variables. | 1698 // We fall back on environment variables. |
| 1682 // | 1699 // |
| 1683 // Consulting environment variables doesn't need to be done from the | 1700 // Consulting environment variables doesn't need to be done from the |
| 1684 // default glib main loop, but it's a tiny enough amount of work. | 1701 // default glib main loop, but it's a tiny enough amount of work. |
| 1685 if (GetConfigFromEnv(&cached_config_)) { | 1702 if (GetConfigFromEnv(&reference_config_)) { |
| 1686 cached_config_.set_source(PROXY_CONFIG_SOURCE_ENV); | 1703 reference_config_.set_source(PROXY_CONFIG_SOURCE_ENV); |
| 1687 cached_config_.set_id(1); // Mark it as valid. | 1704 reference_config_.set_id(1); // Mark it as valid. |
| 1688 VLOG(1) << "Obtained proxy settings from environment variables"; | 1705 VLOG(1) << "Obtained proxy settings from environment variables"; |
| 1689 } | 1706 } |
| 1690 } | 1707 } |
| 1708 |
| 1709 // Post a task to the IO thread with the new configuration, so it can |
| 1710 // update |cached_config_|. |
| 1711 io_thread_task_runner_->PostTask(FROM_HERE, base::Bind( |
| 1712 &ProxyConfigServiceLinux::Delegate::SetNewProxyConfig, |
| 1713 this, reference_config_)); |
| 1691 } | 1714 } |
| 1692 | 1715 |
| 1693 // Depending on the SettingGetter in use, this method will be called | 1716 // Depending on the SettingGetter in use, this method will be called |
| 1694 // on either the UI thread (GConf) or the file thread (KDE). | 1717 // on either the UI thread (GConf) or the file thread (KDE). |
| 1695 void ProxyConfigServiceLinux::Delegate::SetUpNotifications() { | 1718 void ProxyConfigServiceLinux::Delegate::SetUpNotifications() { |
| 1696 scoped_refptr<base::SingleThreadTaskRunner> required_loop = | 1719 scoped_refptr<base::SingleThreadTaskRunner> required_loop = |
| 1697 setting_getter_->GetNotificationTaskRunner(); | 1720 setting_getter_->GetNotificationTaskRunner(); |
| 1698 DCHECK(!required_loop || required_loop->BelongsToCurrentThread()); | 1721 DCHECK(!required_loop || required_loop->BelongsToCurrentThread()); |
| 1699 if (!setting_getter_->SetUpNotifications(this)) | 1722 if (!setting_getter_->SetUpNotifications(this)) |
| 1700 LOG(ERROR) << "Unable to set up proxy configuration change notifications"; | 1723 LOG(ERROR) << "Unable to set up proxy configuration change notifications"; |
| 1701 } | 1724 } |
| 1702 | 1725 |
| 1703 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) { | 1726 void ProxyConfigServiceLinux::Delegate::AddObserver(Observer* observer) { |
| 1704 observers_.AddObserver(observer); | 1727 observers_.AddObserver(observer); |
| 1705 } | 1728 } |
| 1706 | 1729 |
| 1707 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) { | 1730 void ProxyConfigServiceLinux::Delegate::RemoveObserver(Observer* observer) { |
| 1708 observers_.RemoveObserver(observer); | 1731 observers_.RemoveObserver(observer); |
| 1709 } | 1732 } |
| 1710 | 1733 |
| 1711 ProxyConfigService::ConfigAvailability | 1734 ProxyConfigService::ConfigAvailability |
| 1712 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig( | 1735 ProxyConfigServiceLinux::Delegate::GetLatestProxyConfig( |
| 1713 ProxyConfig* config) { | 1736 ProxyConfig* config) { |
| 1714 // This is called from the IO thread. | 1737 // This is called from the IO thread. |
| 1715 DCHECK(!io_thread_task_runner_ || | 1738 DCHECK(!io_thread_task_runner_ || |
| 1716 io_thread_task_runner_->BelongsToCurrentThread()); | 1739 io_thread_task_runner_->BelongsToCurrentThread()); |
| 1717 | 1740 |
| 1741 if (!finished_initialization_) |
| 1742 return CONFIG_PENDING; |
| 1743 |
| 1718 // Simply return the last proxy configuration that glib_default_loop | 1744 // Simply return the last proxy configuration that glib_default_loop |
| 1719 // notified us of. | 1745 // notified us of. |
| 1720 if (cached_config_.is_valid()) { | 1746 if (cached_config_.is_valid()) { |
| 1721 *config = cached_config_; | 1747 *config = cached_config_; |
| 1722 } else { | 1748 } else { |
| 1723 *config = ProxyConfig::CreateDirect(); | 1749 *config = ProxyConfig::CreateDirect(); |
| 1724 config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED); | 1750 config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED); |
| 1725 } | 1751 } |
| 1726 | 1752 |
| 1727 // We return CONFIG_VALID to indicate that *config was filled in. It is always | 1753 // We return CONFIG_VALID to indicate that *config was filled in. |
| 1728 // going to be available since we initialized eagerly on the UI thread. | |
| 1729 // TODO(eroman): do lazy initialization instead, so we no longer need | |
| 1730 // to construct ProxyConfigServiceLinux on the UI thread. | |
| 1731 // In which case, we may return false here. | |
| 1732 return CONFIG_VALID; | 1754 return CONFIG_VALID; |
| 1733 } | 1755 } |
| 1734 | 1756 |
| 1735 // Depending on the SettingGetter in use, this method will be called | 1757 // Depending on the SettingGetter in use, this method will be called |
| 1736 // on either the UI thread (GConf) or the file thread (KDE). | 1758 // on either the UI thread (GConf) or the file thread (KDE). |
| 1737 void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() { | 1759 void ProxyConfigServiceLinux::Delegate::OnCheckProxyConfigSettings() { |
| 1738 scoped_refptr<base::SingleThreadTaskRunner> required_loop = | 1760 scoped_refptr<base::SingleThreadTaskRunner> required_loop = |
| 1739 setting_getter_->GetNotificationTaskRunner(); | 1761 setting_getter_->GetNotificationTaskRunner(); |
| 1740 DCHECK(!required_loop || required_loop->BelongsToCurrentThread()); | 1762 DCHECK(!required_loop || required_loop->BelongsToCurrentThread()); |
| 1741 ProxyConfig new_config; | 1763 ProxyConfig new_config; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1756 } else { | 1778 } else { |
| 1757 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing."; | 1779 VLOG(1) << "Detected no-op change to proxy settings. Doing nothing."; |
| 1758 } | 1780 } |
| 1759 } | 1781 } |
| 1760 | 1782 |
| 1761 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig( | 1783 void ProxyConfigServiceLinux::Delegate::SetNewProxyConfig( |
| 1762 const ProxyConfig& new_config) { | 1784 const ProxyConfig& new_config) { |
| 1763 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); | 1785 DCHECK(io_thread_task_runner_->BelongsToCurrentThread()); |
| 1764 VLOG(1) << "Proxy configuration changed"; | 1786 VLOG(1) << "Proxy configuration changed"; |
| 1765 cached_config_ = new_config; | 1787 cached_config_ = new_config; |
| 1788 finished_initialization_ = true; |
| 1766 FOR_EACH_OBSERVER( | 1789 FOR_EACH_OBSERVER( |
| 1767 Observer, observers_, | 1790 Observer, observers_, |
| 1768 OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID)); | 1791 OnProxyConfigChanged(new_config, ProxyConfigService::CONFIG_VALID)); |
| 1769 } | 1792 } |
| 1770 | 1793 |
| 1771 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() { | 1794 void ProxyConfigServiceLinux::Delegate::PostDestroyTask() { |
| 1772 if (!setting_getter_.get()) | 1795 if (!setting_getter_.get()) |
| 1773 return; | 1796 return; |
| 1774 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = | 1797 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = |
| 1775 setting_getter_->GetNotificationTaskRunner(); | 1798 setting_getter_->GetNotificationTaskRunner(); |
| 1776 if (!shutdown_loop || shutdown_loop->BelongsToCurrentThread()) { | 1799 if (!shutdown_loop || shutdown_loop->BelongsToCurrentThread()) { |
| 1777 // Already on the right thread, call directly. | 1800 // Already on the right thread, call directly. |
| 1778 // This is the case for the unittests. | 1801 // This is the case for the unittests. |
| 1779 OnDestroy(); | 1802 OnDestroy(); |
| 1780 } else { | 1803 } else { |
| 1781 // Post to shutdown thread. Note that on browser shutdown, we may quit | 1804 // Post to shutdown thread. Note that on browser shutdown, we may quit |
| 1782 // this MessageLoop and exit the program before ever running this. | 1805 // this MessageLoop and exit the program before ever running this. |
| 1783 shutdown_loop->PostTask(FROM_HERE, base::Bind( | 1806 shutdown_loop->PostTask(FROM_HERE, base::Bind( |
| 1784 &ProxyConfigServiceLinux::Delegate::OnDestroy, this)); | 1807 &ProxyConfigServiceLinux::Delegate::OnDestroy, this)); |
| 1785 } | 1808 } |
| 1786 } | 1809 } |
| 1810 |
| 1787 void ProxyConfigServiceLinux::Delegate::OnDestroy() { | 1811 void ProxyConfigServiceLinux::Delegate::OnDestroy() { |
| 1788 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = | 1812 scoped_refptr<base::SingleThreadTaskRunner> shutdown_loop = |
| 1789 setting_getter_->GetNotificationTaskRunner(); | 1813 setting_getter_->GetNotificationTaskRunner(); |
| 1790 DCHECK(!shutdown_loop || shutdown_loop->BelongsToCurrentThread()); | 1814 DCHECK(!shutdown_loop || shutdown_loop->BelongsToCurrentThread()); |
| 1791 setting_getter_->ShutDown(); | 1815 setting_getter_->ShutDown(); |
| 1792 } | 1816 } |
| 1793 | 1817 |
| 1794 ProxyConfigServiceLinux::ProxyConfigServiceLinux() | 1818 |
| 1819 ProxyConfigServiceLinux::ProxyConfigServiceLinux( |
| 1820 base::SingleThreadTaskRunner* glib_thread_task_runner, |
| 1821 base::SingleThreadTaskRunner* io_thread_task_runner, |
| 1822 MessageLoopForIO* file_loop) |
| 1795 : delegate_(new Delegate(base::Environment::Create())) { | 1823 : delegate_(new Delegate(base::Environment::Create())) { |
| 1824 SetupAndFetchInitialConfig(glib_thread_task_runner, |
| 1825 io_thread_task_runner, |
| 1826 file_loop); |
| 1796 } | 1827 } |
| 1797 | 1828 |
| 1798 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() { | 1829 ProxyConfigServiceLinux::~ProxyConfigServiceLinux() { |
| 1830 } |
| 1831 |
| 1832 void ProxyConfigServiceLinux::StartTearDown() { |
| 1799 delegate_->PostDestroyTask(); | 1833 delegate_->PostDestroyTask(); |
| 1800 } | 1834 } |
| 1801 | 1835 |
| 1802 ProxyConfigServiceLinux::ProxyConfigServiceLinux( | 1836 ProxyConfigServiceLinux::ProxyConfigServiceLinux( |
| 1803 base::Environment* env_var_getter) | 1837 base::Environment* env_var_getter) |
| 1804 : delegate_(new Delegate(env_var_getter)) { | 1838 : delegate_(new Delegate(env_var_getter)) { |
| 1805 } | 1839 } |
| 1806 | 1840 |
| 1807 ProxyConfigServiceLinux::ProxyConfigServiceLinux( | 1841 ProxyConfigServiceLinux::ProxyConfigServiceLinux( |
| 1808 base::Environment* env_var_getter, SettingGetter* setting_getter) | 1842 base::Environment* env_var_getter, SettingGetter* setting_getter) |
| 1809 : delegate_(new Delegate(env_var_getter, setting_getter)) { | 1843 : delegate_(new Delegate(env_var_getter, setting_getter)) { |
| 1810 } | 1844 } |
| 1811 | 1845 |
| 1812 void ProxyConfigServiceLinux::AddObserver(Observer* observer) { | 1846 void ProxyConfigServiceLinux::AddObserver(Observer* observer) { |
| 1813 delegate_->AddObserver(observer); | 1847 delegate_->AddObserver(observer); |
| 1814 } | 1848 } |
| 1815 | 1849 |
| 1816 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { | 1850 void ProxyConfigServiceLinux::RemoveObserver(Observer* observer) { |
| 1817 delegate_->RemoveObserver(observer); | 1851 delegate_->RemoveObserver(observer); |
| 1818 } | 1852 } |
| 1819 | 1853 |
| 1820 ProxyConfigService::ConfigAvailability | 1854 ProxyConfigService::ConfigAvailability |
| 1821 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { | 1855 ProxyConfigServiceLinux::GetLatestProxyConfig(ProxyConfig* config) { |
| 1822 return delegate_->GetLatestProxyConfig(config); | 1856 return delegate_->GetLatestProxyConfig(config); |
| 1823 } | 1857 } |
| 1824 | 1858 |
| 1825 } // namespace net | 1859 } // namespace net |
| OLD | NEW |