OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 <iterator> | 8 #include <iterator> |
9 #include <set> | 9 #include <set> |
10 | 10 |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/files/file_util.h" | |
12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
16 #include "base/threading/sequenced_worker_pool.h" | 17 #include "base/threading/sequenced_worker_pool.h" |
17 #include "base/threading/thread_restrictions.h" | 18 #include "base/threading/thread_restrictions.h" |
18 #include "base/time/time.h" | 19 #include "base/time/time.h" |
19 #include "chrome/browser/browser_process.h" | 20 #include "chrome/browser/browser_process.h" |
20 #include "chrome/browser/chrome_notification_types.h" | 21 #include "chrome/browser/chrome_notification_types.h" |
21 #include "chrome/browser/content_settings/content_settings_custom_extension_prov ider.h" | 22 #include "chrome/browser/content_settings/content_settings_custom_extension_prov ider.h" |
(...skipping 27 matching lines...) Expand all Loading... | |
49 #include "chrome/browser/ui/webui/theme_source.h" | 50 #include "chrome/browser/ui/webui/theme_source.h" |
50 #include "chrome/common/chrome_switches.h" | 51 #include "chrome/common/chrome_switches.h" |
51 #include "chrome/common/crash_keys.h" | 52 #include "chrome/common/crash_keys.h" |
52 #include "chrome/common/extensions/extension_constants.h" | 53 #include "chrome/common/extensions/extension_constants.h" |
53 #include "chrome/common/extensions/features/feature_channel.h" | 54 #include "chrome/common/extensions/features/feature_channel.h" |
54 #include "chrome/common/url_constants.h" | 55 #include "chrome/common/url_constants.h" |
55 #include "components/content_settings/core/browser/host_content_settings_map.h" | 56 #include "components/content_settings/core/browser/host_content_settings_map.h" |
56 #include "components/crx_file/id_util.h" | 57 #include "components/crx_file/id_util.h" |
57 #include "components/startup_metric_utils/startup_metric_utils.h" | 58 #include "components/startup_metric_utils/startup_metric_utils.h" |
58 #include "content/public/browser/devtools_agent_host.h" | 59 #include "content/public/browser/devtools_agent_host.h" |
60 #include "content/public/browser/indexed_db_context.h" | |
59 #include "content/public/browser/notification_service.h" | 61 #include "content/public/browser/notification_service.h" |
60 #include "content/public/browser/render_process_host.h" | 62 #include "content/public/browser/render_process_host.h" |
61 #include "content/public/browser/storage_partition.h" | 63 #include "content/public/browser/storage_partition.h" |
62 #include "extensions/browser/event_router.h" | 64 #include "extensions/browser/event_router.h" |
63 #include "extensions/browser/extension_host.h" | 65 #include "extensions/browser/extension_host.h" |
64 #include "extensions/browser/extension_prefs.h" | 66 #include "extensions/browser/extension_prefs.h" |
65 #include "extensions/browser/extension_registry.h" | 67 #include "extensions/browser/extension_registry.h" |
66 #include "extensions/browser/extension_system.h" | 68 #include "extensions/browser/extension_system.h" |
67 #include "extensions/browser/extensions_browser_client.h" | 69 #include "extensions/browser/extensions_browser_client.h" |
68 #include "extensions/browser/install_flag.h" | 70 #include "extensions/browser/install_flag.h" |
69 #include "extensions/browser/runtime_data.h" | 71 #include "extensions/browser/runtime_data.h" |
70 #include "extensions/browser/uninstall_reason.h" | 72 #include "extensions/browser/uninstall_reason.h" |
71 #include "extensions/browser/update_observer.h" | 73 #include "extensions/browser/update_observer.h" |
72 #include "extensions/browser/updater/extension_cache.h" | 74 #include "extensions/browser/updater/extension_cache.h" |
73 #include "extensions/browser/updater/extension_downloader.h" | 75 #include "extensions/browser/updater/extension_downloader.h" |
74 #include "extensions/common/extension_messages.h" | 76 #include "extensions/common/extension_messages.h" |
75 #include "extensions/common/extension_urls.h" | 77 #include "extensions/common/extension_urls.h" |
76 #include "extensions/common/feature_switch.h" | 78 #include "extensions/common/feature_switch.h" |
77 #include "extensions/common/file_util.h" | 79 #include "extensions/common/file_util.h" |
78 #include "extensions/common/manifest_constants.h" | 80 #include "extensions/common/manifest_constants.h" |
79 #include "extensions/common/manifest_handlers/background_info.h" | 81 #include "extensions/common/manifest_handlers/background_info.h" |
80 #include "extensions/common/manifest_url_handlers.h" | 82 #include "extensions/common/manifest_url_handlers.h" |
81 #include "extensions/common/one_shot_event.h" | 83 #include "extensions/common/one_shot_event.h" |
82 #include "extensions/common/permissions/permission_message_provider.h" | 84 #include "extensions/common/permissions/permission_message_provider.h" |
83 #include "extensions/common/permissions/permissions_data.h" | 85 #include "extensions/common/permissions/permissions_data.h" |
86 #include "storage/browser/fileapi/sandbox_file_system_backend_delegate.h" | |
87 #include "storage/common/database/database_identifier.h" | |
88 #include "storage/common/fileapi/file_system_types.h" | |
84 | 89 |
85 #if defined(OS_CHROMEOS) | 90 #if defined(OS_CHROMEOS) |
86 #include "chrome/browser/chromeos/extensions/install_limiter.h" | 91 #include "chrome/browser/chromeos/extensions/install_limiter.h" |
87 #include "storage/browser/fileapi/file_system_backend.h" | 92 #include "storage/browser/fileapi/file_system_backend.h" |
88 #include "storage/browser/fileapi/file_system_context.h" | 93 #include "storage/browser/fileapi/file_system_context.h" |
89 #endif | 94 #endif |
90 | 95 |
91 using content::BrowserContext; | 96 using content::BrowserContext; |
92 using content::BrowserThread; | 97 using content::BrowserThread; |
93 using content::DevToolsAgentHost; | 98 using content::DevToolsAgentHost; |
(...skipping 14 matching lines...) Expand all Loading... | |
108 using extensions::SharedModuleService; | 113 using extensions::SharedModuleService; |
109 using extensions::UnloadedExtensionInfo; | 114 using extensions::UnloadedExtensionInfo; |
110 | 115 |
111 namespace errors = extensions::manifest_errors; | 116 namespace errors = extensions::manifest_errors; |
112 | 117 |
113 namespace { | 118 namespace { |
114 | 119 |
115 // Wait this many seconds after an extensions becomes idle before updating it. | 120 // Wait this many seconds after an extensions becomes idle before updating it. |
116 const int kUpdateIdleDelay = 5; | 121 const int kUpdateIdleDelay = 5; |
117 | 122 |
123 void CopyFileSystem( | |
124 storage::SandboxFileSystemBackendDelegate* old_sandbox_delegate, | |
125 storage::SandboxFileSystemBackendDelegate* sandbox_delegate, | |
126 const GURL& origin, | |
127 storage::FileSystemType type){ | |
128 | |
129 base::FilePath old_base_path = | |
130 old_sandbox_delegate->GetBaseDirectoryForOriginAndType( | |
131 origin, | |
132 type, | |
133 false); | |
134 | |
135 base::FilePath base_path = | |
136 sandbox_delegate->GetBaseDirectoryForOriginAndType( | |
137 origin, | |
138 type, | |
139 true); | |
140 | |
141 base::CopyDirectory(old_base_path, base_path.DirName(), true); | |
142 } | |
143 | |
144 void MigrateLegacyPartition( | |
145 content::StoragePartition* old_partition, | |
146 content::StoragePartition* current_partition, | |
147 const Extension* extension) { | |
148 GURL extension_url = Extension::GetBaseURLFromExtensionId(extension->id()); | |
benwells
2014/11/03 00:08:41
Could you add a check here that this is happening
ryanackley
2014/11/04 22:51:54
Acknowledged.
| |
149 | |
150 content::IndexedDBContext* indexed_db_context = | |
151 current_partition->GetIndexedDBContext(); | |
152 content::IndexedDBContext* old_indexed_db_context = | |
153 old_partition->GetIndexedDBContext(); | |
154 | |
155 base::FilePath old_db_path = | |
156 old_indexed_db_context->GetFilePath(extension_url); | |
157 base::FilePath current_db_path = | |
158 indexed_db_context->GetFilePath(extension_url); | |
159 | |
160 if (base::PathExists(old_db_path) && !base::PathExists(current_db_path)){ | |
161 base::CopyDirectory(old_db_path, current_db_path.DirName(), true); | |
162 } | |
163 | |
164 storage::FileSystemContext* old_fs_context = | |
165 old_partition->GetFileSystemContext(); | |
166 storage::FileSystemContext* fs_context = | |
167 current_partition->GetFileSystemContext(); | |
168 | |
169 storage::SandboxFileSystemBackendDelegate* old_sandbox_delegate = | |
170 old_fs_context->sandbox_delegate(); | |
171 storage::SandboxFileSystemBackendDelegate* sandbox_delegate = | |
172 fs_context->sandbox_delegate(); | |
173 | |
174 scoped_ptr<storage::SandboxFileSystemBackendDelegate::OriginEnumerator> | |
175 enumerator(old_sandbox_delegate->CreateOriginEnumerator()); | |
176 | |
177 GURL origin; | |
178 while (extension_url != (origin = enumerator->Next()) && !origin.is_empty()){ | |
benwells
2014/11/03 00:08:41
Nit: you need a space before the curly (here and e
ryanackley
2014/11/04 22:51:53
Acknowledged.
| |
179 continue; | |
180 } | |
181 if (!origin.is_empty()){ | |
182 if (enumerator->HasFileSystemType(storage::kFileSystemTypeTemporary)){ | |
183 CopyFileSystem( | |
184 old_sandbox_delegate, | |
185 sandbox_delegate, | |
186 extension_url, | |
187 storage::kFileSystemTypeTemporary); | |
188 } | |
189 if (enumerator->HasFileSystemType(storage::kFileSystemTypePersistent)){ | |
190 CopyFileSystem( | |
191 old_sandbox_delegate, | |
192 sandbox_delegate, | |
193 extension_url, | |
194 storage::kFileSystemTypePersistent); | |
195 } | |
196 } | |
197 } | |
198 | |
118 } // namespace | 199 } // namespace |
119 | 200 |
120 // ExtensionService. | 201 // ExtensionService. |
121 | 202 |
122 void ExtensionService::CheckExternalUninstall(const std::string& id) { | 203 void ExtensionService::CheckExternalUninstall(const std::string& id) { |
123 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 204 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
124 | 205 |
125 // Check if the providers know about this extension. | 206 // Check if the providers know about this extension. |
126 extensions::ProviderCollection::const_iterator i; | 207 extensions::ProviderCollection::const_iterator i; |
127 for (i = external_extension_providers_.begin(); | 208 for (i = external_extension_providers_.begin(); |
(...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1334 } | 1415 } |
1335 | 1416 |
1336 bool is_extension_upgrade = false; | 1417 bool is_extension_upgrade = false; |
1337 bool is_extension_installed = false; | 1418 bool is_extension_installed = false; |
1338 const Extension* old = GetInstalledExtension(extension->id()); | 1419 const Extension* old = GetInstalledExtension(extension->id()); |
1339 if (old) { | 1420 if (old) { |
1340 is_extension_installed = true; | 1421 is_extension_installed = true; |
1341 int version_compare_result = | 1422 int version_compare_result = |
1342 extension->version()->CompareTo(*(old->version())); | 1423 extension->version()->CompareTo(*(old->version())); |
1343 is_extension_upgrade = version_compare_result > 0; | 1424 is_extension_upgrade = version_compare_result > 0; |
1425 | |
1344 // Other than for unpacked extensions, CrxInstaller should have guaranteed | 1426 // Other than for unpacked extensions, CrxInstaller should have guaranteed |
1345 // that we aren't downgrading. | 1427 // that we aren't downgrading. |
1346 if (!Manifest::IsUnpackedLocation(extension->location())) | 1428 if (!Manifest::IsUnpackedLocation(extension->location())) |
1347 CHECK_GE(version_compare_result, 0); | 1429 CHECK_GE(version_compare_result, 0); |
1348 } | 1430 } |
1349 system_->runtime_data()->SetBeingUpgraded(extension, is_extension_upgrade); | 1431 system_->runtime_data()->SetBeingUpgraded(extension, is_extension_upgrade); |
1350 | 1432 |
1351 // The extension is now loaded, remove its data from unloaded extension map. | 1433 // The extension is now loaded, remove its data from unloaded extension map. |
1352 unloaded_extension_paths_.erase(extension->id()); | 1434 unloaded_extension_paths_.erase(extension->id()); |
1353 | 1435 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1407 extension->id(), | 1489 extension->id(), |
1408 extension->ShouldDisplayInNewTabPage() && | 1490 extension->ShouldDisplayInNewTabPage() && |
1409 !extension_prefs_->IsEphemeralApp(extension->id())); | 1491 !extension_prefs_->IsEphemeralApp(extension->id())); |
1410 if (!extension_prefs_->IsEphemeralApp(extension->id())) { | 1492 if (!extension_prefs_->IsEphemeralApp(extension->id())) { |
1411 extension_prefs_->app_sorting()->EnsureValidOrdinals( | 1493 extension_prefs_->app_sorting()->EnsureValidOrdinals( |
1412 extension->id(), syncer::StringOrdinal()); | 1494 extension->id(), syncer::StringOrdinal()); |
1413 } | 1495 } |
1414 } | 1496 } |
1415 | 1497 |
1416 registry_->AddEnabled(extension); | 1498 registry_->AddEnabled(extension); |
1499 | |
1417 if (extension_sync_service_) | 1500 if (extension_sync_service_) |
1418 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); | 1501 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); |
1419 NotifyExtensionLoaded(extension); | 1502 NotifyExtensionLoaded(extension); |
1420 } | 1503 } |
1504 | |
1421 system_->runtime_data()->SetBeingUpgraded(extension, false); | 1505 system_->runtime_data()->SetBeingUpgraded(extension, false); |
1422 } | 1506 } |
1423 | 1507 |
1424 void ExtensionService::AddComponentExtension(const Extension* extension) { | 1508 void ExtensionService::AddComponentExtension(const Extension* extension) { |
1425 const std::string old_version_string( | 1509 const std::string old_version_string( |
1426 extension_prefs_->GetVersionString(extension->id())); | 1510 extension_prefs_->GetVersionString(extension->id())); |
1427 const Version old_version(old_version_string); | 1511 const Version old_version(old_version_string); |
1428 | 1512 |
1429 VLOG(1) << "AddComponentExtension " << extension->name(); | 1513 VLOG(1) << "AddComponentExtension " << extension->name(); |
1430 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { | 1514 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1705 page_ordinal, | 1789 page_ordinal, |
1706 install_parameter); | 1790 install_parameter); |
1707 } | 1791 } |
1708 } | 1792 } |
1709 | 1793 |
1710 void ExtensionService::OnExtensionManagementSettingsChanged() { | 1794 void ExtensionService::OnExtensionManagementSettingsChanged() { |
1711 error_controller_->ShowErrorIfNeeded(); | 1795 error_controller_->ShowErrorIfNeeded(); |
1712 CheckManagementPolicy(); | 1796 CheckManagementPolicy(); |
1713 } | 1797 } |
1714 | 1798 |
1799 bool ExtensionService::NeedsMigration(const Extension* extension){ | |
benwells
2014/11/03 00:08:41
Could all the new logic you're adding go in a new
benwells
2014/11/03 00:08:42
Can you add a check here that this is happening on
ryanackley
2014/11/04 22:51:54
Acknowledged.
ryanackley
2014/11/04 22:51:54
Acknowledged.
| |
1800 const Extension* old = GetInstalledExtension(extension->id()); | |
1801 return old && old->is_legacy_packaged_app() && extension->is_platform_app(); | |
1802 } | |
1803 | |
1804 void ExtensionService::MigrateThenFinishInstallation( | |
1805 const Extension* extension, | |
1806 bool was_ephemeral){ | |
1807 | |
1808 const Extension* old = GetInstalledExtension(extension->id()); | |
1809 | |
1810 // juggle the enabled status of the new and old extensions so we can get | |
1811 // the old and new storage partitions | |
1812 content::StoragePartition* old_partition = | |
1813 BrowserContext::GetStoragePartitionForSite( | |
1814 profile_, | |
1815 Extension::GetBaseURLFromExtensionId(extension->id())); | |
1816 bool oldWasDisabled = registry_->AddEnabled(extension); | |
1817 content::StoragePartition* new_partition = | |
1818 BrowserContext::GetStoragePartitionForSite( | |
1819 profile_, | |
1820 Extension::GetBaseURLFromExtensionId(extension->id())); | |
1821 | |
1822 if (!oldWasDisabled){ | |
1823 registry_->AddEnabled(old); | |
1824 }else{ | |
1825 registry_->RemoveEnabled(extension->id()); | |
1826 } | |
1827 | |
1828 BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE, | |
benwells
2014/11/03 00:08:41
Could you use the blocking pool instead? See https
ryanackley
2014/11/04 22:51:54
Acknowledged.
| |
1829 base::Bind( | |
1830 &MigrateLegacyPartition, | |
1831 old_partition, | |
1832 new_partition, | |
1833 make_scoped_refptr(extension)), | |
1834 base::Bind( | |
1835 &ExtensionService::FinishInstallation, | |
1836 AsWeakPtr(), | |
1837 make_scoped_refptr(extension), | |
1838 was_ephemeral)); | |
1839 } | |
1840 | |
1715 void ExtensionService::AddNewOrUpdatedExtension( | 1841 void ExtensionService::AddNewOrUpdatedExtension( |
1716 const Extension* extension, | 1842 const Extension* extension, |
1717 Extension::State initial_state, | 1843 Extension::State initial_state, |
1718 int install_flags, | 1844 int install_flags, |
1719 const syncer::StringOrdinal& page_ordinal, | 1845 const syncer::StringOrdinal& page_ordinal, |
1720 const std::string& install_parameter) { | 1846 const std::string& install_parameter) { |
1721 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1847 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1722 bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); | 1848 bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); |
1723 extension_prefs_->OnExtensionInstalled( | 1849 extension_prefs_->OnExtensionInstalled( |
1724 extension, initial_state, page_ordinal, install_flags, install_parameter); | 1850 extension, initial_state, page_ordinal, install_flags, install_parameter); |
1725 delayed_installs_.Remove(extension->id()); | 1851 delayed_installs_.Remove(extension->id()); |
1726 if (InstallVerifier::NeedsVerification(*extension)) | 1852 if (InstallVerifier::NeedsVerification(*extension)) |
1727 system_->install_verifier()->VerifyExtension(extension->id()); | 1853 system_->install_verifier()->VerifyExtension(extension->id()); |
1728 FinishInstallation(extension, was_ephemeral); | 1854 |
1855 if (NeedsMigration(extension)){ | |
benwells
2014/11/03 00:08:42
The patter chrome tends to use here is more like:
ryanackley
2014/11/04 22:51:54
Acknowledged.
| |
1856 MigrateThenFinishInstallation(extension, was_ephemeral); | |
1857 }else{ | |
1858 FinishInstallation(extension, was_ephemeral); | |
1859 } | |
1860 | |
1729 } | 1861 } |
1730 | 1862 |
1731 void ExtensionService::MaybeFinishDelayedInstallation( | 1863 void ExtensionService::MaybeFinishDelayedInstallation( |
1732 const std::string& extension_id) { | 1864 const std::string& extension_id) { |
1733 // Check if the extension already got installed. | 1865 // Check if the extension already got installed. |
1734 if (!delayed_installs_.Contains(extension_id)) | 1866 if (!delayed_installs_.Contains(extension_id)) |
1735 return; | 1867 return; |
1736 extensions::ExtensionPrefs::DelayReason reason = | 1868 extensions::ExtensionPrefs::DelayReason reason = |
1737 extension_prefs_->GetDelayedInstallReason(extension_id); | 1869 extension_prefs_->GetDelayedInstallReason(extension_id); |
1738 | 1870 |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2371 } | 2503 } |
2372 | 2504 |
2373 void ExtensionService::OnProfileDestructionStarted() { | 2505 void ExtensionService::OnProfileDestructionStarted() { |
2374 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); | 2506 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); |
2375 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); | 2507 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); |
2376 it != ids_to_unload.end(); | 2508 it != ids_to_unload.end(); |
2377 ++it) { | 2509 ++it) { |
2378 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); | 2510 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); |
2379 } | 2511 } |
2380 } | 2512 } |
OLD | NEW |