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 3 // found in the LICENSE file. 4 5 #include "extensions/common/api/bluetooth/bluetooth_manifest_permission.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/stl_util.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/values.h" 11 #include "device/bluetooth/bluetooth_uuid.h" 12 #include "extensions/common/api/bluetooth/bluetooth_manifest_data.h" 13 #include "extensions/common/api/extensions_manifest_types.h" 14 #include "extensions/common/error_utils.h" 15 #include "extensions/common/manifest_constants.h" 16 #include "grit/extensions_strings.h" 17 #include "ipc/ipc_message.h" 18 #include "ui/base/l10n/l10n_util.h" 19 20 namespace extensions { 21 22 namespace bluetooth_errors { 23 const char kErrorInvalidUuid[] = "Invalid UUID '*'"; 24 } 25 26 namespace errors = bluetooth_errors; 27 28 namespace { 29 30 bool ParseUuid(BluetoothManifestPermission* permission, 31 const std::string& uuid, 32 base::string16* error) { 33 device::BluetoothUUID bt_uuid(uuid); 34 if (!bt_uuid.IsValid()) { 35 *error = ErrorUtils::FormatErrorMessageUTF16( 36 errors::kErrorInvalidUuid, uuid); 37 return false; 38 } 39 permission->AddPermission(uuid); 40 return true; 41 } 42 43 bool ParseUuidArray(BluetoothManifestPermission* permission, 44 const scoped_ptr<std::vector<std::string> >& uuids, 45 base::string16* error) { 46 for (std::vector<std::string>::const_iterator it = uuids->begin(); 47 it != uuids->end(); 48 ++it) { 49 if (!ParseUuid(permission, *it, error)) { 50 return false; 51 } 52 } 53 return true; 54 } 55 56 } // namespace 57 58 BluetoothManifestPermission::BluetoothManifestPermission() 59 : socket_(false), 60 low_energy_(false) {} 61 62 BluetoothManifestPermission::~BluetoothManifestPermission() {} 63 64 // static 65 scoped_ptr<BluetoothManifestPermission> BluetoothManifestPermission::FromValue( 66 const base::Value& value, 67 base::string16* error) { 68 scoped_ptr<core_api::extensions_manifest_types::Bluetooth> bluetooth = 69 core_api::extensions_manifest_types::Bluetooth::FromValue(value, error); 70 if (!bluetooth) 71 return scoped_ptr<BluetoothManifestPermission>(); 72 73 scoped_ptr<BluetoothManifestPermission> result( 74 new BluetoothManifestPermission()); 75 if (bluetooth->uuids) { 76 if (!ParseUuidArray(result.get(), bluetooth->uuids, error)) { 77 return scoped_ptr<BluetoothManifestPermission>(); 78 } 79 } 80 if (bluetooth->socket) { 81 result->socket_ = *(bluetooth->socket); 82 } 83 if (bluetooth->low_energy) { 84 result->low_energy_ = *(bluetooth->low_energy); 85 } 86 return result.Pass(); 87 } 88 89 bool BluetoothManifestPermission::CheckRequest( 90 const Extension* extension, 91 const BluetoothPermissionRequest& request) const { 92 93 device::BluetoothUUID param_uuid(request.uuid); 94 for (BluetoothUuidSet::const_iterator it = uuids_.begin(); 95 it != uuids_.end(); 96 ++it) { 97 device::BluetoothUUID uuid(*it); 98 if (param_uuid == uuid) 99 return true; 100 } 101 return false; 102 } 103 104 bool BluetoothManifestPermission::CheckSocketPermitted( 105 const Extension* extension) const { 106 return socket_; 107 } 108 109 bool BluetoothManifestPermission::CheckLowEnergyPermitted( 110 const Extension* extension) const { 111 return low_energy_; 112 } 113 114 std::string BluetoothManifestPermission::name() const { 115 return manifest_keys::kBluetooth; 116 } 117 118 std::string BluetoothManifestPermission::id() const { return name(); } 119 120 bool BluetoothManifestPermission::HasMessages() const { return true; } 121 122 PermissionMessages BluetoothManifestPermission::GetMessages() const { 123 DCHECK(HasMessages()); 124 PermissionMessages result; 125 126 result.push_back(PermissionMessage( 127 PermissionMessage::kBluetooth, 128 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH))); 129 130 if (!uuids_.empty()) { 131 result.push_back( 132 PermissionMessage(PermissionMessage::kBluetoothDevices, 133 l10n_util::GetStringUTF16( 134 IDS_EXTENSION_PROMPT_WARNING_BLUETOOTH_DEVICES))); 135 } 136 137 return result; 138 } 139 140 bool BluetoothManifestPermission::FromValue(const base::Value* value) { 141 if (!value) 142 return false; 143 base::string16 error; 144 scoped_ptr<BluetoothManifestPermission> manifest_permission( 145 BluetoothManifestPermission::FromValue(*value, &error)); 146 147 if (!manifest_permission) 148 return false; 149 150 uuids_ = manifest_permission->uuids_; 151 return true; 152 } 153 154 scoped_ptr<base::Value> BluetoothManifestPermission::ToValue() const { 155 core_api::extensions_manifest_types::Bluetooth bluetooth; 156 bluetooth.uuids.reset(new std::vector<std::string>(uuids_.begin(), 157 uuids_.end())); 158 return bluetooth.ToValue().PassAs<base::Value>(); 159 } 160 161 ManifestPermission* BluetoothManifestPermission::Diff( 162 const ManifestPermission* rhs) const { 163 const BluetoothManifestPermission* other = 164 static_cast<const BluetoothManifestPermission*>(rhs); 165 166 scoped_ptr<BluetoothManifestPermission> result( 167 new BluetoothManifestPermission()); 168 result->uuids_ = base::STLSetDifference<BluetoothUuidSet>( 169 uuids_, other->uuids_); 170 return result.release(); 171 } 172 173 ManifestPermission* BluetoothManifestPermission::Union( 174 const ManifestPermission* rhs) const { 175 const BluetoothManifestPermission* other = 176 static_cast<const BluetoothManifestPermission*>(rhs); 177 178 scoped_ptr<BluetoothManifestPermission> result( 179 new BluetoothManifestPermission()); 180 result->uuids_ = base::STLSetUnion<BluetoothUuidSet>( 181 uuids_, other->uuids_); 182 return result.release(); 183 } 184 185 ManifestPermission* BluetoothManifestPermission::Intersect( 186 const ManifestPermission* rhs) const { 187 const BluetoothManifestPermission* other = 188 static_cast<const BluetoothManifestPermission*>(rhs); 189 190 scoped_ptr<BluetoothManifestPermission> result( 191 new BluetoothManifestPermission()); 192 result->uuids_ = base::STLSetIntersection<BluetoothUuidSet>( 193 uuids_, other->uuids_); 194 return result.release(); 195 } 196 197 void BluetoothManifestPermission::AddPermission(const std::string& uuid) { 198 uuids_.insert(uuid); 199 } 200 201 } // namespace extensions 202