externally_connectable.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/externally_connectable.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <algorithm> 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/stl_util.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/manifest_types.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/permissions/api_permission_set.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/extensions/permissions/permissions_data.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/common/error_utils.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/common/url_pattern.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace rcd = net::registry_controlled_domains; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace extensions { 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace externally_connectable_errors { 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kErrorInvalid[] = "Invalid value for 'externally_connectable'"; 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kErrorInvalidMatchPattern[] = "Invalid match pattern '*'"; 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kErrorInvalidId[] = "Invalid ID '*'"; 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char kErrorNothingSpecified[] = 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "'externally_connectable' specifies neither 'matches' nor 'ids'; " 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "nothing will be able to connect"; 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kErrorTopLevelDomainsNotAllowed[] = 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "\"*\" is an effective top level domain for which wildcard subdomains such " 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "as \"*\" are not allowed"; 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kErrorWildcardHostsNotAllowed[] = 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "Wildcard domain patterns such as \"*\" are not allowed"; 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace externally_connectable_errors 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace keys = extension_manifest_keys; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace errors = externally_connectable_errors; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using api::manifest_types::ExternallyConnectable; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kAllIds[] = "*"; 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)template <typename T> 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::vector<T> Sorted(const std::vector<T>& in) { 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<T> out = in; 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::sort(out.begin(), out.end()); 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return out; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternallyConnectableHandler::ExternallyConnectableHandler() {} 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternallyConnectableHandler::~ExternallyConnectableHandler() {} 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExternallyConnectableHandler::Parse(Extension* extension, 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string16* error) { 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Value* externally_connectable = NULL; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(extension->manifest()->Get(keys::kExternallyConnectable, 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &externally_connectable)); 645e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) std::vector<InstallWarning> install_warnings; 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ExternallyConnectableInfo> info = 665e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) ExternallyConnectableInfo::FromValue(*externally_connectable, 675e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) &install_warnings, 685e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) error); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!info) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info->matches.is_empty()) { 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PermissionsData::GetInitialAPIPermissions(extension)->insert( 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) APIPermission::kWebConnectable); 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 755e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) extension->AddInstallWarnings(install_warnings); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension->SetManifestData(keys::kExternallyConnectable, info.release()); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::vector<std::string> ExternallyConnectableHandler::Keys() const { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SingleKey(keys::kExternallyConnectable); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternallyConnectableInfo* ExternallyConnectableInfo::Get( 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const Extension* extension) { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return static_cast<ExternallyConnectableInfo*>( 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension->GetManifestData(keys::kExternallyConnectable)); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ExternallyConnectableInfo> ExternallyConnectableInfo::FromValue( 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::Value& value, 945e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) std::vector<InstallWarning>* install_warnings, 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) string16* error) { 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ExternallyConnectable> externally_connectable = 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExternallyConnectable::FromValue(value); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!externally_connectable) { 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *error = UTF8ToUTF16(errors::kErrorInvalid); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_ptr<ExternallyConnectableInfo>(); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) URLPatternSet matches; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (externally_connectable->matches) { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<std::string>::iterator it = 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) externally_connectable->matches->begin(); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it != externally_connectable->matches->end(); ++it) { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Safe to use SCHEME_ALL here; externally_connectable gives a page -> 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // extension communication path, not the other way. 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) URLPattern pattern(URLPattern::SCHEME_ALL); 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pattern.Parse(*it) != URLPattern::PARSE_SUCCESS) { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *error = ErrorUtils::FormatErrorMessageUTF16( 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) errors::kErrorInvalidMatchPattern, *it); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_ptr<ExternallyConnectableInfo>(); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Wildcard hosts are not allowed. 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pattern.host().empty()) { 1205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) // Warning not error for forwards compatibility. 1215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) install_warnings->push_back( 1225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) InstallWarning::Text(ErrorUtils::FormatErrorMessage( 1235e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) errors::kErrorWildcardHostsNotAllowed, *it))); 1245e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) continue; 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Wildcards on subdomains of a TLD are not allowed. 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t registry_length = rcd::GetRegistryLength( 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pattern.host(), 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This means that things that look like TLDs - the foobar in 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // http://google.foobar - count as TLDs. 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rcd::INCLUDE_UNKNOWN_REGISTRIES, 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This means that effective TLDs like appspot.com count as TLDs; 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // codereview.appspot.com and evil.appspot.com are different. 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) rcd::INCLUDE_PRIVATE_REGISTRIES); 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (registry_length == std::string::npos) { 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The URL parsing combined with host().empty() should have caught this. 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NOTREACHED() << *it; 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *error = ErrorUtils::FormatErrorMessageUTF16( 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) errors::kErrorInvalidMatchPattern, *it); 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return scoped_ptr<ExternallyConnectableInfo>(); 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Broad match patterns like "*.com", "*.co.uk", and even "*.appspot.com" 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // are not allowed. However just "appspot.com" is ok. 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (registry_length == 0 && pattern.match_subdomains()) { 1485e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) // Warning not error for forwards compatibility. 1495e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) install_warnings->push_back(InstallWarning::Text( 1505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) ErrorUtils::FormatErrorMessage( 1515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) errors::kErrorTopLevelDomainsNotAllowed, 1525e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) pattern.host().c_str(), 1535e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) *it))); 1545e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) continue; 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) matches.AddPattern(pattern); 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> ids; 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool all_ids = false; 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (externally_connectable->ids) { 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<std::string>::iterator it = 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) externally_connectable->ids->begin(); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it != externally_connectable->ids->end(); ++it) { 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (*it == kAllIds) { 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) all_ids = true; 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (Extension::IdIsValid(*it)) { 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ids.push_back(*it); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *error = ErrorUtils::FormatErrorMessageUTF16( 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) errors::kErrorInvalidId, *it); 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return scoped_ptr<ExternallyConnectableInfo>(); 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!externally_connectable->matches && 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) !externally_connectable->ids) { 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) install_warnings->push_back(InstallWarning::Text( 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) errors::kErrorNothingSpecified)); 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return make_scoped_ptr( 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new ExternallyConnectableInfo(matches, ids, all_ids)); 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternallyConnectableInfo::~ExternallyConnectableInfo() {} 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ExternallyConnectableInfo::ExternallyConnectableInfo( 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const URLPatternSet& matches, 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<std::string>& ids, 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool all_ids) 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : matches(matches), ids(Sorted(ids)), all_ids(all_ids) {} 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ExternallyConnectableInfo::IdCanConnect(const std::string& id) { 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (all_ids) 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return true; 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(base::STLIsSorted(ids)); 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return std::binary_search(ids.begin(), ids.end(), id); 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace extensions 206