text:
namespace {

#if BUILDFLAG(IS_CHROMEOS_ASH)
bool IsPrivilegedCrosSetting(const std::string& pref_name) {
  if (!ash::CrosSettings::IsCrosSettings(pref_name))
    return false;
  if (!ash::system::PerUserTimezoneEnabled()) {
    // kSystemTimezone should be changeable by all users.
    if (pref_name == ash::kSystemTimezone)
      return false;
  }
  // Cros settings are considered privileged and are either policy
  // controlled or owner controlled.
  return true;
}

bool IsRestrictedCrosSettingForChildUser(Profile* profile,
                                         const std::string& pref_name) {
  if (!profile->IsChild())
    return false;

  return ash::CrosSettings::Get()
      ->supervised_user_cros_settings_provider()
      ->HandlesSetting(pref_name);
}

const base::Value* GetRestrictedCrosSettingValueForChildUser(
    Profile* profile,
    const std::string& pref_name) {
  // Make sure that profile belongs to a child and the preference is
  // pre-set.
  DCHECK(IsRestrictedCrosSettingForChildUser(profile, pref_name));

  return ash::CrosSettings::Get()
      ->supervised_user_cros_settings_provider()
      ->Get(pref_name);
}

#endif

bool IsSettingReadOnly(const std::string& pref_name) {
  // download.default_directory is used to display the directory location and
  // for policy indicators, but should not be changed directly.
  if (pref_name == prefs::kDownloadDefaultDirectory)
    return true;
#if BUILDFLAG(IS_CHROMEOS_ASH)
  // System timezone is never directly changeable by the user.
  if (pref_name == ash::kSystemTimezone)
    return ash::system::PerUserTimezoneEnabled();
  // enable_screen_lock and pin_unlock_autosubmit_enabled
  // must be changed through the quickUnlockPrivate API.
  if (pref_name == ash::prefs::kEnableAutoScreenLock ||
      pref_name == ::prefs::kPinUnlockAutosubmitEnabled) {
    return true;
  }
#endif
#if defined(OS_WIN)
  // Don't allow user to change sw_reporter preferences.
  if (pref_name == prefs::kSwReporterEnabled)
    return true;
#endif
  return false;
}

}  // namespace

namespace extensions {

namespace settings_api = api::settings_private;

PrefsUtil::PrefsUtil(Profile* profile) : profile_(profile) {}

PrefsUtil::~PrefsUtil() {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
using CrosSettings = chromeos::CrosSettings;
#endif

const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() {
  static PrefsUtil::TypedPrefMap* s_allowlist = nullptr;
  if (s_allowlist)
    return *s_allowlist;
  s_allowlist = new PrefsUtil::TypedPrefMap();

  // Miscellaneous
  (*s_allowlist)[::embedder_support::kAlternateErrorPagesEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[autofill::prefs::kAutofillProfileEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[autofill::prefs::kAutofillCreditCardEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[autofill::prefs::kAutofillCreditCardFidoAuthEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[payments::kCanMakePaymentEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[bookmarks::prefs::kShowBookmarkBar] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
// of lacros-chrome is complete.
#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
  (*s_allowlist)[::prefs::kUseCustomChromeFrame] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif
  (*s_allowlist)[::prefs::kShowHomeButton] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Appearance settings.
  (*s_allowlist)[::prefs::kCurrentThemeID] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kPolicyThemeColor] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
// of lacros-chrome is complete.
#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
  (*s_allowlist)[::prefs::kUsesSystemTheme] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif
  (*s_allowlist)[::prefs::kHomePage] = settings_api::PrefType::PREF_TYPE_URL;
  (*s_allowlist)[::prefs::kHomePageIsNewTabPage] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kWebKitDefaultFixedFontSize] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kWebKitDefaultFontSize] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kWebKitMinimumFontSize] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kWebKitFixedFontFamily] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kWebKitSansSerifFontFamily] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kWebKitSerifFontFamily] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kWebKitStandardFontFamily] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kDefaultCharset] =
      settings_api::PrefType::PREF_TYPE_STRING;
#if defined(OS_MAC)
  (*s_allowlist)[::prefs::kWebkitTabsToLinks] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kConfirmToQuitEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif
  (*s_allowlist)[dom_distiller::prefs::kOfferReaderMode] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // On startup.
  (*s_allowlist)[::prefs::kRestoreOnStartup] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kURLsToRestoreOnStartup] =
      settings_api::PrefType::PREF_TYPE_LIST;

  // Downloads settings.
  (*s_allowlist)[::prefs::kDownloadDefaultDirectory] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kPromptForDownload] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[drive::prefs::kDisableDrive] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#if BUILDFLAG(IS_CHROMEOS_ASH)
  (*s_allowlist)[::prefs::kNetworkFileSharesAllowed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kMostRecentlyUsedNetworkFileShareURL] =
      settings_api::PrefType::PREF_TYPE_STRING;
