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; | |
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; | |
130 std::copy(it->data.begin(), it->data.end(), data.begin()); | |
131 (*created_data)[it->uuid] = data; | |
132 } | |
133 return created_data; | |
134 } | |
armansito
2015/05/08 22:46:13
You'll need unit tests for these functions. It's O
rkc
2015/05/11 21:59:35
Both these functions are getting exercised by the
| |
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) { | |
armansito
2015/05/08 23:08:19
DCHECK(advertisements_manager);
rkc
2015/05/11 21:59:35
Done.
| |
840 return advertisements_manager_->Add(advertisement); | |
841 } | |
842 | |
843 BluetoothApiAdvertisement* | |
844 BluetoothLowEnergyAdvertisementFunction::GetAdvertisement( | |
845 int advertisement_id) { | |
armansito
2015/05/08 23:08:19
DCHECK(advertisements_manager);
rkc
2015/05/11 21:59:35
Done.
| |
846 return advertisements_manager_->Get(extension_id(), advertisement_id); | |
847 } | |
848 | |
849 void BluetoothLowEnergyAdvertisementFunction::RemoveAdvertisement( | |
850 int advertisement_id) { | |
armansito
2015/05/08 23:08:19
DCHECK(advertisements_manager);
rkc
2015/05/11 21:59:35
Done.
| |
851 advertisements_manager_->Remove(extension_id(), advertisement_id); | |
852 } | |
853 | |
854 bool BluetoothLowEnergyAdvertisementFunction::RunAsync() { | |
855 Initialize(); | |
856 return BluetoothLowEnergyExtensionFunction::RunAsync(); | |
857 } | |
858 | |
859 void BluetoothLowEnergyAdvertisementFunction::Initialize() { | |
860 advertisements_manager_ = | |
861 ApiResourceManager<BluetoothApiAdvertisement>::Get(browser_context()); | |
862 } | |
863 | |
796 // RegisterAdvertisement: | 864 // RegisterAdvertisement: |
797 | 865 |
798 bool BluetoothLowEnergyRegisterAdvertisementFunction::DoWork() { | 866 bool BluetoothLowEnergyRegisterAdvertisementFunction::DoWork() { |
799 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 867 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
800 | 868 |
801 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { | 869 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { |
802 error_ = kErrorPermissionDenied; | 870 error_ = kErrorPermissionDenied; |
803 SendResponse(false); | 871 SendResponse(false); |
804 return false; | 872 return false; |
805 } | 873 } |
806 | 874 |
807 BluetoothLowEnergyEventRouter* event_router = | 875 BluetoothLowEnergyEventRouter* event_router = |
808 GetEventRouter(browser_context()); | 876 GetEventRouter(browser_context()); |
809 | 877 |
810 // The adapter must be initialized at this point, but return an error instead | 878 // The adapter must be initialized at this point, but return an error instead |
811 // of asserting. | 879 // of asserting. |
812 if (!event_router->HasAdapter()) { | 880 if (!event_router->HasAdapter()) { |
813 SetError(kErrorAdapterNotInitialized); | 881 SetError(kErrorAdapterNotInitialized); |
814 SendResponse(false); | 882 SendResponse(false); |
815 return false; | 883 return false; |
816 } | 884 } |
817 | 885 |
818 scoped_ptr<apibtle::RegisterAdvertisement::Params> params( | 886 scoped_ptr<apibtle::RegisterAdvertisement::Params> params( |
819 apibtle::RegisterAdvertisement::Params::Create(*args_)); | 887 apibtle::RegisterAdvertisement::Params::Create(*args_)); |
820 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 888 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
821 | 889 |
822 // TODO(rkc): Implement this function. | 890 scoped_ptr<device::BluetoothAdvertisement::Data> advertisement_data( |
891 new device::BluetoothAdvertisement::Data( | |
892 params->advertisement.type == | |
893 apibtle::AdvertisementType::ADVERTISEMENT_TYPE_BROADCAST | |
894 ? device::BluetoothAdvertisement::AdvertisementType:: | |
895 ADVERTISEMENT_TYPE_BROADCAST | |
896 : device::BluetoothAdvertisement::AdvertisementType:: | |
897 ADVERTISEMENT_TYPE_PERIPHERAL)); | |
898 | |
899 advertisement_data->set_service_uuids( | |
900 params->advertisement.service_uuids.Pass()); | |
901 advertisement_data->set_solicit_uuids( | |
902 params->advertisement.solicit_uuids.Pass()); | |
903 | |
904 if (params->advertisement.manufacturer_data) | |
armansito
2015/05/08 23:08:19
Use curly braces for these two if statement. Even
rkc
2015/05/11 21:59:35
Done.
| |
905 advertisement_data->set_manufacturer_data( | |
906 CreateManufacturerData(params->advertisement.manufacturer_data.get()) | |
907 .Pass()); | |
908 if (params->advertisement.service_data) | |
armansito
2015/05/08 23:08:19
ditto
rkc
2015/05/11 21:59:35
Done.
| |
909 advertisement_data->set_service_data( | |
910 CreateServiceData(params->advertisement.service_data.get()).Pass()); | |
911 | |
912 event_router->adapter()->RegisterAdvertisement( | |
913 advertisement_data.Pass(), | |
914 base::Bind( | |
915 &BluetoothLowEnergyRegisterAdvertisementFunction::SuccessCallback, | |
916 this), | |
917 base::Bind( | |
918 &BluetoothLowEnergyRegisterAdvertisementFunction::ErrorCallback, | |
919 this)); | |
823 | 920 |
824 return true; | 921 return true; |
825 } | 922 } |
826 | 923 |
924 void BluetoothLowEnergyRegisterAdvertisementFunction::SuccessCallback( | |
925 scoped_refptr<device::BluetoothAdvertisement> advertisement) { | |
926 results_ = apibtle::RegisterAdvertisement::Results::Create(AddAdvertisement( | |
927 new BluetoothApiAdvertisement(extension_id(), advertisement))); | |
928 SendResponse(true); | |
929 } | |
930 | |
931 void BluetoothLowEnergyRegisterAdvertisementFunction::ErrorCallback( | |
932 device::BluetoothAdvertisement::ErrorCode status) { | |
933 switch (status) { | |
934 case device::BluetoothAdvertisement::ErrorCode:: | |
935 ERROR_ADVERTISEMENT_ALREADY_EXISTS: | |
936 SetError(kStatusAdvertisementAlreadyExists); | |
937 break; | |
938 case device::BluetoothAdvertisement::ErrorCode:: | |
939 ERROR_ADVERTISEMENT_INVALID_LENGTH: | |
940 SetError(kErrorInvalidAdvertisementLength); | |
941 break; | |
942 default: | |
943 SetError(kErrorOperationFailed); | |
944 } | |
945 SendResponse(false); | |
946 } | |
947 | |
827 // UnregisterAdvertisement: | 948 // UnregisterAdvertisement: |
828 | 949 |
829 bool BluetoothLowEnergyUnregisterAdvertisementFunction::DoWork() { | 950 bool BluetoothLowEnergyUnregisterAdvertisementFunction::DoWork() { |
830 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 951 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
831 | 952 |
832 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { | 953 if (!BluetoothManifestData::CheckPeripheralPermitted(extension())) { |
833 error_ = kErrorPermissionDenied; | 954 error_ = kErrorPermissionDenied; |
834 SendResponse(false); | 955 SendResponse(false); |
835 return false; | 956 return false; |
836 } | 957 } |
837 | 958 |
838 BluetoothLowEnergyEventRouter* event_router = | 959 BluetoothLowEnergyEventRouter* event_router = |
839 GetEventRouter(browser_context()); | 960 GetEventRouter(browser_context()); |
840 | 961 |
841 // If we don't have an initialized adapter, unregistering is a no-op. | 962 // If we don't have an initialized adapter, unregistering is a no-op. |
842 if (!event_router->HasAdapter()) | 963 if (!event_router->HasAdapter()) |
843 return true; | 964 return true; |
844 | 965 |
845 scoped_ptr<apibtle::UnregisterAdvertisement::Params> params( | 966 scoped_ptr<apibtle::UnregisterAdvertisement::Params> params( |
846 apibtle::UnregisterAdvertisement::Params::Create(*args_)); | 967 apibtle::UnregisterAdvertisement::Params::Create(*args_)); |
847 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | 968 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); |
848 | 969 |
849 // TODO(rkc): Implement this function. | 970 BluetoothApiAdvertisement* advertisement = |
971 GetAdvertisement(params->advertisement_id); | |
972 if (!advertisement) { | |
973 error_ = kStatusAdvertisementDoesNotExist; | |
974 SendResponse(false); | |
975 return false; | |
976 } | |
977 | |
978 advertisement->advertisement()->Unregister( | |
979 base::Bind( | |
980 &BluetoothLowEnergyUnregisterAdvertisementFunction::SuccessCallback, | |
981 this, params->advertisement_id), | |
982 base::Bind( | |
983 &BluetoothLowEnergyUnregisterAdvertisementFunction::ErrorCallback, | |
984 this, params->advertisement_id)); | |
850 | 985 |
851 return true; | 986 return true; |
852 } | 987 } |
853 | 988 |
989 void BluetoothLowEnergyUnregisterAdvertisementFunction::SuccessCallback( | |
990 int advertisement_id) { | |
991 RemoveAdvertisement(advertisement_id); | |
992 SendResponse(true); | |
993 } | |
994 | |
995 void BluetoothLowEnergyUnregisterAdvertisementFunction::ErrorCallback( | |
996 int advertisement_id, | |
997 device::BluetoothAdvertisement::ErrorCode status) { | |
998 RemoveAdvertisement(advertisement_id); | |
999 switch (status) { | |
1000 case device::BluetoothAdvertisement::ErrorCode:: | |
1001 ERROR_ADVERTISEMENT_DOES_NOT_EXIST: | |
1002 SetError(kStatusAdvertisementDoesNotExist); | |
1003 break; | |
1004 default: | |
1005 SetError(kErrorOperationFailed); | |
1006 } | |
1007 SendResponse(false); | |
1008 } | |
1009 | |
854 } // namespace core_api | 1010 } // namespace core_api |
855 } // namespace extensions | 1011 } // namespace extensions |
OLD | NEW |