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