#endif

  // Miscellaneous. TODO(stevenjb): categorize.
  (*s_allowlist)[::prefs::kEnableDoNotTrack] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kEnableEncryptedMedia] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::language::prefs::kApplicationLocale] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kNetworkPredictionOptions] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[password_manager::prefs::kCredentialsEnableService] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[password_manager::prefs::kCredentialsEnableAutosignin] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[password_manager::prefs::kPasswordLeakDetectionEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Privacy page
  (*s_allowlist)[::prefs::kSigninAllowedOnNextStartup] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kDnsOverHttpsMode] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kDnsOverHttpsTemplates] =
      settings_api::PrefType::PREF_TYPE_STRING;

  // Privacy Review
  (*s_allowlist)[::prefs::kPrivacyReviewShowWelcomeCard] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kPrivacyGuideViewed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Privacy Sandbox page
  (*s_allowlist)[::prefs::kPrivacySandboxApisEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kPrivacySandboxManuallyControlled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kPrivacySandboxPageViewed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::kGeneratedFlocPref] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Security page
  (*s_allowlist)[::kGeneratedPasswordLeakDetectionPref] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kSafeBrowsingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kSafeBrowsingEnhanced] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kSafeBrowsingScoutReportingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::safe_browsing::kGeneratedSafeBrowsingPref] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kHttpsOnlyModeEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Sync and personalization page.
  (*s_allowlist)[::prefs::kSearchSuggestEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)
      [::unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled] =
          settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::omnibox::kDocumentSuggestEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Languages page
  (*s_allowlist)[spellcheck::prefs::kSpellCheckEnable] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[spellcheck::prefs::kSpellCheckDictionaries] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[spellcheck::prefs::kSpellCheckForcedDictionaries] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[spellcheck::prefs::kSpellCheckBlocklistedDictionaries] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[spellcheck::prefs::kSpellCheckUseSpellingService] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[translate::prefs::kOfferTranslateEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[translate::prefs::kBlockedLanguages] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[language::prefs::kSelectedLanguages] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[language::prefs::kForcedLanguages] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[::language::prefs::kAcceptLanguages] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[translate::prefs::kPrefTranslateRecentTarget] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[translate::prefs::kPrefAlwaysTranslateList] =
      settings_api::PrefType::PREF_TYPE_LIST;
#if BUILDFLAG(IS_CHROMEOS_ASH)
  (*s_allowlist)[::prefs::kLanguageImeMenuActivated] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::prefs::kAssistPersonalInfoEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::prefs::kAssistPredictiveWritingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::prefs::kEmojiSuggestionEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kLacrosProxyControllingExtension] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[::prefs::kLanguageInputMethodSpecificSettings] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[ash::prefs::kLastUsedImeShortcutReminderDismissed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kNextImeShortcutReminderDismissed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
  // Nearby Share.
  (*s_allowlist)[::prefs::kNearbySharingEnabledPrefName] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)
      [::prefs::kNearbySharingFastInitiationNotificationStatePrefName] =
          settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kNearbySharingOnboardingCompletePrefName] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kNearbySharingActiveProfilePrefName] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kNearbySharingDeviceNamePrefName] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kNearbySharingDataUsageName] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
#endif

  // Search page.
  (*s_allowlist)[DefaultSearchManager::kDefaultSearchProviderDataPrefName] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[::omnibox::kKeywordSpaceTriggeringEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Site Settings prefs.
  (*s_allowlist)[::content_settings::kCookiePrimarySetting] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::content_settings::kCookieSessionOnly] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kCookieControlsMode] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::content_settings::kGeneratedNotificationPref] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kPluginsAlwaysOpenPdfExternally] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kProtectedContentDefault] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kEnableQuietNotificationPermissionUi] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Clear browsing data settings.
  (*s_allowlist)[browsing_data::prefs::kDeleteBrowsingHistory] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteBrowsingHistoryBasic] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteDownloadHistory] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteCache] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteCacheBasic] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteCookies] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteCookiesBasic] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeletePasswords] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteFormData] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteSiteSettings] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteHostedAppsData] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[browsing_data::prefs::kDeleteTimePeriod] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[browsing_data::prefs::kDeleteTimePeriodBasic] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[browsing_data::prefs::kLastClearBrowsingDataTab] =
      settings_api::PrefType::PREF_TYPE_NUMBER;

  // Accessibility.
  (*s_allowlist)[::prefs::kAccessibilityImageLabelsEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kAccessibilityCaptionsTextSize] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kAccessibilityCaptionsTextFont] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kAccessibilityCaptionsTextColor] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kAccessibilityCaptionsTextOpacity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kAccessibilityCaptionsBackgroundColor] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kAccessibilityCaptionsTextShadow] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kAccessibilityCaptionsBackgroundOpacity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
#if !defined(OS_ANDROID)
  (*s_allowlist)[::prefs::kLiveCaptionEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kLiveCaptionLanguageCode] =
      settings_api::PrefType::PREF_TYPE_STRING;
