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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 const char kModelOffline[] = "Offline"; | 44 const char kModelOffline[] = "Offline"; |
45 | 45 |
46 const char kPageListRequest[] = "/json"; | 46 const char kPageListRequest[] = "/json"; |
47 const char kVersionRequest[] = "/json/version"; | 47 const char kVersionRequest[] = "/json/version"; |
48 const char kClosePageRequest[] = "/json/close/%s"; | 48 const char kClosePageRequest[] = "/json/close/%s"; |
49 const char kNewPageRequest[] = "/json/new"; | 49 const char kNewPageRequest[] = "/json/new"; |
50 const char kNewPageRequestWithURL[] = "/json/new?%s"; | 50 const char kNewPageRequestWithURL[] = "/json/new?%s"; |
51 const char kActivatePageRequest[] = "/json/activate/%s"; | 51 const char kActivatePageRequest[] = "/json/activate/%s"; |
52 const char kBrowserTargetSocket[] = "/devtools/browser"; | 52 const char kBrowserTargetSocket[] = "/devtools/browser"; |
53 const int kAdbPollingIntervalMs = 1000; | |
54 | 53 |
55 const char kUrlParam[] = "url"; | 54 const char kUrlParam[] = "url"; |
56 const char kPageReloadCommand[] = "Page.reload"; | 55 const char kPageReloadCommand[] = "Page.reload"; |
57 const char kPageNavigateCommand[] = "Page.navigate"; | 56 const char kPageNavigateCommand[] = "Page.navigate"; |
58 | 57 |
59 const int kMinVersionNewWithURL = 32; | 58 const int kMinVersionNewWithURL = 32; |
60 const int kNewPageNavigateDelayMs = 500; | 59 const int kNewPageNavigateDelayMs = 500; |
61 | 60 |
62 // DiscoveryRequest ----------------------------------------------------- | 61 // DiscoveryRequest ----------------------------------------------------- |
63 | 62 |
(...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 if (!thread_) | 836 if (!thread_) |
838 return; | 837 return; |
839 // Shut down thread on FILE thread to join into IO. | 838 // Shut down thread on FILE thread to join into IO. |
840 BrowserThread::PostTask( | 839 BrowserThread::PostTask( |
841 BrowserThread::FILE, FROM_HERE, | 840 BrowserThread::FILE, FROM_HERE, |
842 base::Bind(&HandlerThread::StopThread, thread_)); | 841 base::Bind(&HandlerThread::StopThread, thread_)); |
843 } | 842 } |
844 | 843 |
845 // DevToolsAndroidBridge ------------------------------------------------------ | 844 // DevToolsAndroidBridge ------------------------------------------------------ |
846 | 845 |
| 846 const int DevToolsAndroidBridge::kAdbPollingIntervalMs = 1000; |
| 847 |
847 DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile) | 848 DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile) |
848 : profile_(profile), | 849 : profile_(profile), |
849 handler_thread_(HandlerThread::GetInstance()) { | 850 handler_thread_(HandlerThread::GetInstance()) { |
850 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 851 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
851 pref_change_registrar_.Init(profile_->GetPrefs()); | 852 pref_change_registrar_.Init(profile_->GetPrefs()); |
852 pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled, | 853 pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled, |
853 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders, | 854 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders, |
854 base::Unretained(this))); | 855 base::Unretained(this))); |
855 CreateDeviceProviders(); | 856 CreateDeviceProviders(); |
856 base::PostTaskAndReplyWithResult( | 857 base::PostTaskAndReplyWithResult( |
857 device_message_loop()->message_loop_proxy(), | 858 device_message_loop()->message_loop_proxy(), |
858 FROM_HERE, | 859 FROM_HERE, |
859 base::Bind(&AndroidDeviceManager::Create), | 860 base::Bind(&AndroidDeviceManager::Create), |
860 base::Bind(&DevToolsAndroidBridge::CreatedDeviceManager, this)); | 861 base::Bind(&DevToolsAndroidBridge::CreatedDeviceManager, this)); |
861 } | 862 } |
862 | 863 |
863 void DevToolsAndroidBridge::AddDeviceListListener( | 864 void DevToolsAndroidBridge::AddDeviceListListener( |
864 DeviceListListener* listener) { | 865 DeviceListListener* listener) { |
865 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 866 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
866 device_list_listeners_.push_back(listener); | 867 device_list_listeners_.push_back(listener); |
867 if (device_list_listeners_.size() == 1 && device_manager_) | 868 if (device_list_listeners_.size() == 1 && device_manager_) |
868 RequestDeviceList(); | 869 StartDeviceListPollingLoop(); |
869 } | 870 } |
870 | 871 |
871 void DevToolsAndroidBridge::RemoveDeviceListListener( | 872 void DevToolsAndroidBridge::RemoveDeviceListListener( |
872 DeviceListListener* listener) { | 873 DeviceListListener* listener) { |
873 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 874 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
874 DeviceListListeners::iterator it = std::find( | 875 DeviceListListeners::iterator it = std::find( |
875 device_list_listeners_.begin(), device_list_listeners_.end(), listener); | 876 device_list_listeners_.begin(), device_list_listeners_.end(), listener); |
876 DCHECK(it != device_list_listeners_.end()); | 877 DCHECK(it != device_list_listeners_.end()); |
877 device_list_listeners_.erase(it); | 878 device_list_listeners_.erase(it); |
878 if (device_list_listeners_.empty() && device_manager_) { | 879 if (device_list_listeners_.empty() && device_manager_) { |
879 device_message_loop()->PostTask(FROM_HERE, | 880 device_message_loop()->PostTask(FROM_HERE, |
880 base::Bind(&AndroidDeviceManager::Stop, device_manager_)); | 881 base::Bind(&AndroidDeviceManager::Stop, device_manager_)); |
| 882 StopDeviceListPollingLoop(); |
881 } | 883 } |
882 } | 884 } |
883 | 885 |
884 void DevToolsAndroidBridge::AddDeviceCountListener( | 886 void DevToolsAndroidBridge::AddDeviceCountListener( |
885 DeviceCountListener* listener) { | 887 DeviceCountListener* listener) { |
886 device_count_listeners_.push_back(listener); | 888 device_count_listeners_.push_back(listener); |
887 if (device_count_listeners_.size() == 1 && device_manager_) | 889 if (device_count_listeners_.size() == 1 && device_manager_) |
888 RequestDeviceCount(); | 890 StartDeviceCountPollingLoop(); |
889 } | 891 } |
890 | 892 |
891 void DevToolsAndroidBridge::RemoveDeviceCountListener( | 893 void DevToolsAndroidBridge::RemoveDeviceCountListener( |
892 DeviceCountListener* listener) { | 894 DeviceCountListener* listener) { |
893 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 895 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
894 DeviceCountListeners::iterator it = std::find( | 896 DeviceCountListeners::iterator it = std::find( |
895 device_count_listeners_.begin(), device_count_listeners_.end(), listener); | 897 device_count_listeners_.begin(), device_count_listeners_.end(), listener); |
896 DCHECK(it != device_count_listeners_.end()); | 898 DCHECK(it != device_count_listeners_.end()); |
897 device_count_listeners_.erase(it); | 899 device_count_listeners_.erase(it); |
| 900 if (device_count_listeners_.empty()) |
| 901 StopDeviceCountPollingLoop(); |
898 } | 902 } |
899 | 903 |
900 // static | 904 // static |
901 bool DevToolsAndroidBridge::HasDevToolsWindow(const std::string& agent_id) { | 905 bool DevToolsAndroidBridge::HasDevToolsWindow(const std::string& agent_id) { |
902 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 906 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
903 return g_host_delegates.Get().find(agent_id) != g_host_delegates.Get().end(); | 907 return g_host_delegates.Get().find(agent_id) != g_host_delegates.Get().end(); |
904 } | 908 } |
905 | 909 |
906 DevToolsAndroidBridge::~DevToolsAndroidBridge() { | 910 DevToolsAndroidBridge::~DevToolsAndroidBridge() { |
907 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 911 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
908 DCHECK(device_list_listeners_.empty()); | 912 DCHECK(device_list_listeners_.empty()); |
909 DCHECK(device_count_listeners_.empty()); | 913 DCHECK(device_count_listeners_.empty()); |
910 if (device_manager_) { | 914 if (device_manager_) { |
911 AndroidDeviceManager* raw_ptr = device_manager_.get(); | 915 AndroidDeviceManager* raw_ptr = device_manager_.get(); |
912 device_manager_->AddRef(); | 916 device_manager_->AddRef(); |
913 device_manager_ = NULL; | 917 device_manager_ = NULL; |
914 device_message_loop()->ReleaseSoon(FROM_HERE, raw_ptr); | 918 device_message_loop()->ReleaseSoon(FROM_HERE, raw_ptr); |
915 } | 919 } |
916 } | 920 } |
917 | 921 |
| 922 void DevToolsAndroidBridge::CreatedDeviceManager( |
| 923 scoped_refptr<AndroidDeviceManager> device_manager) { |
| 924 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 925 device_manager_ = device_manager; |
| 926 if (!device_list_listeners_.empty()) |
| 927 StartDeviceListPollingLoop(); |
| 928 if (!device_count_listeners_.empty()) |
| 929 StartDeviceCountPollingLoop(); |
| 930 } |
| 931 |
918 void DevToolsAndroidBridge::RequestDeviceList() { | 932 void DevToolsAndroidBridge::RequestDeviceList() { |
919 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 933 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
920 DCHECK(device_manager_); | 934 DCHECK(device_manager_); |
921 | 935 |
922 if (device_list_listeners_.empty()) | 936 if (device_list_listeners_.empty()) |
923 return; | 937 return; |
924 | 938 |
925 new DiscoveryRequest( | 939 new DiscoveryRequest(this, |
926 this, | 940 device_manager(), |
927 device_manager(), | 941 device_message_loop(), |
928 device_message_loop(), | 942 device_providers_, |
929 device_providers_, | 943 received_device_list_bound_.callback()); |
930 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this)); | |
931 } | |
932 | |
933 void DevToolsAndroidBridge::CreatedDeviceManager( | |
934 scoped_refptr<AndroidDeviceManager> device_manager) { | |
935 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
936 device_manager_ = device_manager; | |
937 if (!device_list_listeners_.empty()) | |
938 RequestDeviceList(); | |
939 if (!device_count_listeners_.empty()) | |
940 RequestDeviceCount(); | |
941 } | 944 } |
942 | 945 |
943 void DevToolsAndroidBridge::ReceivedDeviceList(RemoteDevices* devices_ptr) { | 946 void DevToolsAndroidBridge::ReceivedDeviceList(RemoteDevices* devices_ptr) { |
944 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 947 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
945 | 948 |
946 scoped_ptr<RemoteDevices> devices(devices_ptr); | 949 scoped_ptr<RemoteDevices> devices(devices_ptr); |
947 | 950 |
948 if (device_list_listeners_.empty()) | |
949 return; | |
950 | |
951 DeviceListListeners copy(device_list_listeners_); | 951 DeviceListListeners copy(device_list_listeners_); |
952 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it) | 952 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it) |
953 (*it)->DeviceListChanged(*devices.get()); | 953 (*it)->DeviceListChanged(*devices.get()); |
954 | 954 |
| 955 if (device_list_listeners_.empty()) |
| 956 return; |
| 957 |
955 BrowserThread::PostDelayedTask( | 958 BrowserThread::PostDelayedTask( |
956 BrowserThread::UI, | 959 BrowserThread::UI, |
957 FROM_HERE, | 960 FROM_HERE, |
958 base::Bind(&DevToolsAndroidBridge::RequestDeviceList, this), | 961 request_device_list_bound_.callback(), |
959 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); | 962 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); |
960 } | 963 } |
961 | 964 |
| 965 void DevToolsAndroidBridge::StartDeviceListPollingLoop() { |
| 966 request_device_list_bound_.Reset( |
| 967 base::Bind(&DevToolsAndroidBridge::RequestDeviceList, this)); |
| 968 received_device_list_bound_.Reset( |
| 969 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this)); |
| 970 RequestDeviceList(); |
| 971 } |
| 972 |
| 973 void DevToolsAndroidBridge::StopDeviceListPollingLoop() { |
| 974 request_device_list_bound_.Cancel(); |
| 975 received_device_list_bound_.Cancel(); |
| 976 } |
| 977 |
962 void DevToolsAndroidBridge::RequestDeviceCount() { | 978 void DevToolsAndroidBridge::RequestDeviceCount() { |
963 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 979 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
964 DCHECK(device_manager_); | 980 DCHECK(device_manager_); |
965 | 981 |
966 if (device_count_listeners_.empty()) | 982 if (device_count_listeners_.empty()) |
967 return; | 983 return; |
968 | 984 |
969 UsbDeviceProvider::CountDevices( | 985 UsbDeviceProvider::CountDevices(received_device_count_bound_.callback()); |
970 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, this)); | |
971 } | 986 } |
972 | 987 |
973 void DevToolsAndroidBridge::ReceivedDeviceCount(int count) { | 988 void DevToolsAndroidBridge::ReceivedDeviceCount(int count) { |
974 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 989 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
975 | 990 |
976 if (device_count_listeners_.empty()) | |
977 return; | |
978 | |
979 DeviceCountListeners copy(device_count_listeners_); | 991 DeviceCountListeners copy(device_count_listeners_); |
980 for (DeviceCountListeners::iterator it = copy.begin(); it != copy.end(); ++it) | 992 for (DeviceCountListeners::iterator it = copy.begin(); it != copy.end(); ++it) |
981 (*it)->DeviceCountChanged(count); | 993 (*it)->DeviceCountChanged(count); |
982 | 994 |
983 BrowserThread::PostDelayedTask( | 995 if (device_count_listeners_.empty()) |
984 BrowserThread::UI, | 996 return; |
985 FROM_HERE, | 997 |
986 base::Bind(&DevToolsAndroidBridge::RequestDeviceCount, this), | 998 ScheduleDeviceCountRequest(request_device_count_bound_.callback()); |
987 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); | 999 } |
| 1000 |
| 1001 void DevToolsAndroidBridge::ScheduleDeviceCountRequest(base::Closure callback) { |
| 1002 if (!device_count_request_scheduler_for_test_.is_null()) |
| 1003 device_count_request_scheduler_for_test_.Run(callback); |
| 1004 else |
| 1005 BrowserThread::PostDelayedTask( |
| 1006 BrowserThread::UI, |
| 1007 FROM_HERE, |
| 1008 callback, |
| 1009 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); |
| 1010 } |
| 1011 |
| 1012 void DevToolsAndroidBridge::StartDeviceCountPollingLoop() { |
| 1013 request_device_count_bound_.Reset( |
| 1014 base::Bind(&DevToolsAndroidBridge::RequestDeviceCount, this)); |
| 1015 received_device_count_bound_.Reset( |
| 1016 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, this)); |
| 1017 RequestDeviceCount(); |
| 1018 } |
| 1019 |
| 1020 void DevToolsAndroidBridge::StopDeviceCountPollingLoop() { |
| 1021 request_device_count_bound_.Cancel(); |
| 1022 received_device_count_bound_.Cancel(); |
988 } | 1023 } |
989 | 1024 |
990 void DevToolsAndroidBridge::CreateDeviceProviders() { | 1025 void DevToolsAndroidBridge::CreateDeviceProviders() { |
991 device_providers_.clear(); | 1026 device_providers_.clear(); |
992 #if defined(DEBUG_DEVTOOLS) | 1027 #if defined(DEBUG_DEVTOOLS) |
993 BrowserListTabContentsProvider::EnableTethering(); | 1028 BrowserListTabContentsProvider::EnableTethering(); |
994 // We cannot rely on command line switch here as we might want to connect | 1029 // We cannot rely on command line switch here as we might want to connect |
995 // to another instance of Chrome. Using hard-coded port number instead. | 1030 // to another instance of Chrome. Using hard-coded port number instead. |
996 const int kDefaultDebuggingPort = 9222; | 1031 const int kDefaultDebuggingPort = 9222; |
997 device_providers_.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort)); | 1032 device_providers_.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort)); |
998 #endif | 1033 #endif |
999 device_providers_.push_back(new AdbDeviceProvider()); | 1034 device_providers_.push_back(new AdbDeviceProvider()); |
1000 | 1035 |
1001 PrefService* service = profile_->GetPrefs(); | 1036 PrefService* service = profile_->GetPrefs(); |
1002 const PrefService::Preference* pref = | 1037 const PrefService::Preference* pref = |
1003 service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled); | 1038 service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled); |
1004 const base::Value* pref_value = pref->GetValue(); | 1039 const base::Value* pref_value = pref->GetValue(); |
1005 | 1040 |
1006 bool enabled; | 1041 bool enabled; |
1007 if (pref_value->GetAsBoolean(&enabled) && enabled) { | 1042 if (pref_value->GetAsBoolean(&enabled) && enabled) { |
1008 device_providers_.push_back(new UsbDeviceProvider(profile_)); | 1043 device_providers_.push_back(new UsbDeviceProvider(profile_)); |
1009 } | 1044 } |
1010 } | 1045 } |
OLD | NEW |