| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/devtools/device/devtools_android_bridge.h" | 5 #include "chrome/browser/devtools/device/devtools_android_bridge.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 const int kMinVersionNewWithURL = 32; | 57 const int kMinVersionNewWithURL = 32; |
| 58 const int kNewPageNavigateDelayMs = 500; | 58 const int kNewPageNavigateDelayMs = 500; |
| 59 | 59 |
| 60 // DiscoveryRequest ----------------------------------------------------- | 60 // DiscoveryRequest ----------------------------------------------------- |
| 61 | 61 |
| 62 class DiscoveryRequest : public base::RefCountedThreadSafe< | 62 class DiscoveryRequest : public base::RefCountedThreadSafe< |
| 63 DiscoveryRequest, | 63 DiscoveryRequest, |
| 64 BrowserThread::DeleteOnUIThread> { | 64 BrowserThread::DeleteOnUIThread> { |
| 65 public: | 65 public: |
| 66 typedef base::Callback<void(scoped_ptr<DevToolsAndroidBridge::RemoteDevices>)> | 66 typedef base::Callback<void(const DevToolsAndroidBridge::RemoteDevices&)> |
| 67 DiscoveryCallback; | 67 DiscoveryCallback; |
| 68 typedef AndroidDeviceManager::Device Device; | 68 typedef AndroidDeviceManager::Device Device; |
| 69 typedef AndroidDeviceManager::Devices Devices; | 69 typedef AndroidDeviceManager::Devices Devices; |
| 70 | 70 |
| 71 DiscoveryRequest( | 71 DiscoveryRequest( |
| 72 AndroidDeviceManager* device_manager, | 72 AndroidDeviceManager* device_manager, |
| 73 const DiscoveryCallback& callback); | 73 const DiscoveryCallback& callback); |
| 74 | 74 |
| 75 private: | 75 private: |
| 76 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; | 76 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 92 } | 92 } |
| 93 | 93 |
| 94 void NextBrowser(); | 94 void NextBrowser(); |
| 95 void NextDevice(); | 95 void NextDevice(); |
| 96 | 96 |
| 97 void Respond(); | 97 void Respond(); |
| 98 | 98 |
| 99 DiscoveryCallback callback_; | 99 DiscoveryCallback callback_; |
| 100 Devices devices_; | 100 Devices devices_; |
| 101 DevToolsAndroidBridge::RemoteBrowsers browsers_; | 101 DevToolsAndroidBridge::RemoteBrowsers browsers_; |
| 102 scoped_ptr<DevToolsAndroidBridge::RemoteDevices> remote_devices_; | 102 DevToolsAndroidBridge::RemoteDevices remote_devices_; |
| 103 }; | 103 }; |
| 104 | 104 |
| 105 DiscoveryRequest::DiscoveryRequest( | 105 DiscoveryRequest::DiscoveryRequest( |
| 106 AndroidDeviceManager* device_manager, | 106 AndroidDeviceManager* device_manager, |
| 107 const DiscoveryCallback& callback) | 107 const DiscoveryCallback& callback) |
| 108 : callback_(callback) { | 108 : callback_(callback) { |
| 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 110 remote_devices_.reset(new DevToolsAndroidBridge::RemoteDevices()); | |
| 111 | 110 |
| 112 device_manager->QueryDevices( | 111 device_manager->QueryDevices( |
| 113 base::Bind(&DiscoveryRequest::ReceivedDevices, this)); | 112 base::Bind(&DiscoveryRequest::ReceivedDevices, this)); |
| 114 } | 113 } |
| 115 | 114 |
| 116 DiscoveryRequest::~DiscoveryRequest() { | 115 DiscoveryRequest::~DiscoveryRequest() { |
| 117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 118 } | 117 } |
| 119 | 118 |
| 120 void DiscoveryRequest::ReceivedDevices(const Devices& devices) { | 119 void DiscoveryRequest::ReceivedDevices(const Devices& devices) { |
| 121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 122 devices_ = devices; | 121 devices_ = devices; |
| 123 ProcessDevices(); | 122 ProcessDevices(); |
| 124 } | 123 } |
| 125 | 124 |
| 126 void DiscoveryRequest::ProcessDevices() { | 125 void DiscoveryRequest::ProcessDevices() { |
| 127 if (devices_.size() == 0) { | 126 if (devices_.size() == 0) { |
| 128 Respond(); | 127 Respond(); |
| 129 return; | 128 return; |
| 130 } | 129 } |
| 131 | 130 |
| 132 current_device()->QueryDeviceInfo( | 131 current_device()->QueryDeviceInfo( |
| 133 base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this)); | 132 base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this)); |
| 134 } | 133 } |
| 135 | 134 |
| 136 void DiscoveryRequest::ReceivedDeviceInfo( | 135 void DiscoveryRequest::ReceivedDeviceInfo( |
| 137 const AndroidDeviceManager::DeviceInfo& device_info) { | 136 const AndroidDeviceManager::DeviceInfo& device_info) { |
| 138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 139 remote_devices_->push_back( | 138 remote_devices_.push_back( |
| 140 new DevToolsAndroidBridge::RemoteDevice(current_device(), device_info)); | 139 new DevToolsAndroidBridge::RemoteDevice(current_device(), device_info)); |
| 141 browsers_ = remote_devices_->back()->browsers(); | 140 browsers_ = remote_devices_.back()->browsers(); |
| 142 ProcessSockets(); | 141 ProcessSockets(); |
| 143 } | 142 } |
| 144 | 143 |
| 145 void DiscoveryRequest::ProcessSockets() { | 144 void DiscoveryRequest::ProcessSockets() { |
| 146 if (browsers_.size() == 0) { | 145 if (browsers_.size() == 0) { |
| 147 NextDevice(); | 146 NextDevice(); |
| 148 return; | 147 return; |
| 149 } | 148 } |
| 150 | 149 |
| 151 current_device()->SendJsonRequest( | 150 current_device()->SendJsonRequest( |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 browsers_.pop_back(); | 204 browsers_.pop_back(); |
| 206 ProcessSockets(); | 205 ProcessSockets(); |
| 207 } | 206 } |
| 208 | 207 |
| 209 void DiscoveryRequest::NextDevice() { | 208 void DiscoveryRequest::NextDevice() { |
| 210 devices_.pop_back(); | 209 devices_.pop_back(); |
| 211 ProcessDevices(); | 210 ProcessDevices(); |
| 212 } | 211 } |
| 213 | 212 |
| 214 void DiscoveryRequest::Respond() { | 213 void DiscoveryRequest::Respond() { |
| 215 callback_.Run(remote_devices_.Pass()); | 214 callback_.Run(remote_devices_); |
| 216 } | 215 } |
| 217 | 216 |
| 218 // ProtocolCommand ------------------------------------------------------------ | 217 // ProtocolCommand ------------------------------------------------------------ |
| 219 | 218 |
| 220 class ProtocolCommand | 219 class ProtocolCommand |
| 221 : public DevToolsAndroidBridge::AndroidWebSocket::Delegate { | 220 : public DevToolsAndroidBridge::AndroidWebSocket::Delegate { |
| 222 public: | 221 public: |
| 223 ProtocolCommand( | 222 ProtocolCommand( |
| 224 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, | 223 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, |
| 225 const std::string& debug_url, | 224 const std::string& debug_url, |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 device_->OpenSocket(socket_name, callback); | 758 device_->OpenSocket(socket_name, callback); |
| 760 } | 759 } |
| 761 | 760 |
| 762 DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() { | 761 DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() { |
| 763 } | 762 } |
| 764 | 763 |
| 765 // DevToolsAndroidBridge ------------------------------------------------------ | 764 // DevToolsAndroidBridge ------------------------------------------------------ |
| 766 | 765 |
| 767 DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile) | 766 DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile) |
| 768 : profile_(profile), | 767 : profile_(profile), |
| 769 device_manager_(AndroidDeviceManager::Create()) { | 768 device_manager_(AndroidDeviceManager::Create()), |
| 769 task_scheduler_(base::Bind(&DevToolsAndroidBridge::ScheduleTaskDefault)) { |
| 770 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 770 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 771 pref_change_registrar_.Init(profile_->GetPrefs()); | 771 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 772 pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled, | 772 pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled, |
| 773 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders, | 773 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders, |
| 774 base::Unretained(this))); | 774 base::Unretained(this))); |
| 775 CreateDeviceProviders(); | 775 CreateDeviceProviders(); |
| 776 } | 776 } |
| 777 | 777 |
| 778 void DevToolsAndroidBridge::AddDeviceListListener( | 778 void DevToolsAndroidBridge::AddDeviceListListener( |
| 779 DeviceListListener* listener) { | 779 DeviceListListener* listener) { |
| 780 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 780 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 781 device_list_listeners_.push_back(listener); | 781 device_list_listeners_.push_back(listener); |
| 782 if (device_list_listeners_.size() == 1) | 782 if (device_list_listeners_.size() == 1) |
| 783 RequestDeviceList(); | 783 StartDeviceListPolling(); |
| 784 } | 784 } |
| 785 | 785 |
| 786 void DevToolsAndroidBridge::RemoveDeviceListListener( | 786 void DevToolsAndroidBridge::RemoveDeviceListListener( |
| 787 DeviceListListener* listener) { | 787 DeviceListListener* listener) { |
| 788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 789 DeviceListListeners::iterator it = std::find( | 789 DeviceListListeners::iterator it = std::find( |
| 790 device_list_listeners_.begin(), device_list_listeners_.end(), listener); | 790 device_list_listeners_.begin(), device_list_listeners_.end(), listener); |
| 791 DCHECK(it != device_list_listeners_.end()); | 791 DCHECK(it != device_list_listeners_.end()); |
| 792 device_list_listeners_.erase(it); | 792 device_list_listeners_.erase(it); |
| 793 if (device_list_listeners_.empty()) | 793 if (device_list_listeners_.empty()) |
| 794 devices_.clear(); | 794 StopDeviceListPolling(); |
| 795 } | 795 } |
| 796 | 796 |
| 797 void DevToolsAndroidBridge::AddDeviceCountListener( | 797 void DevToolsAndroidBridge::AddDeviceCountListener( |
| 798 DeviceCountListener* listener) { | 798 DeviceCountListener* listener) { |
| 799 device_count_listeners_.push_back(listener); | 799 device_count_listeners_.push_back(listener); |
| 800 if (device_count_listeners_.size() == 1) | 800 if (device_count_listeners_.size() == 1) |
| 801 RequestDeviceCount(); | 801 StartDeviceCountPolling(); |
| 802 } | 802 } |
| 803 | 803 |
| 804 void DevToolsAndroidBridge::RemoveDeviceCountListener( | 804 void DevToolsAndroidBridge::RemoveDeviceCountListener( |
| 805 DeviceCountListener* listener) { | 805 DeviceCountListener* listener) { |
| 806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 807 DeviceCountListeners::iterator it = std::find( | 807 DeviceCountListeners::iterator it = std::find( |
| 808 device_count_listeners_.begin(), device_count_listeners_.end(), listener); | 808 device_count_listeners_.begin(), device_count_listeners_.end(), listener); |
| 809 DCHECK(it != device_count_listeners_.end()); | 809 DCHECK(it != device_count_listeners_.end()); |
| 810 device_count_listeners_.erase(it); | 810 device_count_listeners_.erase(it); |
| 811 if (device_count_listeners_.empty()) |
| 812 StopDeviceCountPolling(); |
| 811 } | 813 } |
| 812 | 814 |
| 813 // static | 815 // static |
| 814 bool DevToolsAndroidBridge::HasDevToolsWindow(const std::string& agent_id) { | 816 bool DevToolsAndroidBridge::HasDevToolsWindow(const std::string& agent_id) { |
| 815 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 816 return g_host_delegates.Get().find(agent_id) != g_host_delegates.Get().end(); | 818 return g_host_delegates.Get().find(agent_id) != g_host_delegates.Get().end(); |
| 817 } | 819 } |
| 818 | 820 |
| 819 DevToolsAndroidBridge::~DevToolsAndroidBridge() { | 821 DevToolsAndroidBridge::~DevToolsAndroidBridge() { |
| 820 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 822 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 821 DCHECK(device_list_listeners_.empty()); | 823 DCHECK(device_list_listeners_.empty()); |
| 822 DCHECK(device_count_listeners_.empty()); | 824 DCHECK(device_count_listeners_.empty()); |
| 823 } | 825 } |
| 824 | 826 |
| 825 void DevToolsAndroidBridge::RequestDeviceList() { | 827 void DevToolsAndroidBridge::StartDeviceListPolling() { |
| 828 device_list_callback_.Reset( |
| 829 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this)); |
| 830 RequestDeviceList(device_list_callback_.callback()); |
| 831 } |
| 832 |
| 833 void DevToolsAndroidBridge::StopDeviceListPolling() { |
| 834 device_list_callback_.Cancel(); |
| 835 devices_.clear(); |
| 836 } |
| 837 |
| 838 void DevToolsAndroidBridge::RequestDeviceList( |
| 839 const base::Callback<void(const RemoteDevices&)>& callback) { |
| 826 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 840 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 827 | 841 |
| 842 if (device_list_listeners_.empty() || |
| 843 !callback.Equals(device_list_callback_.callback())) |
| 844 return; |
| 845 |
| 846 new DiscoveryRequest(device_manager_.get(), callback); |
| 847 } |
| 848 |
| 849 void DevToolsAndroidBridge::ReceivedDeviceList(const RemoteDevices& devices) { |
| 850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 851 |
| 852 DeviceListListeners copy(device_list_listeners_); |
| 853 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it) |
| 854 (*it)->DeviceListChanged(devices); |
| 855 |
| 828 if (device_list_listeners_.empty()) | 856 if (device_list_listeners_.empty()) |
| 829 return; | 857 return; |
| 830 | 858 |
| 831 new DiscoveryRequest( | 859 devices_ = devices; |
| 832 device_manager_.get(), | 860 |
| 833 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this)); | 861 task_scheduler_.Run( |
| 862 base::Bind(&DevToolsAndroidBridge::RequestDeviceList, |
| 863 this, device_list_callback_.callback())); |
| 834 } | 864 } |
| 835 | 865 |
| 836 void DevToolsAndroidBridge::ReceivedDeviceList( | 866 void DevToolsAndroidBridge::StartDeviceCountPolling() { |
| 837 scoped_ptr<RemoteDevices> devices) { | 867 device_count_callback_.Reset( |
| 868 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, this)); |
| 869 RequestDeviceCount(device_count_callback_.callback()); |
| 870 } |
| 871 |
| 872 void DevToolsAndroidBridge::StopDeviceCountPolling() { |
| 873 device_count_callback_.Cancel(); |
| 874 } |
| 875 |
| 876 void DevToolsAndroidBridge::RequestDeviceCount( |
| 877 const base::Callback<void(int)>& callback) { |
| 838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 878 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 839 | 879 |
| 840 if (device_list_listeners_.empty()) | 880 if (device_count_listeners_.empty() || |
| 881 !callback.Equals(device_count_callback_.callback())) |
| 841 return; | 882 return; |
| 842 | 883 |
| 843 devices_ = *devices; | 884 UsbDeviceProvider::CountDevices(callback); |
| 844 | |
| 845 DeviceListListeners copy(device_list_listeners_); | |
| 846 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it) | |
| 847 (*it)->DeviceListChanged(*devices.get()); | |
| 848 | |
| 849 BrowserThread::PostDelayedTask( | |
| 850 BrowserThread::UI, | |
| 851 FROM_HERE, | |
| 852 base::Bind(&DevToolsAndroidBridge::RequestDeviceList, this), | |
| 853 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); | |
| 854 } | |
| 855 | |
| 856 void DevToolsAndroidBridge::RequestDeviceCount() { | |
| 857 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 858 | |
| 859 if (device_count_listeners_.empty()) | |
| 860 return; | |
| 861 | |
| 862 UsbDeviceProvider::CountDevices( | |
| 863 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, this)); | |
| 864 } | 885 } |
| 865 | 886 |
| 866 void DevToolsAndroidBridge::ReceivedDeviceCount(int count) { | 887 void DevToolsAndroidBridge::ReceivedDeviceCount(int count) { |
| 867 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 888 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 868 | 889 |
| 869 if (device_count_listeners_.empty()) | |
| 870 return; | |
| 871 | |
| 872 DeviceCountListeners copy(device_count_listeners_); | 890 DeviceCountListeners copy(device_count_listeners_); |
| 873 for (DeviceCountListeners::iterator it = copy.begin(); it != copy.end(); ++it) | 891 for (DeviceCountListeners::iterator it = copy.begin(); it != copy.end(); ++it) |
| 874 (*it)->DeviceCountChanged(count); | 892 (*it)->DeviceCountChanged(count); |
| 875 | 893 |
| 894 if (device_count_listeners_.empty()) |
| 895 return; |
| 896 |
| 897 task_scheduler_.Run( |
| 898 base::Bind(&DevToolsAndroidBridge::RequestDeviceCount, |
| 899 this, device_count_callback_.callback())); |
| 900 } |
| 901 |
| 902 // static |
| 903 void DevToolsAndroidBridge::ScheduleTaskDefault(const base::Closure& task) { |
| 876 BrowserThread::PostDelayedTask( | 904 BrowserThread::PostDelayedTask( |
| 877 BrowserThread::UI, | 905 BrowserThread::UI, |
| 878 FROM_HERE, | 906 FROM_HERE, |
| 879 base::Bind(&DevToolsAndroidBridge::RequestDeviceCount, this), | 907 task, |
| 880 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); | 908 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); |
| 881 } | 909 } |
| 882 | 910 |
| 883 void DevToolsAndroidBridge::CreateDeviceProviders() { | 911 void DevToolsAndroidBridge::CreateDeviceProviders() { |
| 884 AndroidDeviceManager::DeviceProviders device_providers; | 912 AndroidDeviceManager::DeviceProviders device_providers; |
| 885 #if defined(DEBUG_DEVTOOLS) | 913 #if defined(DEBUG_DEVTOOLS) |
| 886 BrowserListTabContentsProvider::EnableTethering(); | 914 BrowserListTabContentsProvider::EnableTethering(); |
| 887 // We cannot rely on command line switch here as we might want to connect | 915 // We cannot rely on command line switch here as we might want to connect |
| 888 // to another instance of Chrome. Using hard-coded port number instead. | 916 // to another instance of Chrome. Using hard-coded port number instead. |
| 889 const int kDefaultDebuggingPort = 9222; | 917 const int kDefaultDebuggingPort = 9222; |
| 890 device_providers.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort)); | 918 device_providers.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort)); |
| 891 #endif | 919 #endif |
| 892 device_providers.push_back(new AdbDeviceProvider()); | 920 device_providers.push_back(new AdbDeviceProvider()); |
| 893 | 921 |
| 894 PrefService* service = profile_->GetPrefs(); | 922 PrefService* service = profile_->GetPrefs(); |
| 895 const PrefService::Preference* pref = | 923 const PrefService::Preference* pref = |
| 896 service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled); | 924 service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled); |
| 897 const base::Value* pref_value = pref->GetValue(); | 925 const base::Value* pref_value = pref->GetValue(); |
| 898 | 926 |
| 899 bool enabled; | 927 bool enabled; |
| 900 if (pref_value->GetAsBoolean(&enabled) && enabled) { | 928 if (pref_value->GetAsBoolean(&enabled) && enabled) { |
| 901 device_providers.push_back(new UsbDeviceProvider(profile_)); | 929 device_providers.push_back(new UsbDeviceProvider(profile_)); |
| 902 } | 930 } |
| 903 device_manager_->SetDeviceProviders(device_providers); | 931 device_manager_->SetDeviceProviders(device_providers); |
| 932 if (!device_list_listeners_.empty()) { |
| 933 StopDeviceListPolling(); |
| 934 StartDeviceListPolling(); |
| 935 } |
| 904 } | 936 } |
| OLD | NEW |