#endif
#if !BUILDFLAG(IS_CHROMEOS_ASH)
  (*s_allowlist)[::prefs::kAccessibilityFocusHighlightEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif
  (*s_allowlist)[::prefs::kCaretBrowsingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

#if BUILDFLAG(IS_CHROMEOS_ASH)
  // Accounts / Users / People.
  (*s_allowlist)[ash::kAccountsPrefAllowGuest] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kAccountsPrefShowUserNamesOnSignIn] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kAccountsPrefAllowNewUser] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kAccountsPrefUsers] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)
      [::account_manager::prefs::kSecondaryGoogleAccountSigninAllowed] =
          settings_api::PrefType::PREF_TYPE_BOOLEAN;
  // kEnableAutoScreenLock is read-only.
  (*s_allowlist)[ash::prefs::kEnableAutoScreenLock] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  // kPinUnlockAutosubmitEnabled is read-only.
  (*s_allowlist)[::prefs::kPinUnlockAutosubmitEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kMessageCenterLockScreenMode] =
      settings_api::PrefType::PREF_TYPE_STRING;

  // Accessibility.
  (*s_allowlist)[ash::prefs::kAccessibilitySpokenFeedbackEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityAutoclickEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityAutoclickDelayMs] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilityAutoclickEventType] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilityAutoclickRevertToLeftClick] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityAutoclickStabilizePosition] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityAutoclickMovementThreshold] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilityCaretHighlightEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityCursorHighlightEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kShouldAlwaysShowAccessibilityMenu] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityDictationEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityDictationLocale] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[ash::prefs::kAccessibilityFocusHighlightEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityHighContrastEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityLargeCursorEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityLargeCursorDipSize] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilityCursorColorEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityCursorColor] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilityScreenMagnifierEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)
      [ash::prefs::kAccessibilityScreenMagnifierFocusFollowingEnabled] =
          settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityScreenMagnifierMouseFollowingMode] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilityScreenMagnifierScale] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilitySelectToSpeakEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityStickyKeysEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilitySwitchAccessEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilitySwitchAccessSelectDeviceKeyCodes] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[ash::prefs::kAccessibilitySwitchAccessNextDeviceKeyCodes] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[ash::prefs::kAccessibilitySwitchAccessPreviousDeviceKeyCodes] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[ash::prefs::kAccessibilitySwitchAccessAutoScanEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilitySwitchAccessAutoScanSpeedMs] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)
      [ash::prefs::kAccessibilityTabletModeShelfNavigationButtonsEnabled] =
          settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)
      [ash::prefs::kAccessibilitySwitchAccessAutoScanKeyboardSpeedMs] =
          settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)
      [ash::prefs::kAccessibilitySwitchAccessPointScanSpeedDipsPerSecond] =
          settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kAccessibilityVirtualKeyboardEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kAccessibilityMonoAudioEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)
      [ash::prefs::kAccessibilityEnhancedNetworkVoicesInSelectToSpeakAllowed] =
          settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Text to Speech.
  (*s_allowlist)[::prefs::kTextToSpeechLangToVoiceName] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[::prefs::kTextToSpeechRate] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kTextToSpeechPitch] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kTextToSpeechVolume] =
      settings_api::PrefType::PREF_TYPE_NUMBER;

  // Guest OS
  (*s_allowlist)[crostini::prefs::kCrostiniEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[crostini::prefs::kCrostiniMicAllowed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[crostini::prefs::kCrostiniSharedUsbDevices] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[crostini::prefs::kCrostiniContainers] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[crostini::prefs::kCrostiniPortForwarding] =
      settings_api::PrefType::PREF_TYPE_LIST;
  (*s_allowlist)[guest_os::prefs::kGuestOSPathsSharedToVms] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;

  // Plugin Vm
  (*s_allowlist)[plugin_vm::prefs::kPluginVmImageExists] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[plugin_vm::prefs::kPluginVmPrintersAllowed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Android Apps.
  (*s_allowlist)[arc::prefs::kArcEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Ambient Mode.
  (*s_allowlist)[ash::ambient::prefs::kAmbientModeEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  // The following prefs are not displayed to the user but are configurable to
  // speed up automated testing of Ambient mode.
  (*s_allowlist)
      [ash::ambient::prefs::kAmbientModeLockScreenInactivityTimeoutSeconds] =
          settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)
      [ash::ambient::prefs::kAmbientModeLockScreenBackgroundTimeoutSeconds] =
          settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::ambient::prefs::kAmbientModePhotoRefreshIntervalSeconds] =
      settings_api::PrefType::PREF_TYPE_NUMBER;

  // Dark Mode.
  (*s_allowlist)[ash::prefs::kDarkModeEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kColorModeThemed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Google Assistant.
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantConsentStatus] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantDisabledByPolicy] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantContextEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantHotwordAlwaysOn] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantHotwordEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)
      [chromeos::assistant::prefs::kAssistantVoiceMatchEnabledDuringOobe] =
          settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantLaunchWithMicOpen] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[chromeos::assistant::prefs::kAssistantNotificationEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Quick Answers.
  (*s_allowlist)[ash::quick_answers::prefs::kQuickAnswersEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::quick_answers::prefs::kQuickAnswersDefinitionEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::quick_answers::prefs::kQuickAnswersTranslationEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)
      [ash::quick_answers::prefs::kQuickAnswersUnitConverstionEnabled] =
          settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Misc.
  (*s_allowlist)[::prefs::kUse24HourClock] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::language::prefs::kPreferredLanguages] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[ash::prefs::kTapDraggingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kStatsReportingPref] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::chromeos::prefs::kSuggestedContentEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kAttestationForContentProtectionEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[prefs::kRestoreLastLockScreenNote] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kDevicePeripheralDataAccessEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kLocalStateDevicePeripheralDataAccessEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kRevenEnableDeviceHWDataUsage] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Bluetooth & Internet settings.
  (*s_allowlist)[ash::kAllowBluetooth] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[proxy_config::prefs::kUseSharedProxies] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::kSignedDataRoamingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kUserBluetoothAdapterEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kSystemBluetoothAdapterEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kFastPairEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kVpnConfigAllowed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[arc::prefs::kAlwaysOnVpnPackage] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[arc::prefs::kAlwaysOnVpnLockdown] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Restore apps and pages on startup
  (*s_allowlist)[ash::full_restore::kRestoreAppsAndPagesPrefName] =
      settings_api::PrefType::PREF_TYPE_NUMBER;

  // Timezone settings.
  (*s_allowlist)[ash::kSystemTimezone] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[prefs::kUserTimezone] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[settings_private::kResolveTimezoneByGeolocationOnOff] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::kPerUserTimezoneEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[settings_private::kResolveTimezoneByGeolocationMethodShort] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::kFineGrainedTimeZoneResolveEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[prefs::kSystemTimezoneAutomaticDetectionPolicy] =
      settings_api::PrefType::PREF_TYPE_NUMBER;

  // Ash settings.
  (*s_allowlist)[ash::prefs::kAmbientColorEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kEnableStylusTools] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kLaunchPaletteOnEjectEvent] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kNightLightEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kNightLightTemperature] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kNightLightScheduleType] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kNightLightCustomStartTime] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kNightLightCustomEndTime] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::prefs::kDockedMagnifierEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kDockedMagnifierScale] =
      settings_api::PrefType::PREF_TYPE_NUMBER;

  // Input method settings.
  (*s_allowlist)[::prefs::kLanguagePreloadEngines] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kLanguageEnabledImes] =
      settings_api::PrefType::PREF_TYPE_STRING;
  (*s_allowlist)[::prefs::kLanguageAllowedInputMethods] =
      settings_api::PrefType::PREF_TYPE_LIST;

  // Device settings.
  (*s_allowlist)[::prefs::kTapToClickEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kNaturalScroll] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kTouchpadSensitivity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kTouchpadScrollSensitivity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kTouchpadHapticFeedback] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kTouchpadHapticClickSensitivity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kPrimaryMouseButtonRight] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kPrimaryPointingStickButtonRight] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[ash::prefs::kMouseReverseScroll] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kMouseAcceleration] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kMouseScrollAcceleration] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kPointingStickAcceleration] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kTouchpadAcceleration] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kTouchpadScrollAcceleration] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kMouseSensitivity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kMouseScrollSensitivity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kPointingStickSensitivity] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapSearchKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapControlKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapAltKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapCapsLockKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapBackspaceKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapAssistantKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapEscapeKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapExternalCommandKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageRemapExternalMetaKeyTo] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::prefs::kLanguageSendFunctionKeys] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kXkbAutoRepeatEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kXkbAutoRepeatDelay] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[::ash::prefs::kXkbAutoRepeatInterval] =
      settings_api::PrefType::PREF_TYPE_NUMBER;
  (*s_allowlist)[ash::kDeviceDisplayResolution] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[ash::kDisplayRotationDefault] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;
  (*s_allowlist)[arc::prefs::kArcVisibleExternalStorages] =
      settings_api::PrefType::PREF_TYPE_LIST;

  // Native Printing settings.
  (*s_allowlist)[::prefs::kUserPrintersAllowed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Privacy settings.
  (*s_allowlist)[::ash::prefs::kSnoopingProtectionEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::ash::prefs::kPowerQuickDimEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

#else
  // System settings.
  (*s_allowlist)[::prefs::kBackgroundModeEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kHardwareAccelerationModeEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

  // Import data
  (*s_allowlist)[::prefs::kImportDialogAutofillFormData] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kImportDialogBookmarks] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kImportDialogHistory] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kImportDialogSavedPasswords] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kImportDialogSearchEngine] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
  (*s_allowlist)[::prefs::kSettingsShowOSBanner] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif

  // Proxy settings.
  (*s_allowlist)[proxy_config::prefs::kProxy] =
      settings_api::PrefType::PREF_TYPE_DICTIONARY;

