15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/preference/preference_api.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/extensions/api/content_settings/content_settings_service.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/preference/preference_api_constants.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/preference/preference_helpers.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/proxy/proxy_api.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 2229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch#include "chrome/browser/net/prediction_options.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/translate/core/common/translate_pref_names.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_pref_value_map.h" 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_pref_value_map_factory.h" 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs_factory.h" 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system_provider.h" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extensions_browser_client.h" 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "extensions/browser/pref_names.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h" 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h" 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extensions::preference_api_constants; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace helpers = extensions::preference_helpers; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::DictionaryValue; 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PrefMappingEntry { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Name of the preference referenced by the extension API JSON. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* extension_pref; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Name of the preference in the PrefStores. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* browser_pref; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Permission required to read and observe this preference. 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Use APIPermission::kInvalid for |read_permission| to express that the read 57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // permission should not be granted. 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID read_permission; 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Permission required to write this preference. 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Use APIPermission::kInvalid for |write_permission| to express that the 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // write permission should not be granted. 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID write_permission; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOnPrefChangeFormat[] = "types.ChromeSetting.%s.onChange"; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kConversionErrorMessage[] = 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error: Stored value for preference '*' cannot be converted " 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "properly."; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrefMappingEntry kPrefMapping[] = { 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"alternateErrorPagesEnabled", prefs::kAlternateErrorPagesEnabled, 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"autofillEnabled", autofill::prefs::kAutofillEnabled, 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"hyperlinkAuditingEnabled", prefs::kEnableHyperlinkAuditing, 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 7829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch {"networkPredictionEnabled", prefs::kNetworkPredictionOptions, 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) APIPermission::kPrivacy, APIPermission::kPrivacy}, 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch {"passwordSavingEnabled", 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch password_manager::prefs::kPasswordManagerSavingEnabled, 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch {"protectedContentEnabled", prefs::kEnableDRM, APIPermission::kPrivacy, 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch APIPermission::kPrivacy}, 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"proxy", prefs::kProxy, APIPermission::kProxy, APIPermission::kProxy}, 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"referrersEnabled", prefs::kEnableReferrers, APIPermission::kPrivacy, 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy}, 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"safeBrowsingEnabled", prefs::kSafeBrowsingEnabled, 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"searchSuggestEnabled", prefs::kSearchSuggestEnabled, 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"spellingServiceEnabled", prefs::kSpellCheckUseSpellingService, 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"thirdPartyCookiesAllowed", prefs::kBlockThirdPartyCookies, 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch {"translationServiceEnabled", prefs::kEnableTranslate, 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kPrivacy, APIPermission::kPrivacy}, 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {"autoclick", prefs::kAccessibilityAutoclickEnabled, 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesRead, 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesModify}, 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {"highContrast", prefs::kAccessibilityHighContrastEnabled, 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesRead, 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesModify}, 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {"largeCursor", prefs::kAccessibilityLargeCursorEnabled, 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesRead, 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesModify}, 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {"screenMagnifier", prefs::kAccessibilityScreenMagnifierEnabled, 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesRead, 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesModify}, 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {"spokenFeedback", prefs::kAccessibilitySpokenFeedbackEnabled, 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesRead, 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesModify}, 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {"stickyKeys", prefs::kAccessibilityStickyKeysEnabled, 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesRead, 116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesModify}, 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) {"virtualKeyboard", prefs::kAccessibilityVirtualKeyboardEnabled, 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesRead, 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::kAccessibilityFeaturesModify}, 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IdentityPrefTransformer : public PrefTransformerInterface { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::Value* ExtensionToBrowserPref(const base::Value* extension_pref, 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* error, 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* bad_message) OVERRIDE { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension_pref->DeepCopy(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::Value* BrowserToExtensionPref( 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Value* browser_pref) OVERRIDE { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser_pref->DeepCopy(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InvertBooleanTransformer : public PrefTransformerInterface { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::Value* ExtensionToBrowserPref(const base::Value* extension_pref, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* error, 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* bad_message) OVERRIDE { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InvertBooleanValue(extension_pref); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual base::Value* BrowserToExtensionPref( 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Value* browser_pref) OVERRIDE { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InvertBooleanValue(browser_pref); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static base::Value* InvertBooleanValue(const base::Value* value) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bool_value = false; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = value->GetAsBoolean(&bool_value); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result); 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return new base::FundamentalValue(!bool_value); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdochclass NetworkPredictionTransformer : public PrefTransformerInterface { 16029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch public: 16129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch virtual base::Value* ExtensionToBrowserPref(const base::Value* extension_pref, 16229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch std::string* error, 16329b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch bool* bad_message) override { 16429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch bool bool_value = false; 16529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch const bool pref_found = extension_pref->GetAsBoolean(&bool_value); 16629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch DCHECK(pref_found) << "Preference not found."; 16729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch if (bool_value) { 16829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch return new base::FundamentalValue( 16929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch chrome_browser_net::NETWORK_PREDICTION_DEFAULT); 17029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch } else { 17129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch return new base::FundamentalValue( 17229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch chrome_browser_net::NETWORK_PREDICTION_NEVER); 17329b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch } 17429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch } 17529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch 17629b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch virtual base::Value* BrowserToExtensionPref( 17729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch const base::Value* browser_pref) override { 17829b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch int int_value = chrome_browser_net::NETWORK_PREDICTION_DEFAULT; 17929b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch const bool pref_found = browser_pref->GetAsInteger(&int_value); 18029b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch DCHECK(pref_found) << "Preference not found."; 18129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch return new base::FundamentalValue( 18229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch int_value != chrome_browser_net::NETWORK_PREDICTION_NEVER); 18329b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch } 18429b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch}; 18529b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrefMapping { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static PrefMapping* GetInstance() { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<PrefMapping>::get(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool FindBrowserPrefForExtensionPref(const std::string& extension_pref, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* browser_pref, 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID* read_permission, 195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID* write_permission) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMap::iterator it = mapping_.find(extension_pref); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != mapping_.end()) { 198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *browser_pref = it->second.pref_name; 199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *read_permission = it->second.read_permission; 200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *write_permission = it->second.write_permission; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool FindEventForBrowserPref(const std::string& browser_pref, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* event_name, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) APIPermission::ID* permission) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMap::iterator it = event_mapping_.find(browser_pref); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != event_mapping_.end()) { 211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *event_name = it->second.pref_name; 212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *permission = it->second.read_permission; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefTransformerInterface* FindTransformerForBrowserPref( 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& browser_pref) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, PrefTransformerInterface*>::iterator it = 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transformers_.find(browser_pref); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != transformers_.end()) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return it->second; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return identity_transformer_.get(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct DefaultSingletonTraits<PrefMapping>; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMapping() { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) identity_transformer_.reset(new IdentityPrefTransformer()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kPrefMapping); ++i) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mapping_[kPrefMapping[i].extension_pref] = 235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PrefMapData(kPrefMapping[i].browser_pref, 236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kPrefMapping[i].read_permission, 237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kPrefMapping[i].write_permission); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name = 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringPrintf(kOnPrefChangeFormat, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPrefMapping[i].extension_pref); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_mapping_[kPrefMapping[i].browser_pref] = 242effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PrefMapData(event_name, 243effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kPrefMapping[i].read_permission, 244effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kPrefMapping[i].write_permission); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(arraysize(kPrefMapping), mapping_.size()); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(arraysize(kPrefMapping), event_mapping_.size()); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RegisterPrefTransformer(prefs::kProxy, new ProxyPrefTransformer()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegisterPrefTransformer(prefs::kBlockThirdPartyCookies, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new InvertBooleanTransformer()); 25129b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch RegisterPrefTransformer(prefs::kNetworkPredictionOptions, 25229b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch new NetworkPredictionTransformer()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PrefMapping() { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPairSecondPointers(transformers_.begin(), 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transformers_.end()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RegisterPrefTransformer(const std::string& browser_pref, 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefTransformerInterface* transformer) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0u, transformers_.count(browser_pref)) << 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Trying to register pref transformer for " << browser_pref << " twice"; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transformers_[browser_pref] = transformer; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 267effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch struct PrefMapData { 268effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PrefMapData() 269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : read_permission(APIPermission::kInvalid), 270effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch write_permission(APIPermission::kInvalid) {} 271effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PrefMapData(const std::string& pref_name, 273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID read, 274effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID write) 275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : pref_name(pref_name), 276effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch read_permission(read), 277effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch write_permission(write) {} 278effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Browser or extension preference to which the data maps. 280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string pref_name; 281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Permission needed to read the preference. 283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID read_permission; 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Permission needed to write the preference. 286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID write_permission; 287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch }; 288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch typedef std::map<std::string, PrefMapData> PrefMap; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mapping from extension pref keys to browser pref keys and permissions. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMap mapping_; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mapping from browser pref keys to extension event names and permissions. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMap event_mapping_; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mapping from browser pref keys to transformers. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, PrefTransformerInterface*> transformers_; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PrefTransformerInterface> identity_transformer_; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PrefMapping); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PreferenceEventRouter::PreferenceEventRouter(Profile* profile) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Init(profile_->GetPrefs()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incognito_registrar_.Init(profile_->GetOffTheRecordPrefs()); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(kPrefMapping); ++i) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(kPrefMapping[i].browser_pref, 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PreferenceEventRouter::OnPrefChanged, 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.prefs())); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) incognito_registrar_.Add(kPrefMapping[i].browser_pref, 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PreferenceEventRouter::OnPrefChanged, 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this), 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) incognito_registrar_.prefs())); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PreferenceEventRouter::~PreferenceEventRouter() { } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PreferenceEventRouter::OnPrefChanged(PrefService* pref_service, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& browser_pref) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool incognito = (pref_service != profile_->GetPrefs()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string event_name; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) APIPermission::ID permission = APIPermission::kInvalid; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool rv = PrefMapping::GetInstance()->FindEventForBrowserPref( 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_pref, &event_name, &permission); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(rv); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::ListValue args; 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* dict = new base::DictionaryValue(); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args.Append(dict); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PrefService::Preference* pref = 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_service->FindPreference(browser_pref.c_str()); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(pref); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefTransformerInterface* transformer = 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Value* transformed_value = 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transformer->BrowserToExtensionPref(pref->GetValue()); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transformed_value) { 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << ErrorUtils::FormatErrorMessage(kConversionErrorMessage, 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pref->name()); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set(keys::kValue, transformed_value); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (incognito) { 3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExtensionPrefs* ep = ExtensionPrefs::Get(profile_); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->SetBoolean(keys::kIncognitoSpecific, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ep->HasIncognitoPrefValue(browser_pref)); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helpers::DispatchEventToExtensions(profile_, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_name, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &args, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) permission, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incognito, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_pref); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PreferenceAPIBase::SetExtensionControlledPref( 3677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& extension_id, 3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& pref_key, 3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExtensionPrefsScope scope, 3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Value* value) { 3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#ifndef NDEBUG 3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PrefService::Preference* pref = 3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_prefs()->pref_service()->FindPreference(pref_key.c_str()); 3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(pref) << "Extension controlled preference key " << pref_key 3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << " not registered."; 3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_EQ(pref->GetType(), value->GetType()) 3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << "Extension controlled preference " << pref_key << " has wrong type."; 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string scope_string; 3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // ScopeToPrefName() returns false if the scope is not persisted. 3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (pref_names::ScopeToPrefName(scope, &scope_string)) { 3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Also store in persisted Preferences file to recover after a 3847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // browser restart. 3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs(), 3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, 3877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scope_string); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* preference = update.Get(); 3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!preference) 3907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) preference = update.Create(); 3917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) preference->SetWithoutPathExpansion(pref_key, value->DeepCopy()); 3927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_pref_value_map()->SetExtensionPref( 3947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, pref_key, scope, value); 3957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PreferenceAPIBase::RemoveExtensionControlledPref( 3987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& extension_id, 3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& pref_key, 4007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExtensionPrefsScope scope) { 4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(extension_prefs()->pref_service()->FindPreference(pref_key.c_str())) 4027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << "Extension controlled preference key " << pref_key 4037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << " not registered."; 4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string scope_string; 4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (pref_names::ScopeToPrefName(scope, &scope_string)) { 4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExtensionPrefs::ScopedDictionaryUpdate update(extension_prefs(), 4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, 4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scope_string); 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* preference = update.Get(); 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (preference) 4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) preference->RemoveWithoutPathExpansion(pref_key, NULL); 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_pref_value_map()->RemoveExtensionPref( 4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, pref_key, scope); 4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool PreferenceAPIBase::CanExtensionControlPref( 4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& extension_id, 4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& pref_key, 4217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool incognito) { 4227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(extension_prefs()->pref_service()->FindPreference(pref_key.c_str())) 4237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << "Extension controlled preference key " << pref_key 4247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << " not registered."; 4257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return extension_pref_value_map()->CanExtensionControlPref( 4277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, pref_key, incognito); 4287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool PreferenceAPIBase::DoesExtensionControlPref( 4317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& extension_id, 4327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& pref_key, 4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool* from_incognito) { 4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(extension_prefs()->pref_service()->FindPreference(pref_key.c_str())) 4357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << "Extension controlled preference key " << pref_key 4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << " not registered."; 4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return extension_pref_value_map()->DoesExtensionControlPref( 4397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, pref_key, from_incognito); 4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PreferenceAPI::PreferenceAPI(content::BrowserContext* context) 443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : profile_(Profile::FromBrowserContext(context)) { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(kPrefMapping); ++i) { 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string event_name; 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APIPermission::ID permission = APIPermission::kInvalid; 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool rv = PrefMapping::GetInstance()->FindEventForBrowserPref( 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kPrefMapping[i].browser_pref, &event_name, &permission); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(rv); 4500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter::Get(profile_)->RegisterObserver(this, event_name); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 452e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content_settings_store()->AddObserver(this); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PreferenceAPI::~PreferenceAPI() { 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PreferenceAPI::Shutdown() { 4590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter::Get(profile_)->UnregisterObserver(this); 4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!extension_prefs()->extensions_disabled()) 4617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ClearIncognitoSessionOnlyContentSettings(); 462e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content_settings_store()->RemoveObserver(this); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance<BrowserContextKeyedAPIFactory<PreferenceAPI> > 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<PreferenceAPI>* 470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PreferenceAPI::GetFactoryInstance() { 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_factory.Pointer(); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static 475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PreferenceAPI* PreferenceAPI::Get(content::BrowserContext* context) { 476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BrowserContextKeyedAPIFactory<PreferenceAPI>::Get(context); 4777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PreferenceAPI::OnListenerAdded(const EventListenerInfo& details) { 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preference_event_router_.reset(new PreferenceEventRouter(profile_)); 4810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter::Get(profile_)->UnregisterObserver(this); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PreferenceAPI::OnContentSettingChanged(const std::string& extension_id, 4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool incognito) { 4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (incognito) { 4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_prefs()->UpdateExtensionPref( 4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, 4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) pref_names::kPrefIncognitoContentSettings, 490e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content_settings_store()->GetSettingsForExtension( 4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, kExtensionPrefsScopeIncognitoPersistent)); 4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } else { 4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_prefs()->UpdateExtensionPref( 4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, 4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) pref_names::kPrefContentSettings, 496e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content_settings_store()->GetSettingsForExtension( 4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id, kExtensionPrefsScopeRegular)); 4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PreferenceAPI::ClearIncognitoSessionOnlyContentSettings() { 5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ExtensionIdList extension_ids; 5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_prefs()->GetExtensions(&extension_ids); 5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (ExtensionIdList::iterator extension_id = extension_ids.begin(); 5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension_id != extension_ids.end(); ++extension_id) { 506e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content_settings_store()->ClearContentSettingsForExtension( 507e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch *extension_id, kExtensionPrefsScopeIncognitoSessionOnly); 5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ExtensionPrefs* PreferenceAPI::extension_prefs() { 5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return ExtensionPrefs::Get(profile_); 5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)ExtensionPrefValueMap* PreferenceAPI::extension_pref_value_map() { 5161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return ExtensionPrefValueMapFactory::GetForBrowserContext(profile_); 5177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 519e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochscoped_refptr<ContentSettingsStore> PreferenceAPI::content_settings_store() { 520e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return ContentSettingsService::Get(profile_)->content_settings_store(); 521e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 522e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)template <> 524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void 525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<PreferenceAPI>::DeclareFactoryDependencies() { 526e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DependsOn(ContentSettingsService::GetFactoryInstance()); 5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DependsOn(ExtensionPrefsFactory::GetInstance()); 5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DependsOn(ExtensionPrefValueMapFactory::GetInstance()); 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); 5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PreferenceFunction::~PreferenceFunction() { } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PreferenceFunction::ValidateBrowserPref( 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_pref_key, 536effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PreferenceFunction::PermissionType permission_type, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* browser_pref_key) { 538effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID read_permission = APIPermission::kInvalid; 539effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID write_permission = APIPermission::kInvalid; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMapping::GetInstance()->FindBrowserPrefForExtensionPref( 542effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch extension_pref_key, 543effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch browser_pref_key, 544effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &read_permission, 545effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &write_permission)); 546effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch APIPermission::ID permission = permission_type == PERMISSION_TYPE_READ 547effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ? read_permission 548effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : write_permission; 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!extension()->permissions_data()->HasAPIPermission(permission)) { 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_ = ErrorUtils::FormatErrorMessage( 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys::kPermissionErrorMessage, extension_pref_key); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPreferenceFunction::~GetPreferenceFunction() { } 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool GetPreferenceFunction::RunSync() { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pref_key; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* details = NULL; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool incognito = false; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (details->HasKey(keys::kIncognitoKey)) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(details->GetBoolean(keys::kIncognitoKey, 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &incognito)); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check incognito access. 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (incognito && !include_incognito()) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kIncognitoErrorMessage; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtain pref. 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string browser_pref; 578effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!ValidateBrowserPref( 579effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch pref_key, PreferenceFunction::PERMISSION_TYPE_READ, &browser_pref)) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 581effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 5821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) PrefService* prefs = incognito ? GetProfile()->GetOffTheRecordPrefs() 5831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) : GetProfile()->GetPrefs(); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefService::Preference* pref = 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs->FindPreference(browser_pref.c_str()); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(pref); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieve level of control. 5911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string level_of_control = helpers::GetLevelOfControl( 5921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetProfile(), extension_id(), browser_pref, incognito); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetString(keys::kLevelOfControl, level_of_control); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieve pref value. 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefTransformerInterface* transformer = 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Value* transformed_value = 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transformer->BrowserToExtensionPref(pref->GetValue()); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transformed_value) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ErrorUtils::FormatErrorMessage(kConversionErrorMessage, 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->name()); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->Set(keys::kValue, transformed_value); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieve incognito status. 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (incognito) { 6101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ExtensionPrefs* ep = ExtensionPrefs::Get(GetProfile()); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kIncognitoSpecific, 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ep->HasIncognitoPrefValue(browser_pref)); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetResult(result.release()); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SetPreferenceFunction::~SetPreferenceFunction() { } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool SetPreferenceFunction::RunSync() { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pref_key; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* details = NULL; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Value* value = NULL; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kValue, &value)); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (details->HasKey(keys::kScopeKey)) { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scope_str; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->GetString(keys::kScopeKey, &scope_str)); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check incognito scope. 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool incognito = 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (scope == kExtensionPrefsScopeIncognitoPersistent || 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scope == kExtensionPrefsScopeIncognitoSessionOnly); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (incognito) { 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Regular profiles can't access incognito unless include_incognito is true. 6451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!GetProfile()->IsOffTheRecord() && !include_incognito()) { 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kIncognitoErrorMessage; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Incognito profiles can't access regular mode ever, they only exist in 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // split mode. 6521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (GetProfile()->IsOffTheRecord()) { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = "Can't modify regular settings from an incognito context."; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (scope == kExtensionPrefsScopeIncognitoSessionOnly && 6591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) !GetProfile()->HasOffTheRecordProfile()) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = keys::kIncognitoSessionOnlyErrorMessage; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Obtain pref. 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string browser_pref; 666effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!ValidateBrowserPref( 667effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch pref_key, PreferenceFunction::PERMISSION_TYPE_WRITE, &browser_pref)) { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 669effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 6701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ExtensionPrefs* prefs = ExtensionPrefs::Get(GetProfile()); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefService::Preference* pref = 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs->pref_service()->FindPreference(browser_pref.c_str()); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(pref); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validate new value. 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefTransformerInterface* transformer = 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefMapping::GetInstance()->FindTransformerForBrowserPref(browser_pref); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bad_message = false; 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> browser_pref_value( 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transformer->ExtensionToBrowserPref(value, &error, &bad_message)); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser_pref_value) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = error; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bad_message_ = bad_message; 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 68729b820f8d84e3bc97d62552e54923c42407f2f29Ben Murdoch EXTENSION_FUNCTION_VALIDATE(browser_pref_value->GetType() == pref->GetType()); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validate also that the stored value can be converted back by the 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // transformer. 6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> extensionPrefValue( 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transformer->BrowserToExtensionPref(browser_pref_value.get())); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extensionPrefValue) { 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_ = ErrorUtils::FormatErrorMessage(kConversionErrorMessage, 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref->name()); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bad_message_ = true; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) PreferenceAPI::Get(GetProfile())->SetExtensionControlledPref( 7011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_id(), browser_pref, scope, browser_pref_value.release()); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClearPreferenceFunction::~ClearPreferenceFunction() { } 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ClearPreferenceFunction::RunSync() { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string pref_key; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &pref_key)); 7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* details = NULL; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionPrefsScope scope = kExtensionPrefsScopeRegular; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (details->HasKey(keys::kScopeKey)) { 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string scope_str; 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE( 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details->GetString(keys::kScopeKey, &scope_str)); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(helpers::StringToScope(scope_str, &scope)); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check incognito scope. 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool incognito = 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (scope == kExtensionPrefsScopeIncognitoPersistent || 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scope == kExtensionPrefsScopeIncognitoSessionOnly); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (incognito) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't check incognito permissions here, as an extension should be 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // always allowed to clear its own settings. 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Incognito profiles can't access regular mode ever, they only exist in 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // split mode. 7321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (GetProfile()->IsOffTheRecord()) { 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = "Can't modify regular settings from an incognito context."; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string browser_pref; 739effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!ValidateBrowserPref( 740effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch pref_key, PreferenceFunction::PERMISSION_TYPE_WRITE, &browser_pref)) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 742effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) PreferenceAPI::Get(GetProfile()) 7451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->RemoveExtensionControlledPref(extension_id(), browser_pref, scope); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 750