| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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/browser/extensions/extension_info_map.h" | |
| 6 | |
| 7 #include "chrome/common/extensions/extension.h" | |
| 8 #include "chrome/common/extensions/extension_set.h" | |
| 9 #include "chrome/common/url_constants.h" | |
| 10 #include "content/public/browser/browser_thread.h" | |
| 11 #include "extensions/common/constants.h" | |
| 12 #include "extensions/common/manifest_handlers/incognito_info.h" | |
| 13 | |
| 14 using content::BrowserThread; | |
| 15 using extensions::Extension; | |
| 16 using extensions::UnloadedExtensionInfo; | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 void CheckOnValidThread() { | |
| 21 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 22 } | |
| 23 | |
| 24 } // namespace | |
| 25 | |
| 26 struct ExtensionInfoMap::ExtraData { | |
| 27 // When the extension was installed. | |
| 28 base::Time install_time; | |
| 29 | |
| 30 // True if the user has allowed this extension to run in incognito mode. | |
| 31 bool incognito_enabled; | |
| 32 | |
| 33 ExtraData(); | |
| 34 ~ExtraData(); | |
| 35 }; | |
| 36 | |
| 37 ExtensionInfoMap::ExtraData::ExtraData() : incognito_enabled(false) {} | |
| 38 | |
| 39 ExtensionInfoMap::ExtraData::~ExtraData() {} | |
| 40 | |
| 41 ExtensionInfoMap::ExtensionInfoMap() : signin_process_id_(-1) {} | |
| 42 | |
| 43 const extensions::ProcessMap& ExtensionInfoMap::process_map() const { | |
| 44 return process_map_; | |
| 45 } | |
| 46 | |
| 47 void ExtensionInfoMap::AddExtension(const Extension* extension, | |
| 48 base::Time install_time, | |
| 49 bool incognito_enabled) { | |
| 50 CheckOnValidThread(); | |
| 51 extensions_.Insert(extension); | |
| 52 disabled_extensions_.Remove(extension->id()); | |
| 53 | |
| 54 extra_data_[extension->id()].install_time = install_time; | |
| 55 extra_data_[extension->id()].incognito_enabled = incognito_enabled; | |
| 56 } | |
| 57 | |
| 58 void ExtensionInfoMap::RemoveExtension( | |
| 59 const std::string& extension_id, | |
| 60 const UnloadedExtensionInfo::Reason reason) { | |
| 61 CheckOnValidThread(); | |
| 62 const Extension* extension = extensions_.GetByID(extension_id); | |
| 63 extra_data_.erase(extension_id); // we don't care about disabled extra data | |
| 64 bool was_uninstalled = (reason != UnloadedExtensionInfo::REASON_DISABLE && | |
| 65 reason != UnloadedExtensionInfo::REASON_TERMINATE); | |
| 66 if (extension) { | |
| 67 if (!was_uninstalled) | |
| 68 disabled_extensions_.Insert(extension); | |
| 69 extensions_.Remove(extension_id); | |
| 70 } else if (was_uninstalled) { | |
| 71 // If the extension was uninstalled, make sure it's removed from the map of | |
| 72 // disabled extensions. | |
| 73 disabled_extensions_.Remove(extension_id); | |
| 74 } else { | |
| 75 // NOTE: This can currently happen if we receive multiple unload | |
| 76 // notifications, e.g. setting incognito-enabled state for a | |
| 77 // disabled extension (e.g., via sync). See | |
| 78 // http://code.google.com/p/chromium/issues/detail?id=50582 . | |
| 79 NOTREACHED() << extension_id; | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 base::Time ExtensionInfoMap::GetInstallTime( | |
| 84 const std::string& extension_id) const { | |
| 85 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id); | |
| 86 if (iter != extra_data_.end()) | |
| 87 return iter->second.install_time; | |
| 88 return base::Time(); | |
| 89 } | |
| 90 | |
| 91 bool ExtensionInfoMap::IsIncognitoEnabled( | |
| 92 const std::string& extension_id) const { | |
| 93 // Keep in sync with duplicate in extension_process_manager.cc. | |
| 94 ExtraDataMap::const_iterator iter = extra_data_.find(extension_id); | |
| 95 if (iter != extra_data_.end()) | |
| 96 return iter->second.incognito_enabled; | |
| 97 return false; | |
| 98 } | |
| 99 | |
| 100 bool ExtensionInfoMap::CanCrossIncognito(const Extension* extension) const { | |
| 101 // This is duplicated from ExtensionService :(. | |
| 102 return IsIncognitoEnabled(extension->id()) && | |
| 103 !extensions::IncognitoInfo::IsSplitMode(extension); | |
| 104 } | |
| 105 | |
| 106 void ExtensionInfoMap::RegisterExtensionProcess(const std::string& extension_id, | |
| 107 int process_id, | |
| 108 int site_instance_id) { | |
| 109 if (!process_map_.Insert(extension_id, process_id, site_instance_id)) { | |
| 110 NOTREACHED() << "Duplicate extension process registration for: " | |
| 111 << extension_id << "," << process_id << "."; | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 void ExtensionInfoMap::UnregisterExtensionProcess( | |
| 116 const std::string& extension_id, | |
| 117 int process_id, | |
| 118 int site_instance_id) { | |
| 119 if (!process_map_.Remove(extension_id, process_id, site_instance_id)) { | |
| 120 NOTREACHED() << "Unknown extension process registration for: " | |
| 121 << extension_id << "," << process_id << "."; | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 void ExtensionInfoMap::UnregisterAllExtensionsInProcess(int process_id) { | |
| 126 process_map_.RemoveAllFromProcess(process_id); | |
| 127 } | |
| 128 | |
| 129 void ExtensionInfoMap::GetExtensionsWithAPIPermissionForSecurityOrigin( | |
| 130 const GURL& origin, | |
| 131 int process_id, | |
| 132 extensions::APIPermission::ID permission, | |
| 133 ExtensionSet* extensions) const { | |
| 134 DCHECK(extensions); | |
| 135 | |
| 136 if (origin.SchemeIs(extensions::kExtensionScheme)) { | |
| 137 const std::string& id = origin.host(); | |
| 138 const Extension* extension = extensions_.GetByID(id); | |
| 139 if (extension && extension->HasAPIPermission(permission) && | |
| 140 process_map_.Contains(id, process_id)) { | |
| 141 extensions->Insert(extension); | |
| 142 } | |
| 143 return; | |
| 144 } | |
| 145 | |
| 146 ExtensionSet::const_iterator i = extensions_.begin(); | |
| 147 for (; i != extensions_.end(); ++i) { | |
| 148 if ((*i)->web_extent().MatchesSecurityOrigin(origin) && | |
| 149 process_map_.Contains((*i)->id(), process_id) && | |
| 150 (*i)->HasAPIPermission(permission)) { | |
| 151 extensions->Insert(*i); | |
| 152 } | |
| 153 } | |
| 154 } | |
| 155 | |
| 156 bool ExtensionInfoMap::SecurityOriginHasAPIPermission( | |
| 157 const GURL& origin, int process_id, | |
| 158 extensions::APIPermission::ID permission) const { | |
| 159 ExtensionSet extensions; | |
| 160 GetExtensionsWithAPIPermissionForSecurityOrigin( | |
| 161 origin, process_id, permission, &extensions); | |
| 162 return !extensions.is_empty(); | |
| 163 } | |
| 164 | |
| 165 ExtensionsQuotaService* ExtensionInfoMap::GetQuotaService() { | |
| 166 CheckOnValidThread(); | |
| 167 if (!quota_service_) | |
| 168 quota_service_.reset(new ExtensionsQuotaService()); | |
| 169 return quota_service_.get(); | |
| 170 } | |
| 171 | |
| 172 void ExtensionInfoMap::SetSigninProcess(int process_id) { | |
| 173 signin_process_id_ = process_id; | |
| 174 } | |
| 175 | |
| 176 bool ExtensionInfoMap::IsSigninProcess(int process_id) const { | |
| 177 return process_id == signin_process_id_; | |
| 178 } | |
| 179 | |
| 180 ExtensionInfoMap::~ExtensionInfoMap() { | |
| 181 if (quota_service_) { | |
| 182 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, | |
| 183 quota_service_.release()); | |
| 184 } | |
| 185 } | |
| OLD | NEW |