#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
  (*s_allowlist)[media_router::prefs::kMediaRouterEnableCloudServices] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kUserFeedbackAllowed] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)

  // Media Remoting settings.
  (*s_allowlist)[media_router::prefs::kMediaRouterMediaRemotingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;

#if defined(OS_WIN)
  // SwReporter settings.
  (*s_allowlist)[::prefs::kSwReporterEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
  (*s_allowlist)[::prefs::kSwReporterReportingEnabled] =
      settings_api::PrefType::PREF_TYPE_BOOLEAN;
#endif

  return *s_allowlist;
}

settings_api::PrefType PrefsUtil::GetAllowlistedPrefType(
    const std::string& pref_name) {
  const TypedPrefMap& keys = GetAllowlistedKeys();
  const auto& iter = keys.find(pref_name);
  return iter != keys.end() ? iter->second
                            : settings_api::PrefType::PREF_TYPE_NONE;
}

settings_api::PrefType PrefsUtil::GetType(const std::string& name,
                                          base::Value::Type type) {
  switch (type) {
    case base::Value::Type::BOOLEAN:
      return settings_api::PrefType::PREF_TYPE_BOOLEAN;
    case base::Value::Type::INTEGER:
    case base::Value::Type::DOUBLE:
      return settings_api::PrefType::PREF_TYPE_NUMBER;
    case base::Value::Type::STRING:
      return IsPrefTypeURL(name) ? settings_api::PrefType::PREF_TYPE_URL
                                 : settings_api::PrefType::PREF_TYPE_STRING;
    case base::Value::Type::LIST:
      return settings_api::PrefType::PREF_TYPE_LIST;
    case base::Value::Type::DICTIONARY:
      return settings_api::PrefType::PREF_TYPE_DICTIONARY;
    default:
      return settings_api::PrefType::PREF_TYPE_NONE;
  }
}

std::unique_ptr<settings_api::PrefObject> PrefsUtil::GetCrosSettingsPref(
    const std::string& name) {
  std::unique_ptr<settings_api::PrefObject> pref_object(
      new settings_api::PrefObject());

#if BUILDFLAG(IS_CHROMEOS_ASH)
  const base::Value* value = CrosSettings::Get()->GetPref(name);
  if (!value) {
    LOG(WARNING) << "Cros settings pref not found: " << name;
    return nullptr;
  }
  pref_object->key = name;
  pref_object->type = GetType(name, value->type());
  pref_object->value = base::Value::ToUniquePtrValue(value->Clone());
#endif

  return pref_object;
}

std::unique_ptr<settings_api::PrefObject> PrefsUtil::GetPref(
    const std::string& name) {
  if (GetAllowlistedPrefType(name) == settings_api::PrefType::PREF_TYPE_NONE) {
    return nullptr;
  }

  settings_private::GeneratedPrefs* generated_prefs =
      settings_private::GeneratedPrefsFactory::GetForBrowserContext(profile_);

  const PrefService::Preference* pref = nullptr;
  std::unique_ptr<settings_api::PrefObject> pref_object;
  if (IsCrosSetting(name)) {
    pref_object = GetCrosSettingsPref(name);
    if (!pref_object)
      return nullptr;
  } else if (generated_prefs && generated_prefs->HasPref(name)) {
    return generated_prefs->GetPref(name);
  } else {
    PrefService* pref_service = FindServiceForPref(name);
    pref = pref_service->FindPreference(name);
    if (!pref)
      return nullptr;
    pref_object = std::make_unique<settings_api::PrefObject>();
    pref_object->key = pref->name();
    pref_object->type = GetType(name, pref->GetType());
    pref_object->value =
        base::Value::ToUniquePtrValue(pref->GetValue()->Clone());
  }

#if BUILDFLAG(IS_CHROMEOS_ASH)
  // We first check for enterprise-managed, then for primary-user managed.
  // Otherwise in multiprofile mode enterprise preference for the secondary
  // user will appear primary-user-controlled, which looks strange, because
  // primary user preference will be disabled with "enterprise controlled"
  // status.
  if (IsPrefEnterpriseManaged(name)) {
    // Enterprise managed prefs are treated the same as device policy restricted
    // prefs in the UI.
    pref_object->controlled_by =
        settings_api::ControlledBy::CONTROLLED_BY_DEVICE_POLICY;
    pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
    return pref_object;
  }

  if (IsPrefPrimaryUserControlled(name)) {
    pref_object->controlled_by =
        settings_api::ControlledBy::CONTROLLED_BY_PRIMARY_USER;
    pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
    pref_object->controlled_by_name =
        std::make_unique<std::string>(user_manager::UserManager::Get()
                                          ->GetPrimaryUser()
                                          ->GetAccountId()
                                          .GetUserEmail());
    return pref_object;
  }
#endif

  if (pref && pref->IsManaged()) {
    if (profile_->IsChild()) {
      pref_object->controlled_by =
          settings_api::ControlledBy::CONTROLLED_BY_CHILD_RESTRICTION;
    } else {
      pref_object->controlled_by =
          settings_api::ControlledBy::CONTROLLED_BY_USER_POLICY;
    }
    pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
    return pref_object;
  }

  // A pref is recommended if it has a recommended value, regardless of whether
  // the current value is set by policy. The UI will test to see whether the
  // current value matches the recommended value and inform the user.
  const base::Value* recommended = pref ? pref->GetRecommendedValue() : nullptr;
  if (recommended) {
    pref_object->controlled_by =
        settings_api::ControlledBy::CONTROLLED_BY_USER_POLICY;
    pref_object->enforcement =
        settings_api::Enforcement::ENFORCEMENT_RECOMMENDED;
    pref_object->recommended_value =
        base::Value::ToUniquePtrValue(recommended->Clone());
    return pref_object;
  }

#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (IsPrefOwnerControlled(name)) {
    // Check for owner controlled after managed checks because if there is a
    // device policy there is no "owner". (In the unlikely case that both
    // situations apply, either badge is potentially relevant, so the order
    // is somewhat arbitrary).
    pref_object->controlled_by =
        settings_api::ControlledBy::CONTROLLED_BY_OWNER;
    pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
    pref_object->controlled_by_name = std::make_unique<std::string>(
        user_manager::UserManager::Get()->GetOwnerAccountId().GetUserEmail());
    return pref_object;
  }

  if (IsRestrictedCrosSettingForChildUser(profile_, name)) {
    pref_object->controlled_by =
        settings_api::ControlledBy::CONTROLLED_BY_CHILD_RESTRICTION;
    pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
    pref_object->value = std::make_unique<base::Value>(
        GetRestrictedCrosSettingValueForChildUser(profile_, name)->Clone());
    return pref_object;
  }

  if (IsHotwordDisabledForChildUser(name)) {
    pref_object->controlled_by =
        settings_api::ControlledBy::CONTROLLED_BY_CHILD_RESTRICTION;
    pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
    return pref_object;
  }
#endif

  const Extension* extension = GetExtensionControllingPref(*pref_object);

  if (extension) {
    pref_object->controlled_by =
        settings_api::ControlledBy::CONTROLLED_BY_EXTENSION;
    pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
    pref_object->extension_id = std::make_unique<std::string>(extension->id());
    pref_object->controlled_by_name =
        std::make_unique<std::string>(extension->name());
    bool can_be_disabled =
        !ExtensionSystem::Get(profile_)->management_policy()->MustRemainEnabled(
            extension, nullptr);
    pref_object->extension_can_be_disabled =
        std::make_unique<bool>(can_be_disabled);
    return pref_object;
  }

  // TODO(dbeam): surface !IsUserModifiable or IsPrefSupervisorControlled?

  return pref_object;
}

