Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 545 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 546 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 546 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 547 profile_(profile), | 547 profile_(profile), |
| 548 extension_prefs_(extension_prefs), | 548 extension_prefs_(extension_prefs), |
| 549 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 549 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 550 install_directory_(install_directory), | 550 install_directory_(install_directory), |
| 551 extensions_enabled_(extensions_enabled), | 551 extensions_enabled_(extensions_enabled), |
| 552 show_extensions_prompts_(true), | 552 show_extensions_prompts_(true), |
| 553 ready_(false), | 553 ready_(false), |
| 554 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 554 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 555 permissions_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | |
| 555 apps_promo_(profile->GetPrefs()), | 556 apps_promo_(profile->GetPrefs()), |
| 556 event_routers_initialized_(false) { | 557 event_routers_initialized_(false) { |
| 557 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 558 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 558 | 559 |
| 559 // Figure out if extension installation should be enabled. | 560 // Figure out if extension installation should be enabled. |
| 560 if (command_line->HasSwitch(switches::kDisableExtensions)) { | 561 if (command_line->HasSwitch(switches::kDisableExtensions)) { |
| 561 extensions_enabled_ = false; | 562 extensions_enabled_ = false; |
| 562 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 563 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
| 563 extensions_enabled_ = false; | 564 extensions_enabled_ = false; |
| 564 } | 565 } |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 967 extension); | 968 extension); |
| 968 terminated_extensions_.erase(iter); | 969 terminated_extensions_.erase(iter); |
| 969 } | 970 } |
| 970 | 971 |
| 971 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); | 972 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); |
| 972 } | 973 } |
| 973 | 974 |
| 974 void ExtensionService::GrantPermissions(const Extension* extension) { | 975 void ExtensionService::GrantPermissions(const Extension* extension) { |
| 975 CHECK(extension); | 976 CHECK(extension); |
| 976 | 977 |
| 977 // We only maintain the granted permissions prefs for INTERNAL extensions. | 978 // We only maintain the granted permissions prefs for INTERNAL extensions |
| 978 CHECK_EQ(Extension::INTERNAL, extension->location()); | 979 // because the other types don't prompt the user at install & upgrade time. |
| 980 if (extension->location() != Extension::INTERNAL) | |
|
Mihai Parparita -not on Chrome
2011/07/23 22:54:53
Not seeing the Extension::CanSilentlyIncreasePermi
jstritar
2011/07/25 19:15:24
Woops. Done.
| |
| 981 return; | |
| 979 | 982 |
| 980 extension_prefs_->AddGrantedPermissions(extension->id(), | 983 extension_prefs_->AddGrantedPermissions(extension->id(), |
| 981 extension->permission_set()); | 984 extension->GetActivePermissions()); |
| 982 } | 985 } |
| 983 | 986 |
| 984 void ExtensionService::GrantPermissionsAndEnableExtension( | 987 void ExtensionService::GrantPermissionsAndEnableExtension( |
| 985 const Extension* extension) { | 988 const Extension* extension) { |
| 986 CHECK(extension); | 989 CHECK(extension); |
| 987 RecordPermissionMessagesHistogram( | 990 RecordPermissionMessagesHistogram( |
| 988 extension, "Extensions.Permissions_ReEnable"); | 991 extension, "Extensions.Permissions_ReEnable"); |
| 989 GrantPermissions(extension); | 992 GrantPermissions(extension); |
| 990 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 993 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
| 991 EnableExtension(extension->id()); | 994 EnableExtension(extension->id()); |
| 992 } | 995 } |
| 993 | 996 |
| 997 void ExtensionService::UpdateActivePermissions( | |
| 998 const Extension* extension, | |
| 999 const ExtensionPermissionSet* permissions) { | |
| 1000 extension_prefs()->SetActivePermissions(extension->id(), permissions); | |
| 1001 extension->SetActivePermissions(permissions); | |
| 1002 } | |
| 1003 | |
| 994 void ExtensionService::LoadExtension(const FilePath& extension_path) { | 1004 void ExtensionService::LoadExtension(const FilePath& extension_path) { |
| 995 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 1005 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 996 NewRunnableMethod(backend_.get(), | 1006 NewRunnableMethod(backend_.get(), |
| 997 &ExtensionServiceBackend::LoadSingleExtension, | 1007 &ExtensionServiceBackend::LoadSingleExtension, |
| 998 extension_path, true)); | 1008 extension_path, true)); |
| 999 } | 1009 } |
| 1000 | 1010 |
| 1001 void ExtensionService::LoadExtensionFromCommandLine( | 1011 void ExtensionService::LoadExtensionFromCommandLine( |
| 1002 const FilePath& path_in) { | 1012 const FilePath& path_in) { |
| 1003 | 1013 |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1327 Source<Profile>(profile_), | 1337 Source<Profile>(profile_), |
| 1328 Details<const Extension>(extension)); | 1338 Details<const Extension>(extension)); |
| 1329 | 1339 |
| 1330 // Tell renderers about the new extension. | 1340 // Tell renderers about the new extension. |
| 1331 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); | 1341 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); |
| 1332 !i.IsAtEnd(); i.Advance()) { | 1342 !i.IsAtEnd(); i.Advance()) { |
| 1333 RenderProcessHost* host = i.GetCurrentValue(); | 1343 RenderProcessHost* host = i.GetCurrentValue(); |
| 1334 if (host->profile()->GetOriginalProfile() == | 1344 if (host->profile()->GetOriginalProfile() == |
| 1335 profile_->GetOriginalProfile()) { | 1345 profile_->GetOriginalProfile()) { |
| 1336 host->Send( | 1346 host->Send( |
| 1337 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params(extension))); | 1347 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params( |
| 1348 extension, extension->GetActivePermissions()))); | |
| 1338 } | 1349 } |
| 1339 } | 1350 } |
| 1340 | 1351 |
| 1341 // Tell a random-ass collection of other subsystems about the new extension. | 1352 // Tell a random-ass collection of other subsystems about the new extension. |
| 1342 // TODO(aa): What should we do with all this goop? Can it move into the | 1353 // TODO(aa): What should we do with all this goop? Can it move into the |
| 1343 // relevant objects via EXTENSION_LOADED? | 1354 // relevant objects via EXTENSION_LOADED? |
| 1344 | 1355 |
| 1345 profile_->GetExtensionSpecialStoragePolicy()-> | 1356 profile_->GetExtensionSpecialStoragePolicy()-> |
| 1346 GrantRightsForExtension(extension); | 1357 GrantRightsForExtension(extension); |
| 1347 | 1358 |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1935 | 1946 |
| 1936 // If a terminated extension is loaded, remove it from the terminated list. | 1947 // If a terminated extension is loaded, remove it from the terminated list. |
| 1937 UntrackTerminatedExtension(extension->id()); | 1948 UntrackTerminatedExtension(extension->id()); |
| 1938 | 1949 |
| 1939 // If the extension was disabled for a reload, then enable it. | 1950 // If the extension was disabled for a reload, then enable it. |
| 1940 if (disabled_extension_paths_.erase(extension->id()) > 0) | 1951 if (disabled_extension_paths_.erase(extension->id()) > 0) |
| 1941 EnableExtension(extension->id()); | 1952 EnableExtension(extension->id()); |
| 1942 | 1953 |
| 1943 // Check if the extension's privileges have changed and disable the | 1954 // Check if the extension's privileges have changed and disable the |
| 1944 // extension if necessary. | 1955 // extension if necessary. |
| 1945 DisableIfPrivilegeIncrease(extension); | 1956 InitializePermissions(extension); |
| 1946 | 1957 |
| 1947 bool disabled = Extension::UserMayDisable(extension->location()) && | 1958 bool disabled = Extension::UserMayDisable(extension->location()) && |
| 1948 extension_prefs_->GetExtensionState(extension->id()) == | 1959 extension_prefs_->GetExtensionState(extension->id()) == |
| 1949 Extension::DISABLED; | 1960 Extension::DISABLED; |
| 1950 if (disabled) { | 1961 if (disabled) { |
| 1951 disabled_extensions_.push_back(scoped_extension); | 1962 disabled_extensions_.push_back(scoped_extension); |
| 1952 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called | 1963 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called |
| 1953 // with a disabled extension for other reasons other than that an update was | 1964 // with a disabled extension for other reasons other than that an update was |
| 1954 // disabled. | 1965 // disabled. |
| 1955 NotificationService::current()->Notify( | 1966 NotificationService::current()->Notify( |
| 1956 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 1967 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
| 1957 Source<Profile>(profile_), | 1968 Source<Profile>(profile_), |
| 1958 Details<const Extension>(extension)); | 1969 Details<const Extension>(extension)); |
| 1959 return; | 1970 return; |
| 1960 } | 1971 } |
| 1961 | 1972 |
| 1962 extensions_.push_back(scoped_extension); | 1973 extensions_.push_back(scoped_extension); |
| 1963 NotifyExtensionLoaded(extension); | 1974 NotifyExtensionLoaded(extension); |
| 1964 } | 1975 } |
| 1965 | 1976 |
| 1966 void ExtensionService::DisableIfPrivilegeIncrease(const Extension* extension) { | 1977 void ExtensionService::InitializePermissions(const Extension* extension) { |
| 1978 // If the extension has used the optional permissions API, it will have a | |
| 1979 // custom set of active permissions defined in the extension prefs. Here, | |
| 1980 // we update the extension's active permissions based on the prefs. | |
| 1981 scoped_ptr<ExtensionPermissionSet> active_permissions( | |
| 1982 extension_prefs()->GetActivePermissions(extension->id())); | |
| 1983 | |
| 1984 if (active_permissions.get()) { | |
| 1985 // We restrict the active permissions to be within the bounds defined in the | |
| 1986 // extension's manifest. | |
| 1987 // a) active permissions must be a subset of optional + default permissions | |
| 1988 // b) active permissions must contains all default permissions | |
| 1989 scoped_ptr<ExtensionPermissionSet> total_permissions( | |
| 1990 ExtensionPermissionSet::CreateUnion( | |
| 1991 extension->required_permission_set(), | |
| 1992 extension->optional_permission_set())); | |
| 1993 | |
| 1994 // Make sure the active permissions contain no more than optional + default. | |
| 1995 scoped_ptr<ExtensionPermissionSet> adjusted_active( | |
| 1996 ExtensionPermissionSet::CreateIntersection( | |
| 1997 total_permissions.get(), active_permissions.get())); | |
| 1998 | |
| 1999 // Make sure the active permissions contain the default permissions. | |
| 2000 adjusted_active.reset( | |
| 2001 ExtensionPermissionSet::CreateUnion( | |
| 2002 extension->required_permission_set(), adjusted_active.get())); | |
| 2003 | |
| 2004 UpdateActivePermissions(extension, adjusted_active.release()); | |
| 2005 } | |
| 2006 | |
| 1967 // We keep track of all permissions the user has granted each extension. | 2007 // We keep track of all permissions the user has granted each extension. |
| 1968 // This allows extensions to gracefully support backwards compatibility | 2008 // This allows extensions to gracefully support backwards compatibility |
| 1969 // by including unknown permissions in their manifests. When the user | 2009 // by including unknown permissions in their manifests. When the user |
| 1970 // installs the extension, only the recognized permissions are recorded. | 2010 // installs the extension, only the recognized permissions are recorded. |
| 1971 // When the unknown permissions become recognized (e.g., through browser | 2011 // When the unknown permissions become recognized (e.g., through browser |
| 1972 // upgrade), we can prompt the user to accept these new permissions. | 2012 // upgrade), we can prompt the user to accept these new permissions. |
| 1973 // Extensions can also silently upgrade to less permissions, and then | 2013 // Extensions can also silently upgrade to less permissions, and then |
| 1974 // silently upgrade to a version that adds these permissions back. | 2014 // silently upgrade to a version that adds these permissions back. |
| 1975 // | 2015 // |
| 1976 // For example, pretend that Chrome 10 includes a permission "omnibox" | 2016 // For example, pretend that Chrome 10 includes a permission "omnibox" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1997 // hasn't been initialized yet. | 2037 // hasn't been initialized yet. |
| 1998 scoped_ptr<ExtensionPermissionSet> granted_permissions( | 2038 scoped_ptr<ExtensionPermissionSet> granted_permissions( |
| 1999 extension_prefs_->GetGrantedPermissions(extension->id())); | 2039 extension_prefs_->GetGrantedPermissions(extension->id())); |
| 2000 CHECK(granted_permissions.get()); | 2040 CHECK(granted_permissions.get()); |
| 2001 | 2041 |
| 2002 // Here, we check if an extension's privileges have increased in a manner | 2042 // Here, we check if an extension's privileges have increased in a manner |
| 2003 // that requires the user's approval. This could occur because the browser | 2043 // that requires the user's approval. This could occur because the browser |
| 2004 // upgraded and recognized additional privileges, or an extension upgrades | 2044 // upgraded and recognized additional privileges, or an extension upgrades |
| 2005 // to a version that requires additional privileges. | 2045 // to a version that requires additional privileges. |
| 2006 is_privilege_increase = | 2046 is_privilege_increase = |
| 2007 granted_permissions->HasLessPrivilegesThan(extension->permission_set()); | 2047 granted_permissions->HasLessPrivilegesThan( |
| 2048 extension->GetActivePermissions()); | |
| 2008 } | 2049 } |
| 2009 | 2050 |
| 2010 if (is_extension_upgrade) { | 2051 if (is_extension_upgrade) { |
| 2011 // Other than for unpacked extensions, CrxInstaller should have guaranteed | 2052 // Other than for unpacked extensions, CrxInstaller should have guaranteed |
| 2012 // that we aren't downgrading. | 2053 // that we aren't downgrading. |
| 2013 if (extension->location() != Extension::LOAD) | 2054 if (extension->location() != Extension::LOAD) |
| 2014 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); | 2055 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); |
| 2015 | 2056 |
| 2016 // Extensions get upgraded if the privileges are allowed to increase or | 2057 // Extensions get upgraded if the privileges are allowed to increase or |
| 2017 // the privileges haven't increased. | 2058 // the privileges haven't increased. |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2349 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); | 2390 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); |
| 2350 | 2391 |
| 2351 // Scripting whitelist. This is modified by tests and must be communicated | 2392 // Scripting whitelist. This is modified by tests and must be communicated |
| 2352 // to renderers. | 2393 // to renderers. |
| 2353 process->Send(new ExtensionMsg_SetScriptingWhitelist( | 2394 process->Send(new ExtensionMsg_SetScriptingWhitelist( |
| 2354 *Extension::GetScriptingWhitelist())); | 2395 *Extension::GetScriptingWhitelist())); |
| 2355 | 2396 |
| 2356 // Loaded extensions. | 2397 // Loaded extensions. |
| 2357 for (size_t i = 0; i < extensions_.size(); ++i) { | 2398 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 2358 process->Send(new ExtensionMsg_Loaded( | 2399 process->Send(new ExtensionMsg_Loaded( |
| 2359 ExtensionMsg_Loaded_Params(extensions_[i]))); | 2400 ExtensionMsg_Loaded_Params( |
| 2401 extensions_[i], extensions_[i]->GetActivePermissions()))); | |
| 2360 } | 2402 } |
| 2361 break; | 2403 break; |
| 2362 } | 2404 } |
| 2363 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { | 2405 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { |
| 2364 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); | 2406 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); |
| 2365 installed_app_hosts_.erase(process->id()); | 2407 installed_app_hosts_.erase(process->id()); |
| 2366 break; | 2408 break; |
| 2367 } | 2409 } |
| 2368 case chrome::NOTIFICATION_PREF_CHANGED: { | 2410 case chrome::NOTIFICATION_PREF_CHANGED: { |
| 2369 std::string* pref_name = Details<std::string>(details).ptr(); | 2411 std::string* pref_name = Details<std::string>(details).ptr(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2497 | 2539 |
| 2498 ExtensionService::NaClModuleInfoList::iterator | 2540 ExtensionService::NaClModuleInfoList::iterator |
| 2499 ExtensionService::FindNaClModule(const GURL& url) { | 2541 ExtensionService::FindNaClModule(const GURL& url) { |
| 2500 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); | 2542 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); |
| 2501 iter != nacl_module_list_.end(); ++iter) { | 2543 iter != nacl_module_list_.end(); ++iter) { |
| 2502 if (iter->url == url) | 2544 if (iter->url == url) |
| 2503 return iter; | 2545 return iter; |
| 2504 } | 2546 } |
| 2505 return nacl_module_list_.end(); | 2547 return nacl_module_list_.end(); |
| 2506 } | 2548 } |
| OLD | NEW |