OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/browser/extension_prefs.h" | 5 #include "extensions/browser/extension_prefs.h" |
6 | 6 |
7 #include <iterator> | 7 #include <iterator> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/prefs/pref_notifier.h" | 10 #include "base/prefs/pref_notifier.h" |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 // A preference that indicates whether the extension was installed as an | 175 // A preference that indicates whether the extension was installed as an |
176 // OEM app. | 176 // OEM app. |
177 const char kPrefWasInstalledByOem[] = "was_installed_by_oem"; | 177 const char kPrefWasInstalledByOem[] = "was_installed_by_oem"; |
178 | 178 |
179 // Key for Geometry Cache preference. | 179 // Key for Geometry Cache preference. |
180 const char kPrefGeometryCache[] = "geometry_cache"; | 180 const char kPrefGeometryCache[] = "geometry_cache"; |
181 | 181 |
182 // A preference that indicates when an extension is last launched. | 182 // A preference that indicates when an extension is last launched. |
183 const char kPrefLastLaunchTime[] = "last_launch_time"; | 183 const char kPrefLastLaunchTime[] = "last_launch_time"; |
184 | 184 |
185 // A preference that marks an ephemeral app that was evicted from the cache. | |
186 // Their data is retained and garbage collected when inactive for a long period | |
187 // of time. | |
188 const char kPrefEvictedEphemeralApp[] = "evicted_ephemeral_app"; | |
189 | |
190 // A preference indicating whether the extension is an ephemeral app. | 185 // A preference indicating whether the extension is an ephemeral app. |
191 const char kPrefEphemeralApp[] = "ephemeral_app"; | 186 const char kPrefEphemeralApp[] = "ephemeral_app"; |
192 | 187 |
193 // Am installation parameter bundled with an extension. | 188 // Am installation parameter bundled with an extension. |
194 const char kPrefInstallParam[] = "install_parameter"; | 189 const char kPrefInstallParam[] = "install_parameter"; |
195 | 190 |
196 // A list of installed ids and a signature. | 191 // A list of installed ids and a signature. |
197 const char kInstallSignature[] = "extensions.install_signature"; | 192 const char kInstallSignature[] = "extensions.install_signature"; |
198 | 193 |
199 // Provider of write access to a dictionary storing extension prefs. | 194 // Provider of write access to a dictionary storing extension prefs. |
(...skipping 30 matching lines...) Expand all Loading... |
230 } | 225 } |
231 | 226 |
232 // Checks if kPrefBlacklist is set to true in the base::DictionaryValue. | 227 // Checks if kPrefBlacklist is set to true in the base::DictionaryValue. |
233 // Return false if the value is false or kPrefBlacklist does not exist. | 228 // Return false if the value is false or kPrefBlacklist does not exist. |
234 // This is used to decide if an extension is blacklisted. | 229 // This is used to decide if an extension is blacklisted. |
235 bool IsBlacklistBitSet(const base::DictionaryValue* ext) { | 230 bool IsBlacklistBitSet(const base::DictionaryValue* ext) { |
236 bool bool_value; | 231 bool bool_value; |
237 return ext->GetBoolean(kPrefBlacklist, &bool_value) && bool_value; | 232 return ext->GetBoolean(kPrefBlacklist, &bool_value) && bool_value; |
238 } | 233 } |
239 | 234 |
240 bool IsEvictedEphemeralApp(const base::DictionaryValue* ext) { | |
241 bool bool_value; | |
242 return ext->GetBoolean(kPrefEvictedEphemeralApp, &bool_value) && bool_value; | |
243 } | |
244 | |
245 void LoadExtensionControlledPrefs(ExtensionPrefs* prefs, | 235 void LoadExtensionControlledPrefs(ExtensionPrefs* prefs, |
246 ExtensionPrefValueMap* value_map, | 236 ExtensionPrefValueMap* value_map, |
247 const std::string& extension_id, | 237 const std::string& extension_id, |
248 ExtensionPrefsScope scope) { | 238 ExtensionPrefsScope scope) { |
249 std::string scope_string; | 239 std::string scope_string; |
250 if (!pref_names::ScopeToPrefName(scope, &scope_string)) | 240 if (!pref_names::ScopeToPrefName(scope, &scope_string)) |
251 return; | 241 return; |
252 std::string key = extension_id + "." + scope_string; | 242 std::string key = extension_id + "." + scope_string; |
253 | 243 |
254 const base::DictionaryValue* source_dict = | 244 const base::DictionaryValue* source_dict = |
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 // no longer lists the extension). | 1258 // no longer lists the extension). |
1269 if (!external_uninstall && Manifest::IsExternalLocation(location)) { | 1259 if (!external_uninstall && Manifest::IsExternalLocation(location)) { |
1270 UpdateExtensionPref(extension_id, kPrefState, | 1260 UpdateExtensionPref(extension_id, kPrefState, |
1271 new base::FundamentalValue( | 1261 new base::FundamentalValue( |
1272 Extension::EXTERNAL_EXTENSION_UNINSTALLED)); | 1262 Extension::EXTERNAL_EXTENSION_UNINSTALLED)); |
1273 extension_pref_value_map_->SetExtensionState(extension_id, false); | 1263 extension_pref_value_map_->SetExtensionState(extension_id, false); |
1274 FOR_EACH_OBSERVER(ExtensionPrefsObserver, | 1264 FOR_EACH_OBSERVER(ExtensionPrefsObserver, |
1275 observer_list_, | 1265 observer_list_, |
1276 OnExtensionStateChanged(extension_id, false)); | 1266 OnExtensionStateChanged(extension_id, false)); |
1277 } else { | 1267 } else { |
1278 if (IsEphemeralApp(extension_id)) { | 1268 DeleteExtensionPrefs(extension_id); |
1279 // Keep ephemeral apps around, but mark them as evicted. | |
1280 UpdateExtensionPref(extension_id, kPrefEvictedEphemeralApp, | |
1281 new base::FundamentalValue(true)); | |
1282 } else { | |
1283 DeleteExtensionPrefs(extension_id); | |
1284 } | |
1285 } | 1269 } |
1286 } | 1270 } |
1287 | 1271 |
1288 void ExtensionPrefs::SetExtensionState(const std::string& extension_id, | 1272 void ExtensionPrefs::SetExtensionState(const std::string& extension_id, |
1289 Extension::State state) { | 1273 Extension::State state) { |
1290 UpdateExtensionPref(extension_id, kPrefState, | 1274 UpdateExtensionPref(extension_id, kPrefState, |
1291 new base::FundamentalValue(state)); | 1275 new base::FundamentalValue(state)); |
1292 bool enabled = (state == Extension::ENABLED); | 1276 bool enabled = (state == Extension::ENABLED); |
1293 extension_pref_value_map_->SetExtensionState(extension_id, enabled); | 1277 extension_pref_value_map_->SetExtensionState(extension_id, enabled); |
1294 FOR_EACH_OBSERVER(ExtensionPrefsObserver, | 1278 FOR_EACH_OBSERVER(ExtensionPrefsObserver, |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 // Old preferences files may not have kPrefState for component extensions. | 1386 // Old preferences files may not have kPrefState for component extensions. |
1403 return scoped_ptr<ExtensionInfo>(); | 1387 return scoped_ptr<ExtensionInfo>(); |
1404 } | 1388 } |
1405 | 1389 |
1406 if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) { | 1390 if (state_value == Extension::EXTERNAL_EXTENSION_UNINSTALLED) { |
1407 LOG(WARNING) << "External extension with id " << extension_id | 1391 LOG(WARNING) << "External extension with id " << extension_id |
1408 << " has been uninstalled by the user"; | 1392 << " has been uninstalled by the user"; |
1409 return scoped_ptr<ExtensionInfo>(); | 1393 return scoped_ptr<ExtensionInfo>(); |
1410 } | 1394 } |
1411 | 1395 |
1412 if (IsEvictedEphemeralApp(ext)) { | |
1413 // Hide evicted ephemeral apps. | |
1414 return scoped_ptr<ExtensionInfo>(); | |
1415 } | |
1416 | |
1417 return GetInstalledInfoHelper(extension_id, ext); | 1396 return GetInstalledInfoHelper(extension_id, ext); |
1418 } | 1397 } |
1419 | 1398 |
1420 scoped_ptr<ExtensionPrefs::ExtensionsInfo> | 1399 scoped_ptr<ExtensionPrefs::ExtensionsInfo> |
1421 ExtensionPrefs::GetInstalledExtensionsInfo() const { | 1400 ExtensionPrefs::GetInstalledExtensionsInfo() const { |
1422 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); | 1401 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); |
1423 | 1402 |
1424 const base::DictionaryValue* extensions = | 1403 const base::DictionaryValue* extensions = |
1425 prefs_->GetDictionary(pref_names::kExtensions); | 1404 prefs_->GetDictionary(pref_names::kExtensions); |
1426 for (base::DictionaryValue::Iterator extension_id(*extensions); | 1405 for (base::DictionaryValue::Iterator extension_id(*extensions); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 continue; | 1562 continue; |
1584 | 1563 |
1585 scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key()); | 1564 scoped_ptr<ExtensionInfo> info = GetDelayedInstallInfo(extension_id.key()); |
1586 if (info) | 1565 if (info) |
1587 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); | 1566 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); |
1588 } | 1567 } |
1589 | 1568 |
1590 return extensions_info.Pass(); | 1569 return extensions_info.Pass(); |
1591 } | 1570 } |
1592 | 1571 |
1593 scoped_ptr<ExtensionPrefs::ExtensionsInfo> | |
1594 ExtensionPrefs::GetEvictedEphemeralAppsInfo() const { | |
1595 scoped_ptr<ExtensionsInfo> extensions_info(new ExtensionsInfo); | |
1596 | |
1597 const base::DictionaryValue* extensions = | |
1598 prefs_->GetDictionary(pref_names::kExtensions); | |
1599 for (base::DictionaryValue::Iterator extension_id(*extensions); | |
1600 !extension_id.IsAtEnd(); extension_id.Advance()) { | |
1601 const base::DictionaryValue* ext = NULL; | |
1602 if (!Extension::IdIsValid(extension_id.key()) || | |
1603 !extension_id.value().GetAsDictionary(&ext)) { | |
1604 continue; | |
1605 } | |
1606 | |
1607 if (!IsEvictedEphemeralApp(ext)) | |
1608 continue; | |
1609 | |
1610 scoped_ptr<ExtensionInfo> info = | |
1611 GetInstalledInfoHelper(extension_id.key(), ext); | |
1612 if (info) | |
1613 extensions_info->push_back(linked_ptr<ExtensionInfo>(info.release())); | |
1614 } | |
1615 | |
1616 return extensions_info.Pass(); | |
1617 } | |
1618 | |
1619 scoped_ptr<ExtensionInfo> ExtensionPrefs::GetEvictedEphemeralAppInfo( | |
1620 const std::string& extension_id) const { | |
1621 const base::DictionaryValue* extension_prefs = GetExtensionPref(extension_id); | |
1622 if (!extension_prefs) | |
1623 return scoped_ptr<ExtensionInfo>(); | |
1624 | |
1625 if (!IsEvictedEphemeralApp(extension_prefs)) | |
1626 return scoped_ptr<ExtensionInfo>(); | |
1627 | |
1628 return GetInstalledInfoHelper(extension_id, extension_prefs); | |
1629 } | |
1630 | |
1631 void ExtensionPrefs::RemoveEvictedEphemeralApp( | |
1632 const std::string& extension_id) { | |
1633 if (ReadPrefAsBooleanAndReturn(extension_id, kPrefEvictedEphemeralApp)) | |
1634 DeleteExtensionPrefs(extension_id); | |
1635 } | |
1636 | |
1637 bool ExtensionPrefs::IsEphemeralApp(const std::string& extension_id) const { | 1572 bool ExtensionPrefs::IsEphemeralApp(const std::string& extension_id) const { |
1638 // Hide the data of evicted ephemeral apps. | |
1639 if (ReadPrefAsBooleanAndReturn(extension_id, kPrefEvictedEphemeralApp)) | |
1640 return false; | |
1641 | |
1642 if (ReadPrefAsBooleanAndReturn(extension_id, kPrefEphemeralApp)) | 1573 if (ReadPrefAsBooleanAndReturn(extension_id, kPrefEphemeralApp)) |
1643 return true; | 1574 return true; |
1644 | 1575 |
1645 // Ephemerality was previously stored in the creation flags, so we must also | 1576 // Ephemerality was previously stored in the creation flags, so we must also |
1646 // check it for backcompatibility. | 1577 // check it for backcompatibility. |
1647 return (GetCreationFlags(extension_id) & Extension::IS_EPHEMERAL) != 0; | 1578 return (GetCreationFlags(extension_id) & Extension::IS_EPHEMERAL) != 0; |
1648 } | 1579 } |
1649 | 1580 |
1650 void ExtensionPrefs::OnEphemeralAppPromoted(const std::string& extension_id) { | 1581 void ExtensionPrefs::OnEphemeralAppPromoted(const std::string& extension_id) { |
1651 DCHECK(IsEphemeralApp(extension_id)); | 1582 DCHECK(IsEphemeralApp(extension_id)); |
1652 | 1583 |
1653 ScopedExtensionPrefUpdate update(prefs_, extension_id); | 1584 UpdateExtensionPref( |
1654 update->Set(kPrefEphemeralApp, new base::FundamentalValue(false)); | 1585 extension_id, kPrefEphemeralApp, new base::FundamentalValue(false)); |
1655 | |
1656 DCHECK(!IsEvictedEphemeralApp(update.Get())); | |
1657 update->Remove(kPrefEvictedEphemeralApp, NULL); | |
1658 } | 1586 } |
1659 | 1587 |
1660 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) { | 1588 bool ExtensionPrefs::WasAppDraggedByUser(const std::string& extension_id) { |
1661 return ReadPrefAsBooleanAndReturn(extension_id, kPrefUserDraggedApp); | 1589 return ReadPrefAsBooleanAndReturn(extension_id, kPrefUserDraggedApp); |
1662 } | 1590 } |
1663 | 1591 |
1664 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) { | 1592 void ExtensionPrefs::SetAppDraggedByUser(const std::string& extension_id) { |
1665 UpdateExtensionPref(extension_id, kPrefUserDraggedApp, | 1593 UpdateExtensionPref(extension_id, kPrefUserDraggedApp, |
1666 new base::FundamentalValue(true)); | 1594 new base::FundamentalValue(true)); |
1667 } | 1595 } |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2199 new base::ListValue); | 2127 new base::ListValue); |
2200 } | 2128 } |
2201 | 2129 |
2202 // If this point has been reached, any pending installs should be considered | 2130 // If this point has been reached, any pending installs should be considered |
2203 // out of date. | 2131 // out of date. |
2204 extension_dict->Remove(kDelayedInstallInfo, NULL); | 2132 extension_dict->Remove(kDelayedInstallInfo, NULL); |
2205 | 2133 |
2206 // Clear state that may be registered from a previous install. | 2134 // Clear state that may be registered from a previous install. |
2207 extension_dict->Remove(EventRouter::kRegisteredEvents, NULL); | 2135 extension_dict->Remove(EventRouter::kRegisteredEvents, NULL); |
2208 | 2136 |
2209 // When evicted ephemeral apps are re-installed, this flag must be reset. | |
2210 extension_dict->Remove(kPrefEvictedEphemeralApp, NULL); | |
2211 | |
2212 // FYI, all code below here races on sudden shutdown because |extension_dict|, | 2137 // FYI, all code below here races on sudden shutdown because |extension_dict|, |
2213 // |app_sorting_|, |extension_pref_value_map_|, and (potentially) observers | 2138 // |app_sorting_|, |extension_pref_value_map_|, and (potentially) observers |
2214 // are updated non-transactionally. This is probably not fixable without | 2139 // are updated non-transactionally. This is probably not fixable without |
2215 // nested transactional updates to pref dictionaries. | 2140 // nested transactional updates to pref dictionaries. |
2216 if (needs_sort_ordinal) | 2141 if (needs_sort_ordinal) |
2217 app_sorting_->EnsureValidOrdinals(extension_id, suggested_page_ordinal); | 2142 app_sorting_->EnsureValidOrdinals(extension_id, suggested_page_ordinal); |
2218 | 2143 |
2219 bool is_enabled = false; | 2144 bool is_enabled = false; |
2220 int initial_state; | 2145 int initial_state; |
2221 if (extension_dict->GetInteger(kPrefState, &initial_state)) { | 2146 if (extension_dict->GetInteger(kPrefState, &initial_state)) { |
2222 is_enabled = initial_state == Extension::ENABLED; | 2147 is_enabled = initial_state == Extension::ENABLED; |
2223 } | 2148 } |
2224 bool is_incognito_enabled = IsIncognitoEnabled(extension_id); | 2149 bool is_incognito_enabled = IsIncognitoEnabled(extension_id); |
2225 | 2150 |
2226 extension_pref_value_map_->RegisterExtension( | 2151 extension_pref_value_map_->RegisterExtension( |
2227 extension_id, install_time, is_enabled, is_incognito_enabled); | 2152 extension_id, install_time, is_enabled, is_incognito_enabled); |
2228 | 2153 |
2229 FOR_EACH_OBSERVER( | 2154 FOR_EACH_OBSERVER( |
2230 ExtensionPrefsObserver, | 2155 ExtensionPrefsObserver, |
2231 observer_list_, | 2156 observer_list_, |
2232 OnExtensionRegistered(extension_id, install_time, is_enabled)); | 2157 OnExtensionRegistered(extension_id, install_time, is_enabled)); |
2233 } | 2158 } |
2234 | 2159 |
2235 } // namespace extensions | 2160 } // namespace extensions |
OLD | NEW |