settings_private::SetPrefResult PrefsUtil::SetPref(const std::string& pref_name,
                                                   const base::Value* value) {
  if (GetAllowlistedPrefType(pref_name) ==
      settings_api::PrefType::PREF_TYPE_NONE) {
    return settings_private::SetPrefResult::PREF_NOT_FOUND;
  }

  if (IsCrosSetting(pref_name))
    return SetCrosSettingsPref(pref_name, value);

  settings_private::GeneratedPrefs* generated_prefs =
      settings_private::GeneratedPrefsFactory::GetForBrowserContext(profile_);
  if (generated_prefs && generated_prefs->HasPref(pref_name))
    return generated_prefs->SetPref(pref_name, value);

  PrefService* pref_service = FindServiceForPref(pref_name);

  if (!IsPrefUserModifiable(pref_name))
    return settings_private::SetPrefResult::PREF_NOT_MODIFIABLE;

  const PrefService::Preference* pref = pref_service->FindPreference(pref_name);
  if (!pref)
    return settings_private::SetPrefResult::PREF_NOT_FOUND;

  switch (pref->GetType()) {
    case base::Value::Type::BOOLEAN:
    case base::Value::Type::LIST:
    case base::Value::Type::DICTIONARY:
      pref_service->Set(pref_name, *value);
      break;
    case base::Value::Type::DOUBLE:
    case base::Value::Type::INTEGER:
      // Explicitly set the double value or the integer value.
      // Otherwise if the number is a whole number like 2.0, it will
      // automatically be of type INTEGER causing type mismatches in
      // PrefService::SetUserPrefValue for doubles, and vice versa.
      if (!value->is_double() && !value->is_int())
        return settings_private::SetPrefResult::PREF_TYPE_MISMATCH;
      double double_value;
      double_value = value->GetDouble();

      if (pref->GetType() == base::Value::Type::DOUBLE)
        pref_service->SetDouble(pref_name, double_value);
      else
        pref_service->SetInteger(pref_name, static_cast<int>(double_value));
      break;
    case base::Value::Type::STRING: {
      if (!value->is_string())
        return settings_private::SetPrefResult::PREF_TYPE_MISMATCH;

      std::string string_value = value->GetString();
      if (IsPrefTypeURL(pref_name)) {
        GURL fixed = url_formatter::FixupURL(string_value, std::string());
        if (fixed.is_valid())
          string_value = fixed.spec();
        else
          string_value = std::string();
      }

      pref_service->SetString(pref_name, string_value);
      break;
    }
    default:
      return settings_private::SetPrefResult::PREF_TYPE_UNSUPPORTED;
  }

  // TODO(orenb): Process setting metrics here and in the CrOS setting method
  // too (like "ProcessUserMetric" in CoreOptionsHandler).
  return settings_private::SetPrefResult::SUCCESS;
}

settings_private::SetPrefResult PrefsUtil::SetCrosSettingsPref(
    const std::string& pref_name,
    const base::Value* value) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  if (pref_name == ash::kSystemTimezone) {
    const std::string* string_value = value->GetIfString();
    if (!string_value)
      return settings_private::SetPrefResult::PREF_TYPE_MISMATCH;
    const user_manager::User* user =
        chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
    if (user && ash::system::SetSystemTimezone(user, *string_value))
      return settings_private::SetPrefResult::SUCCESS;
    return settings_private::SetPrefResult::PREF_NOT_MODIFIABLE;
  }

  ash::OwnerSettingsServiceAsh* service =
      ash::OwnerSettingsServiceAshFactory::GetForBrowserContext(profile_);

  if (service && service->HandlesSetting(pref_name) &&
      service->Set(pref_name, *value)) {
    return settings_private::SetPrefResult::SUCCESS;
  }
  return settings_private::SetPrefResult::PREF_NOT_MODIFIABLE;

