15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 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)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/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"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/constants.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/sandboxed_page_info.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace extensions {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::const_iterator::const_iterator() {}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::const_iterator::const_iterator(const const_iterator& other)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : it_(other.it_) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::const_iterator::const_iterator(ExtensionMap::const_iterator it)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : it_(it) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ExtensionSet::const_iterator::~const_iterator() {}
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::ExtensionSet() {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::~ExtensionSet() {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ExtensionSet::size() const {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions_.size();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::is_empty() const {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions_.empty();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::Contains(const std::string& extension_id) const {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extensions_.find(extension_id) != extensions_.end();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ExtensionSet::Insert(const scoped_refptr<const Extension>& extension) {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool was_present = ContainsKey(extensions_, extension->id());
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_[extension->id()] = extension;
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!was_present && !modification_callback_.is_null())
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    modification_callback_.Run(GetIDs());
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !was_present;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::InsertAll(const ExtensionSet& extensions) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t before = size();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionSet::const_iterator iter = extensions.begin();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions.end(); ++iter) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Insert(*iter);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return size() != before;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionSet::Remove(const std::string& id) {
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool was_present = extensions_.erase(id) > 0;
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (was_present && !modification_callback_.is_null())
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    modification_callback_.Run(GetIDs());
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return was_present;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Clear() {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_.clear();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstd::string ExtensionSet::GetExtensionOrAppIDByURL(const GURL& url) const {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (url.SchemeIs(kExtensionScheme))
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return url.host();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const Extension* extension = GetHostedAppByURL(url);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension->id();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst Extension* ExtensionSet::GetExtensionOrAppByURL(const GURL& url) const {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (url.SchemeIs(kExtensionScheme))
87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return GetByID(url.host());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return GetHostedAppByURL(url);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst Extension* ExtensionSet::GetAppByURL(const GURL& url) const {
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const Extension* extension = GetExtensionOrAppByURL(url);
94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return (extension && extension->is_app()) ? extension : NULL;
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst Extension* ExtensionSet::GetHostedAppByURL(const GURL& url) const {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionMap::const_iterator iter = extensions_.begin();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (iter->second->web_extent().MatchesURL(url))
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return iter->second.get();
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* ExtensionSet::GetHostedAppByOverlappingWebExtent(
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const URLPatternSet& extent) const {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionMap::const_iterator iter = extensions_.begin();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (iter->second->web_extent().OverlapsWith(extent))
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return iter->second.get();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::InSameExtent(const GURL& old_url,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const GURL& new_url) const {
120ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return GetExtensionOrAppByURL(old_url) ==
121ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      GetExtensionOrAppByURL(new_url);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* ExtensionSet::GetByID(const std::string& id) const {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionMap::const_iterator i = extensions_.find(id);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (i != extensions_.end())
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return i->second.get();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionIdSet ExtensionSet::GetIDs() const {
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionIdSet ids;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ExtensionMap::const_iterator it = extensions_.begin();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != extensions_.end(); ++it) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ids.insert(it->first);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ids;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ExtensionSet::ExtensionBindingsAllowed(const GURL& url) const {
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (url.SchemeIs(kExtensionScheme))
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (ExtensionMap::const_iterator it = extensions_.begin();
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != extensions_.end(); ++it) {
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (it->second->location() == Manifest::COMPONENT &&
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        it->second->web_extent().MatchesURL(url))
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace extensions
156