OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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_prefs.h" | 5 #include "chrome/browser/extensions/extension_prefs.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/prefs/pref_notifier.h" | 8 #include "base/prefs/pref_notifier.h" |
9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 | 112 |
113 // A bit we use to keep track of whether we need to do an "active" ping. | 113 // A bit we use to keep track of whether we need to do an "active" ping. |
114 const char kActiveBit[] = "active_bit"; | 114 const char kActiveBit[] = "active_bit"; |
115 | 115 |
116 // Path for settings specific to blacklist update. | 116 // Path for settings specific to blacklist update. |
117 const char kExtensionsBlacklistUpdate[] = "extensions.blacklistupdate"; | 117 const char kExtensionsBlacklistUpdate[] = "extensions.blacklistupdate"; |
118 | 118 |
119 // Path for the idle install info dictionary preference. | 119 // Path for the idle install info dictionary preference. |
120 const char kIdleInstallInfo[] = "idle_install_info"; | 120 const char kIdleInstallInfo[] = "idle_install_info"; |
121 | 121 |
| 122 // Path for the suggested page ordinal of a delayed extension install. |
| 123 const char kPrefSuggestedPageOrdinal[] = "suggested_page_ordinal"; |
| 124 |
122 // A preference that, if true, will allow this extension to run in incognito | 125 // A preference that, if true, will allow this extension to run in incognito |
123 // mode. | 126 // mode. |
124 const char kPrefIncognitoEnabled[] = "incognito"; | 127 const char kPrefIncognitoEnabled[] = "incognito"; |
125 | 128 |
126 // A preference to control whether an extension is allowed to inject script in | 129 // A preference to control whether an extension is allowed to inject script in |
127 // pages with file URLs. | 130 // pages with file URLs. |
128 const char kPrefAllowFileAccess[] = "newAllowFileAccess"; | 131 const char kPrefAllowFileAccess[] = "newAllowFileAccess"; |
129 // TODO(jstritar): As part of fixing http://crbug.com/91577, we revoked all | 132 // TODO(jstritar): As part of fixing http://crbug.com/91577, we revoked all |
130 // extension file access by renaming the pref. We should eventually clean up | 133 // extension file access by renaming the pref. We should eventually clean up |
131 // the old flag and possibly go back to that name. | 134 // the old flag and possibly go back to that name. |
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1441 } | 1444 } |
1442 | 1445 |
1443 void ExtensionPrefs::SetActionBoxOrder(const ExtensionIdList& extension_ids) { | 1446 void ExtensionPrefs::SetActionBoxOrder(const ExtensionIdList& extension_ids) { |
1444 SetExtensionPrefFromVector(kExtensionActionBox, extension_ids); | 1447 SetExtensionPrefFromVector(kExtensionActionBox, extension_ids); |
1445 } | 1448 } |
1446 | 1449 |
1447 void ExtensionPrefs::OnExtensionInstalled( | 1450 void ExtensionPrefs::OnExtensionInstalled( |
1448 const Extension* extension, | 1451 const Extension* extension, |
1449 Extension::State initial_state, | 1452 Extension::State initial_state, |
1450 const syncer::StringOrdinal& page_ordinal) { | 1453 const syncer::StringOrdinal& page_ordinal) { |
1451 const std::string& id = extension->id(); | 1454 ScopedExtensionPrefUpdate update(prefs_, extension->id()); |
1452 CHECK(Extension::IdIsValid(id)); | |
1453 ScopedExtensionPrefUpdate update(prefs_, id); | |
1454 DictionaryValue* extension_dict = update.Get(); | 1455 DictionaryValue* extension_dict = update.Get(); |
1455 const base::Time install_time = time_provider_->GetCurrentTime(); | 1456 const base::Time install_time = time_provider_->GetCurrentTime(); |
1456 | 1457 PopulateExtensionInfoPrefs(extension, install_time, initial_state, |
1457 // Leave the state blank for component extensions so that old chrome versions | 1458 extension_dict); |
1458 // loading new profiles do not fail in GetInstalledExtensionInfo. Older | 1459 FinishExtensionInfoPrefs(extension->id(), install_time, |
1459 // Chrome versions would only check for an omitted state. | 1460 extension->RequiresSortOrdinal(), |
1460 if (initial_state != Extension::ENABLED_COMPONENT) | 1461 page_ordinal, extension_dict); |
1461 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); | |
1462 | |
1463 extension_dict->Set(kPrefLocation, | |
1464 Value::CreateIntegerValue(extension->location())); | |
1465 extension_dict->Set(kPrefCreationFlags, | |
1466 Value::CreateIntegerValue(extension->creation_flags())); | |
1467 extension_dict->Set(kPrefFromWebStore, | |
1468 Value::CreateBooleanValue(extension->from_webstore())); | |
1469 extension_dict->Set(kPrefFromBookmark, | |
1470 Value::CreateBooleanValue(extension->from_bookmark())); | |
1471 extension_dict->Set(kPrefWasInstalledByDefault, | |
1472 Value::CreateBooleanValue(extension->was_installed_by_default())); | |
1473 extension_dict->Set(kPrefInstallTime, | |
1474 Value::CreateStringValue( | |
1475 base::Int64ToString(install_time.ToInternalValue()))); | |
1476 extension_dict->Set(kPrefPreferences, new DictionaryValue()); | |
1477 extension_dict->Set(kPrefIncognitoPreferences, new DictionaryValue()); | |
1478 extension_dict->Set(kPrefRegularOnlyPreferences, new DictionaryValue()); | |
1479 extension_dict->Set(kPrefContentSettings, new ListValue()); | |
1480 extension_dict->Set(kPrefIncognitoContentSettings, new ListValue()); | |
1481 | |
1482 FilePath::StringType path = MakePathRelative(install_directory_, | |
1483 extension->path()); | |
1484 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); | |
1485 // We store prefs about LOAD extensions, but don't cache their manifest | |
1486 // since it may change on disk. | |
1487 if (extension->location() != Extension::LOAD) { | |
1488 extension_dict->Set(kPrefManifest, | |
1489 extension->manifest()->value()->DeepCopy()); | |
1490 } | |
1491 | |
1492 // Clear state that may be registered from a previous install. | |
1493 extension_dict->Remove(kRegisteredEvents, NULL); | |
1494 | |
1495 if (extension->RequiresSortOrdinal()) | |
1496 extension_sorting_->EnsureValidOrdinals(extension->id(), page_ordinal); | |
1497 | |
1498 extension_pref_value_map_->RegisterExtension( | |
1499 id, install_time, initial_state == Extension::ENABLED); | |
1500 content_settings_store_->RegisterExtension( | |
1501 id, install_time, initial_state == Extension::ENABLED); | |
1502 } | 1462 } |
1503 | 1463 |
1504 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, | 1464 void ExtensionPrefs::OnExtensionUninstalled(const std::string& extension_id, |
1505 const Extension::Location& location, | 1465 const Extension::Location& location, |
1506 bool external_uninstall) { | 1466 bool external_uninstall) { |
1507 extension_sorting_->ClearOrdinals(extension_id); | 1467 extension_sorting_->ClearOrdinals(extension_id); |
1508 | 1468 |
1509 // For external extensions, we save a preference reminding ourself not to try | 1469 // For external extensions, we save a preference reminding ourself not to try |
1510 // and install the extension anymore (except when |external_uninstall| is | 1470 // and install the extension anymore (except when |external_uninstall| is |
1511 // true, which signifies that the registry key was deleted or the pref file | 1471 // true, which signifies that the registry key was deleted or the pref file |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 scoped_ptr<ExtensionInfo> info = GetInstalledExtensionInfo(*extension_id); | 1670 scoped_ptr<ExtensionInfo> info = GetInstalledExtensionInfo(*extension_id); |
1711 if (info) | 1671 if (info) |
1712 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); | 1672 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); |
1713 } | 1673 } |
1714 | 1674 |
1715 return extensions_info.Pass(); | 1675 return extensions_info.Pass(); |
1716 } | 1676 } |
1717 | 1677 |
1718 void ExtensionPrefs::SetIdleInstallInfo( | 1678 void ExtensionPrefs::SetIdleInstallInfo( |
1719 const Extension* extension, | 1679 const Extension* extension, |
1720 Extension::State initial_state) { | 1680 Extension::State initial_state, |
1721 const base::Time install_time = time_provider_->GetCurrentTime(); | 1681 const syncer::StringOrdinal& page_ordinal) { |
1722 DictionaryValue* extension_dict = new DictionaryValue(); | 1682 DictionaryValue* extension_dict = new DictionaryValue(); |
1723 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); | 1683 PopulateExtensionInfoPrefs(extension, time_provider_->GetCurrentTime(), |
1724 extension_dict->Set(kPrefLocation, | 1684 initial_state, extension_dict); |
1725 Value::CreateIntegerValue(extension->location())); | |
1726 extension_dict->Set(kPrefCreationFlags, | |
1727 Value::CreateIntegerValue(extension->creation_flags())); | |
1728 extension_dict->Set(kPrefFromWebStore, | |
1729 Value::CreateBooleanValue(extension->from_webstore())); | |
1730 extension_dict->Set(kPrefFromBookmark, | |
1731 Value::CreateBooleanValue(extension->from_bookmark())); | |
1732 extension_dict->Set(kPrefWasInstalledByDefault, | |
1733 Value::CreateBooleanValue(extension->was_installed_by_default())); | |
1734 extension_dict->Set(kPrefInstallTime, | |
1735 Value::CreateStringValue( | |
1736 base::Int64ToString(install_time.ToInternalValue()))); | |
1737 | 1685 |
1738 FilePath::StringType path = MakePathRelative(install_directory_, | 1686 // Add transient data that is needed by FinishIdleInstallInfo(), but |
1739 extension->path()); | 1687 // should not be in the final extension prefs. All entries here should have |
1740 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); | 1688 // a corresponding Remove() call in FinishIdleInstallInfo(). |
1741 extension_dict->Set(kPrefManifest, | 1689 if (extension->RequiresSortOrdinal()) { |
1742 extension->manifest()->value()->DeepCopy()); | 1690 extension_dict->SetString(kPrefSuggestedPageOrdinal, |
| 1691 page_ordinal.ToInternalValue()); |
| 1692 } |
1743 | 1693 |
1744 UpdateExtensionPref(extension->id(), kIdleInstallInfo, extension_dict); | 1694 UpdateExtensionPref(extension->id(), kIdleInstallInfo, extension_dict); |
1745 } | 1695 } |
1746 | 1696 |
1747 bool ExtensionPrefs::RemoveIdleInstallInfo(const std::string& extension_id) { | 1697 bool ExtensionPrefs::RemoveIdleInstallInfo(const std::string& extension_id) { |
1748 if (!GetExtensionPref(extension_id)) | 1698 if (!GetExtensionPref(extension_id)) |
1749 return false; | 1699 return false; |
1750 ScopedExtensionPrefUpdate update(prefs_, extension_id); | 1700 ScopedExtensionPrefUpdate update(prefs_, extension_id); |
1751 bool result = update->Remove(kIdleInstallInfo, NULL); | 1701 bool result = update->Remove(kIdleInstallInfo, NULL); |
1752 return result; | 1702 return result; |
1753 } | 1703 } |
1754 | 1704 |
1755 bool ExtensionPrefs::FinishIdleInstallInfo(const std::string& extension_id) { | 1705 bool ExtensionPrefs::FinishIdleInstallInfo(const std::string& extension_id) { |
1756 CHECK(Extension::IdIsValid(extension_id)); | 1706 CHECK(Extension::IdIsValid(extension_id)); |
1757 ScopedExtensionPrefUpdate update(prefs_, extension_id); | 1707 ScopedExtensionPrefUpdate update(prefs_, extension_id); |
1758 DictionaryValue* extension_dict = update.Get(); | 1708 DictionaryValue* extension_dict = update.Get(); |
1759 DictionaryValue* update_dict; | 1709 DictionaryValue* pending_install_dict = NULL; |
1760 if (!extension_dict->GetDictionary(kIdleInstallInfo, &update_dict)) | 1710 if (!extension_dict->GetDictionary(kIdleInstallInfo, &pending_install_dict)) |
1761 return false; | 1711 return false; |
1762 | 1712 |
| 1713 // Retrieve and clear transient values populated by SetIdleInstallInfo(). Also |
| 1714 // do any other data cleanup that makes sense. |
| 1715 std::string serialized_ordinal; |
| 1716 syncer::StringOrdinal suggested_page_ordinal; |
| 1717 bool needs_sort_ordinal = false; |
| 1718 if (pending_install_dict->GetString(kPrefSuggestedPageOrdinal, |
| 1719 &serialized_ordinal)) { |
| 1720 suggested_page_ordinal = syncer::StringOrdinal(serialized_ordinal); |
| 1721 needs_sort_ordinal = true; |
| 1722 pending_install_dict->Remove(kPrefSuggestedPageOrdinal, NULL); |
| 1723 } |
| 1724 |
1763 const base::Time install_time = time_provider_->GetCurrentTime(); | 1725 const base::Time install_time = time_provider_->GetCurrentTime(); |
1764 extension_dict->MergeDictionary(update_dict); | 1726 pending_install_dict->Set( |
1765 extension_dict->Set(kPrefInstallTime, | 1727 kPrefInstallTime, |
1766 Value::CreateStringValue( | 1728 Value::CreateStringValue( |
1767 base::Int64ToString(install_time.ToInternalValue()))); | 1729 base::Int64ToString(install_time.ToInternalValue()))); |
1768 extension_dict->Set(kPrefPreferences, new DictionaryValue()); | |
1769 extension_dict->Set(kPrefIncognitoPreferences, new DictionaryValue()); | |
1770 extension_dict->Set(kPrefRegularOnlyPreferences, new DictionaryValue()); | |
1771 extension_dict->Set(kPrefContentSettings, new ListValue()); | |
1772 extension_dict->Set(kPrefIncognitoContentSettings, new ListValue()); | |
1773 | 1730 |
1774 // Clear state that may be registered from a previous install. | 1731 // Commit the delayed install data. |
1775 extension_dict->Remove(kRegisteredEvents, NULL); | 1732 extension_dict->MergeDictionary(pending_install_dict); |
1776 | 1733 FinishExtensionInfoPrefs(extension_id, install_time, needs_sort_ordinal, |
1777 // Remove pending update information | 1734 suggested_page_ordinal, extension_dict); |
1778 extension_dict->Remove(kIdleInstallInfo, NULL); | |
1779 | |
1780 int initial_state; | |
1781 if (extension_dict->GetInteger(kPrefState, &initial_state)) { | |
1782 extension_pref_value_map_->RegisterExtension( | |
1783 extension_id, install_time, initial_state == Extension::ENABLED); | |
1784 content_settings_store_->RegisterExtension( | |
1785 extension_id, install_time, initial_state == Extension::ENABLED); | |
1786 } | |
1787 return true; | 1735 return true; |
1788 } | 1736 } |
1789 | 1737 |
1790 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetIdleInstallInfo( | 1738 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetIdleInstallInfo( |
1791 const std::string& extension_id) const { | 1739 const std::string& extension_id) const { |
1792 const DictionaryValue* extension_prefs = GetExtensionPref(extension_id); | 1740 const DictionaryValue* extension_prefs = GetExtensionPref(extension_id); |
1793 if (!extension_prefs) | 1741 if (!extension_prefs) |
1794 return scoped_ptr<ExtensionInfo>(); | 1742 return scoped_ptr<ExtensionInfo>(); |
1795 | 1743 |
1796 const DictionaryValue* ext = NULL; | 1744 const DictionaryValue* ext = NULL; |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2308 const char* pref, | 2256 const char* pref, |
2309 const ExtensionIdList& strings) { | 2257 const ExtensionIdList& strings) { |
2310 ListPrefUpdate update(prefs_, pref); | 2258 ListPrefUpdate update(prefs_, pref); |
2311 ListValue* list_of_values = update.Get(); | 2259 ListValue* list_of_values = update.Get(); |
2312 list_of_values->Clear(); | 2260 list_of_values->Clear(); |
2313 for (ExtensionIdList::const_iterator iter = strings.begin(); | 2261 for (ExtensionIdList::const_iterator iter = strings.begin(); |
2314 iter != strings.end(); ++iter) | 2262 iter != strings.end(); ++iter) |
2315 list_of_values->Append(new StringValue(*iter)); | 2263 list_of_values->Append(new StringValue(*iter)); |
2316 } | 2264 } |
2317 | 2265 |
| 2266 void ExtensionPrefs::PopulateExtensionInfoPrefs( |
| 2267 const Extension* extension, |
| 2268 const base::Time install_time, |
| 2269 Extension::State initial_state, |
| 2270 DictionaryValue* extension_dict) { |
| 2271 // Leave the state blank for component extensions so that old chrome versions |
| 2272 // loading new profiles do not fail in GetInstalledExtensionInfo. Older |
| 2273 // Chrome versions would only check for an omitted state. |
| 2274 if (initial_state != Extension::ENABLED_COMPONENT) |
| 2275 extension_dict->Set(kPrefState, Value::CreateIntegerValue(initial_state)); |
| 2276 |
| 2277 extension_dict->Set(kPrefLocation, |
| 2278 Value::CreateIntegerValue(extension->location())); |
| 2279 extension_dict->Set(kPrefCreationFlags, |
| 2280 Value::CreateIntegerValue(extension->creation_flags())); |
| 2281 extension_dict->Set(kPrefFromWebStore, |
| 2282 Value::CreateBooleanValue(extension->from_webstore())); |
| 2283 extension_dict->Set(kPrefFromBookmark, |
| 2284 Value::CreateBooleanValue(extension->from_bookmark())); |
| 2285 extension_dict->Set(kPrefWasInstalledByDefault, |
| 2286 Value::CreateBooleanValue(extension->was_installed_by_default())); |
| 2287 extension_dict->Set(kPrefInstallTime, |
| 2288 Value::CreateStringValue( |
| 2289 base::Int64ToString(install_time.ToInternalValue()))); |
| 2290 |
| 2291 FilePath::StringType path = MakePathRelative(install_directory_, |
| 2292 extension->path()); |
| 2293 extension_dict->Set(kPrefPath, Value::CreateStringValue(path)); |
| 2294 // We store prefs about LOAD extensions, but don't cache their manifest |
| 2295 // since it may change on disk. |
| 2296 if (extension->location() != Extension::LOAD) { |
| 2297 extension_dict->Set(kPrefManifest, |
| 2298 extension->manifest()->value()->DeepCopy()); |
| 2299 } |
| 2300 } |
| 2301 |
| 2302 void ExtensionPrefs::FinishExtensionInfoPrefs( |
| 2303 const std::string& extension_id, |
| 2304 const base::Time install_time, |
| 2305 bool needs_sort_ordinal, |
| 2306 const syncer::StringOrdinal& suggested_page_ordinal, |
| 2307 DictionaryValue* extension_dict) { |
| 2308 // Reinitializes various preferences with empty dictionaries. |
| 2309 extension_dict->Set(kPrefPreferences, new DictionaryValue()); |
| 2310 extension_dict->Set(kPrefIncognitoPreferences, new DictionaryValue()); |
| 2311 extension_dict->Set(kPrefRegularOnlyPreferences, new DictionaryValue()); |
| 2312 extension_dict->Set(kPrefContentSettings, new ListValue()); |
| 2313 extension_dict->Set(kPrefIncognitoContentSettings, new ListValue()); |
| 2314 |
| 2315 // If this point has been reached, any pending installs should be considered |
| 2316 // out of date. |
| 2317 extension_dict->Remove(kIdleInstallInfo, NULL); |
| 2318 |
| 2319 // Clear state that may be registered from a previous install. |
| 2320 extension_dict->Remove(kRegisteredEvents, NULL); |
| 2321 |
| 2322 // FYI, all code below here races on sudden shutdown because |
| 2323 // |extension_dict|, |extension_sorting_|, |extension_pref_value_map_|, |
| 2324 // and |content_settings_store_| are updated non-transactionally. This is |
| 2325 // probably not fixable without nested transactional updates to pref |
| 2326 // dictionaries. |
| 2327 if (needs_sort_ordinal) { |
| 2328 extension_sorting_->EnsureValidOrdinals(extension_id, |
| 2329 suggested_page_ordinal); |
| 2330 } |
| 2331 |
| 2332 bool is_enabled = false; |
| 2333 int initial_state; |
| 2334 if (extension_dict->GetInteger(kPrefState, &initial_state)) { |
| 2335 is_enabled = initial_state == Extension::ENABLED; |
| 2336 } |
| 2337 |
| 2338 extension_pref_value_map_->RegisterExtension(extension_id, install_time, |
| 2339 is_enabled); |
| 2340 content_settings_store_->RegisterExtension(extension_id, install_time, |
| 2341 is_enabled); |
| 2342 } |
| 2343 |
2318 } // namespace extensions | 2344 } // namespace extensions |
OLD | NEW |