#else
  return settings_private::SetPrefResult::PREF_NOT_FOUND;
#endif
}

bool PrefsUtil::AppendToListCrosSetting(const std::string& pref_name,
                                        const base::Value& value) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  ash::OwnerSettingsServiceAsh* service =
      ash::OwnerSettingsServiceAshFactory::GetForBrowserContext(profile_);

  return service && service->HandlesSetting(pref_name) &&
         service->AppendToList(pref_name, value);

#else
  return false;
#endif
}

bool PrefsUtil::RemoveFromListCrosSetting(const std::string& pref_name,
                                          const base::Value& value) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  ash::OwnerSettingsServiceAsh* service =
      ash::OwnerSettingsServiceAshFactory::GetForBrowserContext(profile_);

  return service && service->HandlesSetting(pref_name) &&
         service->RemoveFromList(pref_name, value);

#else
  return false;
#endif
}

bool PrefsUtil::IsPrefTypeURL(const std::string& pref_name) {
  return GetAllowlistedPrefType(pref_name) ==
         settings_api::PrefType::PREF_TYPE_URL;
}

#if BUILDFLAG(IS_CHROMEOS_ASH)
bool PrefsUtil::IsPrefEnterpriseManaged(const std::string& pref_name) {
  policy::BrowserPolicyConnectorAsh* connector =
      g_browser_process->platform_part()->browser_policy_connector_ash();
  if (!connector->IsDeviceEnterpriseManaged())
    return false;
  if (IsPrivilegedCrosSetting(pref_name))
    return true;
  if (pref_name == ash::kSystemTimezone || pref_name == prefs::kUserTimezone) {
    return ash::system::IsTimezonePrefsManaged(pref_name);
  }
  return false;
}

bool PrefsUtil::IsPrefOwnerControlled(const std::string& pref_name) {
  // ash::kSystemTimezone is global display-only preference and
  // it should appear as disabled, but not owned.
  if (pref_name == ash::kSystemTimezone)
    return false;

  if (IsPrivilegedCrosSetting(pref_name)) {
    if (!chromeos::ProfileHelper::IsOwnerProfile(profile_))
      return true;
  }
  return false;
}

bool PrefsUtil::IsPrefPrimaryUserControlled(const std::string& pref_name) {
  // ash::kSystemTimezone is read-only, but for the non-primary users
  // it should have "primary user controlled" attribute.
  if (pref_name == prefs::kUserTimezone || pref_name == ash::kSystemTimezone) {
    user_manager::UserManager* user_manager = user_manager::UserManager::Get();
    const user_manager::User* user =
        chromeos::ProfileHelper::Get()->GetUserByProfile(profile_);
    if (user && user->GetAccountId() !=
                    user_manager->GetPrimaryUser()->GetAccountId()) {
      return true;
    }
  }
  return false;
}

bool PrefsUtil::IsHotwordDisabledForChildUser(const std::string& pref_name) {
  const std::string& hotwordEnabledPref =
      chromeos::assistant::prefs::kAssistantHotwordEnabled;
  if (!profile_->IsChild() || pref_name != hotwordEnabledPref)
    return false;

  PrefService* pref_service = FindServiceForPref(hotwordEnabledPref);
  const PrefService::Preference* pref =
      pref_service->FindPreference(hotwordEnabledPref);
  DCHECK(pref);
  const bool isHotwordEnabled = pref->GetValue()->GetIfBool().value_or(false);
  return !isHotwordEnabled;
}
#endif

bool PrefsUtil::IsPrefSupervisorControlled(const std::string& pref_name) {
  if (pref_name != prefs::kBrowserGuestModeEnabled &&
      pref_name != prefs::kBrowserAddPersonEnabled) {
    return false;
  }
  return profile_->IsChild();
}

bool PrefsUtil::IsPrefUserModifiable(const std::string& pref_name) {
  if (IsSettingReadOnly(pref_name))
    return false;

  const PrefService::Preference* profile_pref =
      profile_->GetPrefs()->FindPreference(pref_name);
  if (profile_pref)
    return profile_pref->IsUserModifiable();

  const PrefService::Preference* local_state_pref =
      g_browser_process->local_state()->FindPreference(pref_name);
  if (local_state_pref)
    return local_state_pref->IsUserModifiable();

  return false;
}

PrefService* PrefsUtil::FindServiceForPref(const std::string& pref_name) {
  PrefService* user_prefs = profile_->GetPrefs();

  // Proxy is a peculiar case: on ChromeOS, settings exist in both user
  // prefs and local state, but chrome://settings should affect only user prefs.
  // Elsewhere the proxy settings are stored in local state.
  // See http://crbug.com/157147

  if (pref_name == proxy_config::prefs::kProxy) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
    return user_prefs;
#else
    return g_browser_process->local_state();
#endif
  }

  // Find which PrefService contains the given pref. Pref names should not
  // be duplicated across services, however if they are, prefer the user's
  // prefs.
  if (user_prefs->FindPreference(pref_name))
    return user_prefs;

  if (g_browser_process->local_state()->FindPreference(pref_name))
    return g_browser_process->local_state();

  return user_prefs;
}

bool PrefsUtil::IsCrosSetting(const std::string& pref_name) {
#if BUILDFLAG(IS_CHROMEOS_ASH)
  return CrosSettings::Get()->IsCrosSettings(pref_name);
#else
  return false;
#endif
}

const Extension* PrefsUtil::GetExtensionControllingPref(
    const settings_api::PrefObject& pref_object) {
  // Look for specific prefs that might be extension controlled. This generally
  // corresponds with some indiciator that should be shown in the settings UI.
  if (pref_object.key == ::prefs::kHomePage)
    return GetExtensionOverridingHomepage(profile_);

  if (pref_object.key == ::prefs::kRestoreOnStartup) {
    if (pref_object.value->GetInt() == SessionStartupPref::kPrefValueURLs)
      return GetExtensionOverridingStartupPages(profile_);
  }

  if (pref_object.key == ::prefs::kURLsToRestoreOnStartup)
    return GetExtensionOverridingStartupPages(profile_);

  if (pref_object.key ==
      DefaultSearchManager::kDefaultSearchProviderDataPrefName) {
    return GetExtensionOverridingSearchEngine(profile_);
  }

  if (pref_object.key == proxy_config::prefs::kProxy)
    return GetExtensionOverridingProxy(profile_);

  // If it's none of the above, attempt a more general strategy.
  std::string extension_id =
      ExtensionPrefValueMapFactory::GetForBrowserContext(profile_)
          ->GetExtensionControllingPref(pref_object.key);
  if (extension_id.empty())
    return nullptr;

  return ExtensionRegistry::Get(profile_)->GetExtensionById(
      extension_id, ExtensionRegistry::ENABLED);
}

}  // namespace extensions

