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 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 544 : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
545 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 545 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
546 profile_(profile), | 546 profile_(profile), |
547 extension_prefs_(extension_prefs), | 547 extension_prefs_(extension_prefs), |
548 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 548 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
549 install_directory_(install_directory), | 549 install_directory_(install_directory), |
550 extensions_enabled_(extensions_enabled), | 550 extensions_enabled_(extensions_enabled), |
551 show_extensions_prompts_(true), | 551 show_extensions_prompts_(true), |
552 ready_(false), | 552 ready_(false), |
553 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 553 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 554 permissions_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
554 apps_promo_(profile->GetPrefs()), | 555 apps_promo_(profile->GetPrefs()), |
555 event_routers_initialized_(false) { | 556 event_routers_initialized_(false) { |
556 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 557 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
557 | 558 |
558 // Figure out if extension installation should be enabled. | 559 // Figure out if extension installation should be enabled. |
559 if (command_line->HasSwitch(switches::kDisableExtensions)) { | 560 if (command_line->HasSwitch(switches::kDisableExtensions)) { |
560 extensions_enabled_ = false; | 561 extensions_enabled_ = false; |
561 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { | 562 } else if (profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) { |
562 extensions_enabled_ = false; | 563 extensions_enabled_ = false; |
563 } | 564 } |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); | 977 NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::DISABLE); |
977 } | 978 } |
978 | 979 |
979 void ExtensionService::GrantPermissions(const Extension* extension) { | 980 void ExtensionService::GrantPermissions(const Extension* extension) { |
980 CHECK(extension); | 981 CHECK(extension); |
981 | 982 |
982 // We only maintain the granted permissions prefs for INTERNAL extensions. | 983 // We only maintain the granted permissions prefs for INTERNAL extensions. |
983 CHECK_EQ(Extension::INTERNAL, extension->location()); | 984 CHECK_EQ(Extension::INTERNAL, extension->location()); |
984 | 985 |
985 extension_prefs_->AddGrantedPermissions(extension->id(), | 986 extension_prefs_->AddGrantedPermissions(extension->id(), |
986 extension->permission_set()); | 987 extension->GetActivePermissions()); |
987 } | 988 } |
988 | 989 |
989 void ExtensionService::GrantPermissionsAndEnableExtension( | 990 void ExtensionService::GrantPermissionsAndEnableExtension( |
990 const Extension* extension) { | 991 const Extension* extension) { |
991 CHECK(extension); | 992 CHECK(extension); |
992 RecordPermissionMessagesHistogram( | 993 RecordPermissionMessagesHistogram( |
993 extension, "Extensions.Permissions_ReEnable"); | 994 extension, "Extensions.Permissions_ReEnable"); |
994 GrantPermissions(extension); | 995 GrantPermissions(extension); |
995 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 996 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
996 EnableExtension(extension->id()); | 997 EnableExtension(extension->id()); |
997 } | 998 } |
998 | 999 |
| 1000 void ExtensionService::UpdateActivePermissions( |
| 1001 const Extension* extension, |
| 1002 const ExtensionPermissionSet* permissions) { |
| 1003 extension_prefs()->SetActivePermissions(extension->id(), permissions); |
| 1004 extension->SetActivePermissions(permissions); |
| 1005 } |
| 1006 |
999 void ExtensionService::LoadExtension(const FilePath& extension_path) { | 1007 void ExtensionService::LoadExtension(const FilePath& extension_path) { |
1000 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 1008 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
1001 NewRunnableMethod(backend_.get(), | 1009 NewRunnableMethod(backend_.get(), |
1002 &ExtensionServiceBackend::LoadSingleExtension, | 1010 &ExtensionServiceBackend::LoadSingleExtension, |
1003 extension_path, true)); | 1011 extension_path, true)); |
1004 } | 1012 } |
1005 | 1013 |
1006 void ExtensionService::LoadExtensionFromCommandLine( | 1014 void ExtensionService::LoadExtensionFromCommandLine( |
1007 const FilePath& extension_path) { | 1015 const FilePath& extension_path) { |
1008 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 1016 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 Source<Profile>(profile_), | 1307 Source<Profile>(profile_), |
1300 Details<const Extension>(extension)); | 1308 Details<const Extension>(extension)); |
1301 | 1309 |
1302 // Tell renderers about the new extension. | 1310 // Tell renderers about the new extension. |
1303 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); | 1311 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); |
1304 !i.IsAtEnd(); i.Advance()) { | 1312 !i.IsAtEnd(); i.Advance()) { |
1305 RenderProcessHost* host = i.GetCurrentValue(); | 1313 RenderProcessHost* host = i.GetCurrentValue(); |
1306 if (host->profile()->GetOriginalProfile() == | 1314 if (host->profile()->GetOriginalProfile() == |
1307 profile_->GetOriginalProfile()) { | 1315 profile_->GetOriginalProfile()) { |
1308 host->Send( | 1316 host->Send( |
1309 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params(extension))); | 1317 new ExtensionMsg_Loaded(ExtensionMsg_Loaded_Params( |
| 1318 extension, extension->GetActivePermissions()))); |
1310 } | 1319 } |
1311 } | 1320 } |
1312 | 1321 |
1313 // Tell a random-ass collection of other subsystems about the new extension. | 1322 // Tell a random-ass collection of other subsystems about the new extension. |
1314 // TODO(aa): What should we do with all this goop? Can it move into the | 1323 // TODO(aa): What should we do with all this goop? Can it move into the |
1315 // relevant objects via EXTENSION_LOADED? | 1324 // relevant objects via EXTENSION_LOADED? |
1316 | 1325 |
1317 profile_->GetExtensionSpecialStoragePolicy()-> | 1326 profile_->GetExtensionSpecialStoragePolicy()-> |
1318 GrantRightsForExtension(extension); | 1327 GrantRightsForExtension(extension); |
1319 | 1328 |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1907 | 1916 |
1908 // If a terminated extension is loaded, remove it from the terminated list. | 1917 // If a terminated extension is loaded, remove it from the terminated list. |
1909 UntrackTerminatedExtension(extension->id()); | 1918 UntrackTerminatedExtension(extension->id()); |
1910 | 1919 |
1911 // If the extension was disabled for a reload, then enable it. | 1920 // If the extension was disabled for a reload, then enable it. |
1912 if (disabled_extension_paths_.erase(extension->id()) > 0) | 1921 if (disabled_extension_paths_.erase(extension->id()) > 0) |
1913 EnableExtension(extension->id()); | 1922 EnableExtension(extension->id()); |
1914 | 1923 |
1915 // Check if the extension's privileges have changed and disable the | 1924 // Check if the extension's privileges have changed and disable the |
1916 // extension if necessary. | 1925 // extension if necessary. |
1917 DisableIfPrivilegeIncrease(extension); | 1926 InitializePermissions(extension); |
1918 | 1927 |
1919 bool disabled = Extension::UserMayDisable(extension->location()) && | 1928 bool disabled = Extension::UserMayDisable(extension->location()) && |
1920 extension_prefs_->GetExtensionState(extension->id()) == | 1929 extension_prefs_->GetExtensionState(extension->id()) == |
1921 Extension::DISABLED; | 1930 Extension::DISABLED; |
1922 if (disabled) { | 1931 if (disabled) { |
1923 disabled_extensions_.push_back(scoped_extension); | 1932 disabled_extensions_.push_back(scoped_extension); |
1924 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called | 1933 // TODO(aa): This seems dodgy. It seems that AddExtension() could get called |
1925 // with a disabled extension for other reasons other than that an update was | 1934 // with a disabled extension for other reasons other than that an update was |
1926 // disabled. | 1935 // disabled. |
1927 NotificationService::current()->Notify( | 1936 NotificationService::current()->Notify( |
1928 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 1937 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
1929 Source<Profile>(profile_), | 1938 Source<Profile>(profile_), |
1930 Details<const Extension>(extension)); | 1939 Details<const Extension>(extension)); |
1931 return; | 1940 return; |
1932 } | 1941 } |
1933 | 1942 |
1934 extensions_.push_back(scoped_extension); | 1943 extensions_.push_back(scoped_extension); |
1935 NotifyExtensionLoaded(extension); | 1944 NotifyExtensionLoaded(extension); |
1936 } | 1945 } |
1937 | 1946 |
1938 void ExtensionService::DisableIfPrivilegeIncrease(const Extension* extension) { | 1947 void ExtensionService::InitializePermissions(const Extension* extension) { |
| 1948 // If the extension has used the optional permissions API, it will have a |
| 1949 // custom set of active permissions defined in the extension prefs. Here, |
| 1950 // we update the extension's active permissions based on the prefs. |
| 1951 scoped_ptr<ExtensionPermissionSet> active_permissions( |
| 1952 extension_prefs()->GetActivePermissions(extension->id())); |
| 1953 |
| 1954 if (active_permissions.get()) { |
| 1955 // We restrict the active permissions to be within the bounds defined in the |
| 1956 // extension's manifest. |
| 1957 // a) active permissions must be a subset of optional + default permissions |
| 1958 // b) active permissions must contains all default permissions |
| 1959 scoped_ptr<ExtensionPermissionSet> total_permissions( |
| 1960 ExtensionPermissionSet::CreateUnion( |
| 1961 extension->required_permission_set(), |
| 1962 extension->optional_permission_set())); |
| 1963 |
| 1964 // Make sure the active permissions contain no more than optional + default. |
| 1965 scoped_ptr<ExtensionPermissionSet> adjusted_active( |
| 1966 ExtensionPermissionSet::CreateIntersection( |
| 1967 total_permissions.get(), active_permissions.get())); |
| 1968 |
| 1969 // Make sure the active permissions contain the default permissions. |
| 1970 adjusted_active.reset( |
| 1971 ExtensionPermissionSet::CreateUnion( |
| 1972 extension->required_permission_set(), adjusted_active.get())); |
| 1973 |
| 1974 UpdateActivePermissions(extension, adjusted_active.release()); |
| 1975 } |
| 1976 |
1939 // We keep track of all permissions the user has granted each extension. | 1977 // We keep track of all permissions the user has granted each extension. |
1940 // This allows extensions to gracefully support backwards compatibility | 1978 // This allows extensions to gracefully support backwards compatibility |
1941 // by including unknown permissions in their manifests. When the user | 1979 // by including unknown permissions in their manifests. When the user |
1942 // installs the extension, only the recognized permissions are recorded. | 1980 // installs the extension, only the recognized permissions are recorded. |
1943 // When the unknown permissions become recognized (e.g., through browser | 1981 // When the unknown permissions become recognized (e.g., through browser |
1944 // upgrade), we can prompt the user to accept these new permissions. | 1982 // upgrade), we can prompt the user to accept these new permissions. |
1945 // Extensions can also silently upgrade to less permissions, and then | 1983 // Extensions can also silently upgrade to less permissions, and then |
1946 // silently upgrade to a version that adds these permissions back. | 1984 // silently upgrade to a version that adds these permissions back. |
1947 // | 1985 // |
1948 // For example, pretend that Chrome 10 includes a permission "omnibox" | 1986 // For example, pretend that Chrome 10 includes a permission "omnibox" |
(...skipping 20 matching lines...) Expand all Loading... |
1969 // hasn't been initialized yet. | 2007 // hasn't been initialized yet. |
1970 scoped_ptr<ExtensionPermissionSet> granted_permissions( | 2008 scoped_ptr<ExtensionPermissionSet> granted_permissions( |
1971 extension_prefs_->GetGrantedPermissions(extension->id())); | 2009 extension_prefs_->GetGrantedPermissions(extension->id())); |
1972 CHECK(granted_permissions.get()); | 2010 CHECK(granted_permissions.get()); |
1973 | 2011 |
1974 // Here, we check if an extension's privileges have increased in a manner | 2012 // Here, we check if an extension's privileges have increased in a manner |
1975 // that requires the user's approval. This could occur because the browser | 2013 // that requires the user's approval. This could occur because the browser |
1976 // upgraded and recognized additional privileges, or an extension upgrades | 2014 // upgraded and recognized additional privileges, or an extension upgrades |
1977 // to a version that requires additional privileges. | 2015 // to a version that requires additional privileges. |
1978 is_privilege_increase = | 2016 is_privilege_increase = |
1979 granted_permissions->HasLessPrivilegesThan(extension->permission_set()); | 2017 granted_permissions->HasLessPrivilegesThan( |
| 2018 extension->GetActivePermissions()); |
1980 } | 2019 } |
1981 | 2020 |
1982 if (is_extension_upgrade) { | 2021 if (is_extension_upgrade) { |
1983 // Other than for unpacked extensions, CrxInstaller should have guaranteed | 2022 // Other than for unpacked extensions, CrxInstaller should have guaranteed |
1984 // that we aren't downgrading. | 2023 // that we aren't downgrading. |
1985 if (extension->location() != Extension::LOAD) | 2024 if (extension->location() != Extension::LOAD) |
1986 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); | 2025 CHECK(extension->version()->CompareTo(*(old->version())) >= 0); |
1987 | 2026 |
1988 // Extensions get upgraded if the privileges are allowed to increase or | 2027 // Extensions get upgraded if the privileges are allowed to increase or |
1989 // the privileges haven't increased. | 2028 // the privileges haven't increased. |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2321 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); | 2360 process->Send(new ExtensionMsg_SetFunctionNames(function_names)); |
2322 | 2361 |
2323 // Scripting whitelist. This is modified by tests and must be communicated | 2362 // Scripting whitelist. This is modified by tests and must be communicated |
2324 // to renderers. | 2363 // to renderers. |
2325 process->Send(new ExtensionMsg_SetScriptingWhitelist( | 2364 process->Send(new ExtensionMsg_SetScriptingWhitelist( |
2326 *Extension::GetScriptingWhitelist())); | 2365 *Extension::GetScriptingWhitelist())); |
2327 | 2366 |
2328 // Loaded extensions. | 2367 // Loaded extensions. |
2329 for (size_t i = 0; i < extensions_.size(); ++i) { | 2368 for (size_t i = 0; i < extensions_.size(); ++i) { |
2330 process->Send(new ExtensionMsg_Loaded( | 2369 process->Send(new ExtensionMsg_Loaded( |
2331 ExtensionMsg_Loaded_Params(extensions_[i]))); | 2370 ExtensionMsg_Loaded_Params( |
| 2371 extensions_[i], extensions_[i]->GetActivePermissions()))); |
2332 } | 2372 } |
2333 break; | 2373 break; |
2334 } | 2374 } |
2335 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { | 2375 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { |
2336 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); | 2376 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); |
2337 installed_app_hosts_.erase(process->id()); | 2377 installed_app_hosts_.erase(process->id()); |
2338 break; | 2378 break; |
2339 } | 2379 } |
2340 case chrome::NOTIFICATION_PREF_CHANGED: { | 2380 case chrome::NOTIFICATION_PREF_CHANGED: { |
2341 std::string* pref_name = Details<std::string>(details).ptr(); | 2381 std::string* pref_name = Details<std::string>(details).ptr(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2469 | 2509 |
2470 ExtensionService::NaClModuleInfoList::iterator | 2510 ExtensionService::NaClModuleInfoList::iterator |
2471 ExtensionService::FindNaClModule(const GURL& url) { | 2511 ExtensionService::FindNaClModule(const GURL& url) { |
2472 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); | 2512 for (NaClModuleInfoList::iterator iter = nacl_module_list_.begin(); |
2473 iter != nacl_module_list_.end(); ++iter) { | 2513 iter != nacl_module_list_.end(); ++iter) { |
2474 if (iter->url == url) | 2514 if (iter->url == url) |
2475 return iter; | 2515 return iter; |
2476 } | 2516 } |
2477 return nacl_module_list_.end(); | 2517 return nacl_module_list_.end(); |
2478 } | 2518 } |
OLD | NEW |