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 "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h
" | 5 #include "extensions/browser/api/bluetooth_low_energy/bluetooth_low_energy_api.h
" |
6 | 6 |
| 7 #include <algorithm> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
9 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
10 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
| 13 #include "extensions/browser/api/bluetooth_low_energy/bluetooth_api_advertisemen
t.h" |
11 #include "extensions/browser/api/bluetooth_low_energy/utils.h" | 14 #include "extensions/browser/api/bluetooth_low_energy/utils.h" |
12 #include "extensions/browser/event_router.h" | 15 #include "extensions/browser/event_router.h" |
13 #include "extensions/common/api/bluetooth/bluetooth_manifest_data.h" | 16 #include "extensions/common/api/bluetooth/bluetooth_manifest_data.h" |
14 #include "extensions/common/api/bluetooth_low_energy.h" | 17 #include "extensions/common/api/bluetooth_low_energy.h" |
15 #include "extensions/common/permissions/permissions_data.h" | 18 #include "extensions/common/permissions/permissions_data.h" |
16 | 19 |
17 using content::BrowserContext; | 20 using content::BrowserContext; |
18 using content::BrowserThread; | 21 using content::BrowserThread; |
19 | 22 |
20 namespace apibtle = extensions::core_api::bluetooth_low_energy; | 23 namespace apibtle = extensions::core_api::bluetooth_low_energy; |
(...skipping 16 matching lines...) Expand all Loading... |
37 const char kErrorNotConnected[] = "Not connected"; | 40 const char kErrorNotConnected[] = "Not connected"; |
38 const char kErrorNotFound[] = "Instance not found"; | 41 const char kErrorNotFound[] = "Instance not found"; |
39 const char kErrorNotNotifying[] = "Not notifying"; | 42 const char kErrorNotNotifying[] = "Not notifying"; |
40 const char kErrorOperationFailed[] = "Operation failed"; | 43 const char kErrorOperationFailed[] = "Operation failed"; |
41 const char kErrorPermissionDenied[] = "Permission denied"; | 44 const char kErrorPermissionDenied[] = "Permission denied"; |
42 const char kErrorPlatformNotSupported[] = | 45 const char kErrorPlatformNotSupported[] = |
43 "This operation is not supported on the current platform"; | 46 "This operation is not supported on the current platform"; |
44 const char kErrorTimeout[] = "Operation timed out"; | 47 const char kErrorTimeout[] = "Operation timed out"; |
45 const char kErrorUnsupportedDevice[] = | 48 const char kErrorUnsupportedDevice[] = |
46 "This device is not supported on the current platform"; | 49 "This device is not supported on the current platform"; |
| 50 const char kErrorInvalidAdvertisementLength[] = "Invalid advertisement length"; |
| 51 const char kStatusAdvertisementAlreadyExists[] = |
| 52 "An advertisement is already advertising"; |
| 53 const char kStatusAdvertisementDoesNotExist[] = |
| 54 "This advertisement does not exist"; |
47 | 55 |
48 // Returns the correct error string based on error status |status|. This is used | 56 // Returns the correct error string based on error status |status|. This is used |
49 // to set the value of |chrome.runtime.lastError.message| and should not be | 57 // to set the value of |chrome.runtime.lastError.message| and should not be |
50 // passed |BluetoothLowEnergyEventRouter::kStatusSuccess|. | 58 // passed |BluetoothLowEnergyEventRouter::kStatusSuccess|. |
51 std::string StatusToString(BluetoothLowEnergyEventRouter::Status status) { | 59 std::string StatusToString(BluetoothLowEnergyEventRouter::Status status) { |
52 switch (status) { | 60 switch (status) { |
53 case BluetoothLowEnergyEventRouter::kStatusErrorPermissionDenied: | 61 case BluetoothLowEnergyEventRouter::kStatusErrorPermissionDenied: |
54 return kErrorPermissionDenied; | 62 return kErrorPermissionDenied; |
55 case BluetoothLowEnergyEventRouter::kStatusErrorNotFound: | 63 case BluetoothLowEnergyEventRouter::kStatusErrorNotFound: |
56 return kErrorNotFound; | 64 return kErrorNotFound; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 BrowserContext* context) { | 101 BrowserContext* context) { |
94 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 102 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
95 return extensions::BluetoothLowEnergyAPI::Get(context)->event_router(); | 103 return extensions::BluetoothLowEnergyAPI::Get(context)->event_router(); |
96 } | 104 } |
97 | 105 |
98 void DoWorkCallback(const base::Callback<bool()>& callback) { | 106 void DoWorkCallback(const base::Callback<bool()>& callback) { |
99 DCHECK(!callback.is_null()); | 107 DCHECK(!callback.is_null()); |
100 callback.Run(); | 108 callback.Run(); |
101 } | 109 } |
102 | 110 |
| 111 scoped_ptr<device::BluetoothAdvertisement::ManufacturerData> |
| 112 CreateManufacturerData( |
| 113 std::vector<linked_ptr<apibtle::ManufacturerData>>* manufacturer_data) { |
| 114 scoped_ptr<device::BluetoothAdvertisement::ManufacturerData> created_data( |
| 115 new device::BluetoothAdvertisement::ManufacturerData()); |
| 116 for (const auto& it : *manufacturer_data) { |
| 117 std::vector<uint8_t> data(it->data.size()); |
| 118 std::copy(it->data.begin(), it->data.end(), data.begin()); |
| 119 (*created_data)[it->id] = data; |
| 120 } |
| 121 return created_data; |
| 122 } |
| 123 |
| 124 scoped_ptr<device::BluetoothAdvertisement::ServiceData> CreateServiceData( |
| 125 std::vector<linked_ptr<apibtle::ServiceData>>* service_data) { |
| 126 scoped_ptr<device::BluetoothAdvertisement::ServiceData> created_data( |
| 127 new device::BluetoothAdvertisement::ServiceData()); |
| 128 for (const auto& it : *service_data) { |
| 129 std::vector<uint8_t> data(it->data.size()); |
| 130 std::copy(it->data.begin(), it->data.end(), data.begin()); |
| 131 (*created_data)[it->uuid] = data; |
| 132 } |
| 133 return created_data; |
| 134 } |
| 135 |
103 } // namespace | 136 } // namespace |
104 | 137 |
105 | 138 |
106 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI> > | 139 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI> > |
107 g_factory = LAZY_INSTANCE_INITIALIZER; | 140 g_factory = LAZY_INSTANCE_INITIALIZER; |
108 | 141 |
109 // static | 142 // static |
110 BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI>* | 143 BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI>* |
111 BluetoothLowEnergyAPI::GetFactoryInstance() { | 144 BluetoothLowEnergyAPI::GetFactoryInstance() { |
112 return g_factory.Pointer(); | 145 return g_factory.Pointer(); |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 results_ = apibtle::WriteDescriptorValue::Results::Create(); | 819 results_ = apibtle::WriteDescriptorValue::Results::Create(); |
787 SendResponse(true); | 820 SendResponse(true); |
788 } | 821 } |
789 | 822 |
790 void BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback( | 823 void BluetoothLowEnergyWriteDescriptorValueFunction::ErrorCallback( |
791 BluetoothLowEnergyEventRouter::Status status) { | 824 BluetoothLowEnergyEventRouter::Status status) { |
792 SetError(StatusToString(status)); | 825 SetError(StatusToString(status)); |
793 SendResponse(false); | 826 SendResponse(false); |
794 } | 827 } |
795 | 828 |
| 829 BluetoothLowEnergyAdvertisementFunction:: |
| 830 BluetoothLowEnergyAdvertisementFunction() |
| 831 : advertisements_manager_(nullptr) { |
| 832 } |
| 833 |
| 834 BluetoothLowEnergyAdvertisementFunction:: |
| 835 ~BluetoothLowEnergyAdvertisementFunction() { |
| 836 } |
| 837 |
| 838 int BluetoothLowEnergyAdvertisementFunction::AddAdvertisement( |
| 839 BluetoothApiAdvertisement* advertisement) { |
| 840 DCHECK(advertisements_manager_); |
| 841 return advertisements_manager_->Add(advertisement); |
| 842 } |
| 843 |
| 844 BluetoothApiAdvertisement* |
| 845 BluetoothLowEnergyAdvertisementFunction::GetAdvertisement( |
| 846 int advertisement_id) { |
| 847 DCHECK(advertisements_manager_); |
| 848 return advertisements_manager_->Get(extension_id(), advertisement_id); |
| 849 } |
| 850 |
| 851 void BluetoothLowEnergyAdvertisementFunction::RemoveAdvertisement( |
| 852 int advertisement_id) { |
| 853 DCHECK(advertisements_manager_); |
| 854 advertisements_manager_->Remove(extension_id(), advertisement_id); |
| 855 } |
| 856 |
| 857 bool BluetoothLowEnergyAdvertisementFunction::RunAsync() { |
| 858 Initialize(); |
| 859 return BluetoothLowEnergyExtensionFunction::RunAsync(); |
| 860 } |
| 861 |
| 862 void BluetoothLowEnergyAdvertisementFunction::Initialize() { |
| 863 advertisements_manager_ = |
| 864 ApiResourceManager<BluetoothApiAdvertisement>::Get(browser_context()); |
| 865 } |
| 866 |
796 // RegisterAdvertisement: | 867 // RegisterAdvertisement: |
797 | 868 |
798 bool BluetoothLowEnergyRegisterAdvertisementFunction::DoWork() { | 869 bool BluetoothLowEnergyRegisterAdvertisementFunction::DoWork() { |
799 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 870 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
800 | 871 |
801 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { | 872 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { |
802 error_ = kErrorPermissionDenied; | 873 error_ = kErrorPermissionDenied; |
803 SendResponse(false); | 874 SendResponse(false); |
804 return false; | 875 return false; |
805 } | 876 } |
806 | 877 |
807 BluetoothLowEnergyEventRouter* event_router = | 878 BluetoothLowEnergyEventRouter* event_router = |
808 GetEventRouter(browser_context()); | 879 GetEventRouter(browser_context()); |
809 | 880 |
810 // The adapter must be initialized at this point, but return an error instead | 881 // The adapter must be initialized at this point, but return an error instead |
811 // of asserting. | 882 // of asserting. |
812 if (!event_router->HasAdapter()) { | 883 if (!event_router->HasAdapter()) { |
813 SetError(kErrorAdapterNotInitialized); | 884 SetError(kErrorAdapterNotInitialized); |
814 SendResponse(false); | 885 SendResponse(false); |
815 return false; | 886 return false; |
816 } | 887 } |
817 | 888 |
818 scoped_ptr<apibtle::RegisterAdvertisement::Params> params( | 889 scoped_ptr<apibtle::RegisterAdvertisement::Params> params( |
819 apibtle::RegisterAdvertisement::Params::Create(*args_)); | 890 apibtle::RegisterAdvertisement::Params::Create(*args_)); |
820 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 891 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
821 | 892 |
822 // TODO(rkc): Implement this function. | 893 scoped_ptr<device::BluetoothAdvertisement::Data> advertisement_data( |
| 894 new device::BluetoothAdvertisement::Data( |
| 895 params->advertisement.type == |
| 896 apibtle::AdvertisementType::ADVERTISEMENT_TYPE_BROADCAST |
| 897 ? device::BluetoothAdvertisement::AdvertisementType:: |
| 898 ADVERTISEMENT_TYPE_BROADCAST |
| 899 : device::BluetoothAdvertisement::AdvertisementType:: |
| 900 ADVERTISEMENT_TYPE_PERIPHERAL)); |
| 901 |
| 902 advertisement_data->set_service_uuids( |
| 903 params->advertisement.service_uuids.Pass()); |
| 904 advertisement_data->set_solicit_uuids( |
| 905 params->advertisement.solicit_uuids.Pass()); |
| 906 if (params->advertisement.manufacturer_data) { |
| 907 advertisement_data->set_manufacturer_data( |
| 908 CreateManufacturerData(params->advertisement.manufacturer_data.get()) |
| 909 .Pass()); |
| 910 } |
| 911 if (params->advertisement.service_data) { |
| 912 advertisement_data->set_service_data( |
| 913 CreateServiceData(params->advertisement.service_data.get()).Pass()); |
| 914 } |
| 915 |
| 916 event_router->adapter()->RegisterAdvertisement( |
| 917 advertisement_data.Pass(), |
| 918 base::Bind( |
| 919 &BluetoothLowEnergyRegisterAdvertisementFunction::SuccessCallback, |
| 920 this), |
| 921 base::Bind( |
| 922 &BluetoothLowEnergyRegisterAdvertisementFunction::ErrorCallback, |
| 923 this)); |
823 | 924 |
824 return true; | 925 return true; |
825 } | 926 } |
826 | 927 |
| 928 void BluetoothLowEnergyRegisterAdvertisementFunction::SuccessCallback( |
| 929 scoped_refptr<device::BluetoothAdvertisement> advertisement) { |
| 930 results_ = apibtle::RegisterAdvertisement::Results::Create(AddAdvertisement( |
| 931 new BluetoothApiAdvertisement(extension_id(), advertisement))); |
| 932 SendResponse(true); |
| 933 } |
| 934 |
| 935 void BluetoothLowEnergyRegisterAdvertisementFunction::ErrorCallback( |
| 936 device::BluetoothAdvertisement::ErrorCode status) { |
| 937 switch (status) { |
| 938 case device::BluetoothAdvertisement::ErrorCode:: |
| 939 ERROR_ADVERTISEMENT_ALREADY_EXISTS: |
| 940 SetError(kStatusAdvertisementAlreadyExists); |
| 941 break; |
| 942 case device::BluetoothAdvertisement::ErrorCode:: |
| 943 ERROR_ADVERTISEMENT_INVALID_LENGTH: |
| 944 SetError(kErrorInvalidAdvertisementLength); |
| 945 break; |
| 946 default: |
| 947 SetError(kErrorOperationFailed); |
| 948 } |
| 949 SendResponse(false); |
| 950 } |
| 951 |
827 // UnregisterAdvertisement: | 952 // UnregisterAdvertisement: |
828 | 953 |
829 bool BluetoothLowEnergyUnregisterAdvertisementFunction::DoWork() { | 954 bool BluetoothLowEnergyUnregisterAdvertisementFunction::DoWork() { |
830 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 955 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
831 | 956 |
832 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { | 957 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { |
833 error_ = kErrorPermissionDenied; | 958 error_ = kErrorPermissionDenied; |
834 SendResponse(false); | 959 SendResponse(false); |
835 return false; | 960 return false; |
836 } | 961 } |
837 | 962 |
838 BluetoothLowEnergyEventRouter* event_router = | 963 BluetoothLowEnergyEventRouter* event_router = |
839 GetEventRouter(browser_context()); | 964 GetEventRouter(browser_context()); |
840 | 965 |
841 // If we don't have an initialized adapter, unregistering is a no-op. | 966 // If we don't have an initialized adapter, unregistering is a no-op. |
842 if (!event_router->HasAdapter()) | 967 if (!event_router->HasAdapter()) |
843 return true; | 968 return true; |
844 | 969 |
845 scoped_ptr<apibtle::UnregisterAdvertisement::Params> params( | 970 scoped_ptr<apibtle::UnregisterAdvertisement::Params> params( |
846 apibtle::UnregisterAdvertisement::Params::Create(*args_)); | 971 apibtle::UnregisterAdvertisement::Params::Create(*args_)); |
847 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 972 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
848 | 973 |
849 // TODO(rkc): Implement this function. | 974 BluetoothApiAdvertisement* advertisement = |
| 975 GetAdvertisement(params->advertisement_id); |
| 976 if (!advertisement) { |
| 977 error_ = kStatusAdvertisementDoesNotExist; |
| 978 SendResponse(false); |
| 979 return false; |
| 980 } |
| 981 |
| 982 advertisement->advertisement()->Unregister( |
| 983 base::Bind( |
| 984 &BluetoothLowEnergyUnregisterAdvertisementFunction::SuccessCallback, |
| 985 this, params->advertisement_id), |
| 986 base::Bind( |
| 987 &BluetoothLowEnergyUnregisterAdvertisementFunction::ErrorCallback, |
| 988 this, params->advertisement_id)); |
850 | 989 |
851 return true; | 990 return true; |
852 } | 991 } |
853 | 992 |
| 993 void BluetoothLowEnergyUnregisterAdvertisementFunction::SuccessCallback( |
| 994 int advertisement_id) { |
| 995 RemoveAdvertisement(advertisement_id); |
| 996 SendResponse(true); |
| 997 } |
| 998 |
| 999 void BluetoothLowEnergyUnregisterAdvertisementFunction::ErrorCallback( |
| 1000 int advertisement_id, |
| 1001 device::BluetoothAdvertisement::ErrorCode status) { |
| 1002 RemoveAdvertisement(advertisement_id); |
| 1003 switch (status) { |
| 1004 case device::BluetoothAdvertisement::ErrorCode:: |
| 1005 ERROR_ADVERTISEMENT_DOES_NOT_EXIST: |
| 1006 SetError(kStatusAdvertisementDoesNotExist); |
| 1007 break; |
| 1008 default: |
| 1009 SetError(kErrorOperationFailed); |
| 1010 } |
| 1011 SendResponse(false); |
| 1012 } |
| 1013 |
854 } // namespace core_api | 1014 } // namespace core_api |
855 } // namespace extensions | 1015 } // namespace extensions |
OLD | NEW |