redpajama_set_name: RedPajamaGithub


Start Shopping With Cleary 365 We know it's important to you to provide your customers with quick quotes and product information. With that in mind Cleary 365 was designed specifically for our lumber dealer customers so that they could provide the quickest and most efficient turn around to their customers. Cleary 365 is a website that provides real-time access to inventory, pricing, and credit information. Click here for more information.
Cleary Millwork Stock Stair Catalog When it comes to stairway needs, Cleary Millwork offers it all: Stairparts, Custom Stairparts, Preassembled Stairs, Spiral and Attic Stairs. We offer a large stocking inventory of Fitts and Cooper Stairparts and our custom capabilities offer the end user endless options. Click here to view the catalog.
Cleary Millwork's Commercial Prefinishing Catalog is here!
Cleary Millwork's 2018 Interior Door Catalog is here!


The second beta of macOS Sierra 10.12.1, a minor update to Apple's latest operating system for the Mac, was today released to developers, a week after Sierra was publicly released.
macOS Sierra 10.12.1 beta 2, build 16B2333a, to use the new beta's full and formal name, is now available for download through the Apple Developer Center or the Mac App Store's Software Update mechanism. So, are there any big changes in this new beta?
It might be too early to say with confidence, but it seems unlikely. MacRumors observes that macOS Sierra 10.12.1 apparently focuses on fixing bugs and making under-the-hood enhancements to performance in order to address recently discovered issues with Sierra.
Furthermore, few obvious changes were noticed in the first beta of macOS Sierra 10.12.1. It did, however, add to the Photos software with support for the Portrait feature brought to the iPhone 7 Plus by the recently-released beta of iOS 10.1.
The Portrait feature, which Apple advertised at its big media event earlier this month but was not ready to ship with the iPhone 7 Plus, enables that device's camera to simulate a shallow depth of field effect akin to that possible with an sophisticated DSLR camera.


