15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_set.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/callback.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stl_util.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/sandboxed_page_info.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::const_iterator::const_iterator() {}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::const_iterator::const_iterator(const const_iterator& other)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : it_(other.it_) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::const_iterator::const_iterator(ExtensionMap::const_iterator it)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : it_(it) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ExtensionSet::const_iterator::~const_iterator() {}
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::ExtensionSet() {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::~ExtensionSet() {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ExtensionSet::size() const {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions_.size();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::is_empty() const {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions_.empty();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::Contains(const std::string& extension_id) const {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions_.find(extension_id) != extensions_.end();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExtensionSet::Insert(const scoped_refptr<const Extension>& extension) {
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool was_present = ContainsKey(extensions_, extension->id());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_[extension->id()] = extension;
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!was_present && !modification_callback_.is_null())
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    modification_callback_.Run(GetIDs());
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !was_present;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::InsertAll(const ExtensionSet& extensions) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t before = size();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionSet::const_iterator iter = extensions.begin();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions.end(); ++iter) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Insert(*iter);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return size() != before;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionSet::Remove(const std::string& id) {
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool was_present = extensions_.erase(id) > 0;
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (was_present && !modification_callback_.is_null())
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    modification_callback_.Run(GetIDs());
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return was_present;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Clear() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_.clear();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstd::string ExtensionSet::GetExtensionOrAppIDByURL(const GURL& url) const {
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (url.SchemeIs(extensions::kExtensionScheme))
77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return url.host();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  const Extension* extension = GetExtensionOrAppByURL(url);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension->id();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst Extension* ExtensionSet::GetExtensionOrAppByURL(const GURL& url) const {
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (url.SchemeIs(extensions::kExtensionScheme))
88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return GetByID(url.host());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return GetHostedAppByURL(url);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst Extension* ExtensionSet::GetHostedAppByURL(const GURL& url) const {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionMap::const_iterator iter = extensions_.begin();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (iter->second->web_extent().MatchesURL(url))
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return iter->second.get();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* ExtensionSet::GetHostedAppByOverlappingWebExtent(
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const extensions::URLPatternSet& extent) const {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionMap::const_iterator iter = extensions_.begin();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->second->web_extent().OverlapsWith(extent))
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return iter->second.get();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::InSameExtent(const GURL& old_url,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const GURL& new_url) const {
116ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return GetExtensionOrAppByURL(old_url) ==
117ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      GetExtensionOrAppByURL(new_url);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* ExtensionSet::GetByID(const std::string& id) const {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionMap::const_iterator i = extensions_.find(id);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != extensions_.end())
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return i->second.get();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)extensions::ExtensionIdSet ExtensionSet::GetIDs() const {
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  extensions::ExtensionIdSet ids;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ExtensionMap::const_iterator it = extensions_.begin();
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != extensions_.end(); ++it) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ids.insert(it->first);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ids;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ExtensionSet::ExtensionBindingsAllowed(const GURL& url) const {
138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (url.SchemeIs(extensions::kExtensionScheme))
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionMap::const_iterator i = extensions_.begin();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; i != extensions_.end(); ++i) {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i->second->location() == extensions::Manifest::COMPONENT &&
144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        i->second->web_extent().MatchesURL(url))
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
150