text:
Tag Archives: war on terror
Cheney: Violating the Code of Ethics for Retired Ministers…And the Tradition of Respect Held Sacred by Former U.S. Chief Executives
Posted on March 28, 2009 by Dr. David Waggoner, PhD
Every professional association that I have belonged to has a Code of Ethics. It is one of the hallmarks that not only defines what the profession stands for but also guarantees to the public, whether customer, client, patient, parishioner or whomever, the standard by which that professional will act with integrity.
In light of recent comments by former vice president Dick Cheney blasting the new administration's policies on national security, I wondered if there was a Code of Ethics that applies to the the nation's two top executives?
In an interview on CNN (quoted in the NY Times), Mr Cheney said,
"He is making some choices that, in my mind, will, in fact, raise the risk to the American people of another attack," Mr. Cheney said of Mr. Obama in an interview on the CNN program "State of the Union."
UPDATE: March 29, 2009: Today, on the CNN Political Ticker website both U.S. Special Envoy Richard Holbrooke and Gen. David Patraeus take issue with Cheney's inappropriate comments and breach of professional ethics by spouting off about the Obama administration's changes on national security.
UPDATE #2: March 29, 2009: The fallout from Dick Cheney's unethical criticism of the Obama administration continues to generate backlash. Former President Bush made this statement in response to a question about Cheney's remarks:
"He deserves my silence. I love my country a lot more than I love politics. I think it is essential that he be helped in office."
I spent an evening Googling and scouring Wikipedia, but came up with, well, not a thing. Now, maybe I missed it; and there are laws that apply to federal employees. Just about every state in the Union has a code of Ethics for its Executive Branch. President Obama signed into law a new code for his administration in January. And, of course, there is the United States Constitution, but we all know that Cheney never let a little thing like that interfere with anything he decided he was right about.
But a code of ethics that applies specifically to the president and vice president of the United States apparently has never been written. (If there is a code of ethics either historically enforced, or currently in place, not including Obama's new one, I'd love to read it. Send it to me!).
You might ask, "So what?" As an ordained minister, one of the conditions of my standing with my church, the Disciples of Christ, I have to abide by a Ministerial Code of Ethics. All major denominations have such codes. That code is structured so the pastor not only ministers in an ethical manner during the time he or she is serving a congregation, but also after the person has left to serve another local church or retired from active service. Pastors develop a strong rapport with their members, and when they leave to work at another church, even if it is one across town, the pastor is responsible for maintaining the professional boundaries so the new minister can work freely to develop a new trust and rapport with the church.
The same principle is true for when a minister retires. While I was in seminary, I was the youth minister for a church whose senior pastor had retired after over thirty years at that church. Even though the church was located in a city of nearly three million people and the retired minister moved to another part of town, he did not set up and strictly abide by those ethical boundaries. The new senior pastor, with whom I worked, was constantly having to "defend" his actions to those members who were calling the old pastor and getting a sympathetic ear. It was a lose-lose situation. A year after I had graduated from seminary, the church fired the senior minister. In all honesty, he never had a chance to succeed.
Here are the two statements that are relevant to this discussion from the Ministerial Code of Ethics:
supporting and at no time speaking maliciously of the ministry of my predecessor or another minister in the congregation in which I hold membership;
encouraging the ministry of my successor upon my retirement or other departure from a ministry position, without interfering or intruding, and by making it clear to former parishioners that I am no longer their pastor.
With these two precepts so deeply engrained in my professional life, I find Mr. Cheney's statements inexcuseable. Because I believe he so blatantly violated the trust of the American people in his open disdain for the United States Constituion, as well as the Oath of Office he took as Vice President, in his retirement, he should remain silenced for the rest of his life. He has violated the Code of Ethics by both interfering and intruding with the actions of his successors. He is no longer our vice president and I thank God he was never our pastor.
Posted in Ethics, Ethics and Politics, Extreme Thinkover, Political Commentary, Presdiential Ethics, Professional Ethics, Republicans	| Tagged Barack Obama, Cheney, Cheney comments, Code of Ethics, Dick Cheney, Ethics, Executive Branch Ethics, foreign policy, homland security, National Security, President Obama, Professional Conduct, terrorists, Vice President, war on terror	| Leave a reply
Bush's Surge: The Arsonist Calls 911
Peter Beinhart, a senior fellow in the Council for Foreign Relations, a so-called conservative think-tank, published an op-ed column in the Washington Post on January 18, titled "Admit It: The Surge Worked." The column was printed in my home town newspaper, The Register Guard, today, in the Commentary Section. The RG's title was "Admit it: Bush was right, and courageous."
Beinhart opens with the following thesis statement:
It's no longer a close call: President Bush was right about the surge. According to Michael O'Hanlon and Jason Campbell of the Brookings Institution, the number of Iraqi war dead was 500 in November of 2008, compared with 3,475 in November of 2006. That same month, 69 Americans died in Iraq; in November 2008, 12 did.
All right, assuming O'Hanlon and Campbell of the Brookings Institution got the numbers right, one could agree that the dramatic drop in deaths of both Iraqis and Americans is a good thing. Whereas we can all probably concur that if no one had been killed in one month would have been best, in a nation where a war is being waged, a low casualty count is encouraging news.
Beinhart goes on to acknowledge that the post-surge improvements are fragile:
Is the surge solely responsible for the turnaround? Of course not. Al-Qaeda alienated the Sunni tribes; Moqtada al-Sadr's Mahdi Army decided to stand down; the United States assassinated key insurgent and militia leaders, all of which mattered as much if not more than the increase in U.S. troops. And the decline in violence isn't necessarily permanent. Iraq watchers warn that communal distrust remains high; if someone strikes a match, civil war could again rage out of control.
To a reasonable person, who has been following the progress of the war in Iraq, this statement makes sense. One phrase, however, is disconcerting:
the United States assassinated key insurgent and militia leaders, all of which mattered as much if not more than the increase in U.S. troops.
Beinhart appears to directly contradict himself, here. He seems to imply that a strategy of assassinating the key insurgent leaders would have had the same effect as adding the 30,000 plus troops on the ground (although his punctuation use might be including the impact of Qaeda on the Sunnis and al-Sadr's holding back his Mahdi Army also contributed). So, which factor should be considered the basis for the dramatic decline in deaths, the assassinations or the troops? To what degree did the one depend on the other for that decline? Finally, can Bush be credited for the success, especially, as Beinhart insists, making a courageous decision?
Beinhart believes so:
But if Iraq overall represents a massive stain on Bush's record, his decision to increase America's troop presence in late 2006 now looks like his finest hour.
This statement, questionable as it is on so many levels given the now historical context of the Bush presidency, is only the prelude to Mr. Beinhart's fatal flaw in his whole argument:
Politically, Bush took the path of most resistance. He endured an avalanche of scorn, and now he has been vindicated. He was not only right; he was courageous.
As my grandfather used to say, this is about as "cock-eyed" an interpretation as you could possibly get. Here's why: Beinhart ignores his own half-hearted attempts to describe the events and outcomes of the Surge within the context of historical reality and how George W. Bush's decisions set those events and outcomes in motion. Beinhart believes his own set of assumptions crafted from his political ideology and draws a conclusion that any sophomore college student taking Introduction to Logic could poke holes in after binge-drinking the night before.
Here's my analogy.
Two gangs from opposite sides of town have been feuding for many years. One gang, known as the Bushies, whose leader is called Decider, has grown very large and powerful. None of the gangs on the other side of town, known collectively as the Easties, are as big or as powerful, but they supply the Bushies with "bling" and the Bushies use lots of it, need lots of it, and know that the biggest source of bling is across town. The gangs have been feuding for a long time, but the rumbles have never been very long and the casualties limited. The bling has continued to flow to the Bushies pretty much uninterrupted.
One day, Decider decides the time has come to have the ultimate rumble and take down the Easties for good. He decides to take down the Baghdaddies first. The Bushies hit the Baghdaddies hard, setting their neighborhood on fire and seem to get the upper hand pretty fast. But the gangs in the surrounding neighborhoods feel threatened, and though they know they can't take on the Bushies directly, they send their gang members to infiltrate the rumble. Sometimes they help the Baghdaddies fight back; sometimes they set more of the neighborhood on fire, hoping to prevent their own turf from being torched.
The Bushies are taking a lot of casualties, even though the Baghdaddies are being killed in droves. The burning neighborhood grows and grows, killing more gang members from both sides than the gangs themselves.
Decider doesn't waver in his decisions. Keep going. Finish the feud once and for all with the Bushies on top. The bling must flow.
Flash point. The burning neighborhood erupts into a firestorm. Decider's gang lieutenants surround him and deliver an ultimatum. The firestorm will destroy them all. They must have help to put out the fire.
Decider, against every fiber of his being, relents. He dials 911 and calls for the fire fighters. The flames are soon extinguished. Decider and his supporters trumpet the success of the rumble, and praise Decider for his courage to call 911 as the finest moment of his time as gang leader.
^^^^^^^^^^^
There is a research principle that says when interpreting data, the most likely solution will be both simple and elegant. It will be simple in that no other interpretation agrees so closely with the data, and elegant because it when applied it creates a satisfying unification with the other data in the theory.
And so, there is a conclusion that fits the evidence both simply and elegantly: The arsonist who first set the fire and then was forced to call 911 to save himself and an entire nation from being destroyed by those flames, Mr. Beinhart, was neither right nor courageous.
Posted in Extreme Thinkover, Iraq, Middle East Conflict, Political Commentary, Surge	| Tagged Brookings Institution, Bush, Bush legacy, Council for Foreign Relations, Iraq, Michael O'Hanlon, Peter Beinhart, Register Guard, the Surge, war on terror, Washington Post	| Leave a reply

redpajama_set_name: RedPajamaCommonCrawl


Coat the entire glass with the absinthe and an ice cube. Discard the ice and excess absinthe, and set aside. Add the remaining ingredients to a shaker and fill with ice. Shake well and pour into the prepared glass. Garnish with lemon twist.