| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ash/input_method/japanese/japanese_settings.h" |
| |
| #include "base/containers/fixed_flat_map.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "chrome/browser/ash/input_method/japanese/japanese_prefs_constants.h" |
| #include "chromeos/ash/services/ime/public/mojom/input_method.mojom.h" |
| |
| namespace ash::input_method { |
| namespace { |
| |
| using ::ash::ime::mojom::JapaneseSettings; |
| using ::ash::ime::mojom::JapaneseSettingsPtr; |
| using ::base::UmaHistogramBoolean; |
| using ::base::UmaHistogramCustomCounts; |
| using ::base::UmaHistogramEnumeration; |
| |
| constexpr auto kHistValInputModes = |
| base::MakeFixedFlatMap<JapaneseSettings::InputMode, HistInputMode>({ |
| {JapaneseSettings::InputMode::kRomaji, HistInputMode::kRomaji}, |
| {JapaneseSettings::InputMode::kKana, HistInputMode::kKana}, |
| }); |
| |
| constexpr auto kHistValPunctuations = |
| base::MakeFixedFlatMap<JapaneseSettings::PunctuationStyle, |
| HistPunctuationStyle>({ |
| {JapaneseSettings::PunctuationStyle::kKutenTouten, |
| HistPunctuationStyle::kKutenTouten}, |
| {JapaneseSettings::PunctuationStyle::kCommaPeriod, |
| HistPunctuationStyle::kCommaPeriod}, |
| {JapaneseSettings::PunctuationStyle::kKutenPeriod, |
| HistPunctuationStyle::kKutenPeriod}, |
| {JapaneseSettings::PunctuationStyle::kCommaTouten, |
| HistPunctuationStyle::kCommaTouten}, |
| }); |
| |
| constexpr auto kHistValSymbols = |
| base::MakeFixedFlatMap<JapaneseSettings::SymbolStyle, HistSymbolStyle>({ |
| {JapaneseSettings::SymbolStyle::kCornerBracketMiddleDot, |
| HistSymbolStyle::kCornerBracketMiddleDot}, |
| {JapaneseSettings::SymbolStyle::kSquareBracketSlash, |
| HistSymbolStyle::kSquareBracketSlash}, |
| {JapaneseSettings::SymbolStyle::kCornerBracketSlash, |
| HistSymbolStyle::kCornerBracketSlash}, |
| {JapaneseSettings::SymbolStyle::kSquareBracketMiddleDot, |
| HistSymbolStyle::kSquareBracketMiddleDot}, |
| }); |
| |
| constexpr auto kHistValSpaceInputStyles = |
| base::MakeFixedFlatMap<JapaneseSettings::SpaceInputStyle, |
| HistSpaceInputStyle>({ |
| {JapaneseSettings::SpaceInputStyle::kInputMode, |
| HistSpaceInputStyle::kInputMode}, |
| {JapaneseSettings::SpaceInputStyle::kFullWidth, |
| HistSpaceInputStyle::kFullWidth}, |
| {JapaneseSettings::SpaceInputStyle::kHalfWidth, |
| HistSpaceInputStyle::kHalfWidth}, |
| }); |
| |
| constexpr auto kHistValSelectionShortcuts = |
| base::MakeFixedFlatMap<JapaneseSettings::SelectionShortcut, |
| HistSelectionShortcut>({ |
| {JapaneseSettings::SelectionShortcut::kDigits123456789, |
| HistSelectionShortcut::kDigits123456789}, |
| {JapaneseSettings::SelectionShortcut::kAsdfghjkl, |
| HistSelectionShortcut::kAsdfghjkl}, |
| {JapaneseSettings::SelectionShortcut::kNoShortcut, |
| HistSelectionShortcut::kNoShortcut}, |
| }); |
| |
| constexpr auto kHistValKeymapStyles = |
| base::MakeFixedFlatMap<JapaneseSettings::KeymapStyle, HistKeymapStyle>({ |
| {JapaneseSettings::KeymapStyle::kCustom, HistKeymapStyle::kCustom}, |
| {JapaneseSettings::KeymapStyle::kAtok, HistKeymapStyle::kAtok}, |
| {JapaneseSettings::KeymapStyle::kMsime, HistKeymapStyle::kMsime}, |
| {JapaneseSettings::KeymapStyle::kKotoeri, HistKeymapStyle::kKotoeri}, |
| {JapaneseSettings::KeymapStyle::kMobile, HistKeymapStyle::kMobile}, |
| {JapaneseSettings::KeymapStyle::kChromeos, HistKeymapStyle::kChromeos}, |
| }); |
| |
| constexpr auto kHistValShiftKeyModeStyles = |
| base::MakeFixedFlatMap<JapaneseSettings::ShiftKeyModeStyle, |
| HistShiftKeyModeStyle>({ |
| {JapaneseSettings::ShiftKeyModeStyle::kOff, |
| HistShiftKeyModeStyle::kOff}, |
| {JapaneseSettings::ShiftKeyModeStyle::kAlphanumeric, |
| HistShiftKeyModeStyle::kAlphanumeric}, |
| {JapaneseSettings::ShiftKeyModeStyle::kKatakana, |
| HistShiftKeyModeStyle::kKatakana}, |
| }); |
| |
| constexpr auto kInputModes = |
| base::MakeFixedFlatMap<std::string_view, JapaneseSettings::InputMode>({ |
| {kJpPrefInputModeRomaji, JapaneseSettings::InputMode::kRomaji}, |
| {kJpPrefInputModeKana, JapaneseSettings::InputMode::kKana}, |
| }); |
| |
| constexpr auto kPunctuations = |
| base::MakeFixedFlatMap<std::string_view, |
| JapaneseSettings::PunctuationStyle>({ |
| {kJpPrefPunctuationStyleKutenTouten, |
| JapaneseSettings::PunctuationStyle::kKutenTouten}, |
| {kJpPrefPunctuationStyleCommaPeriod, |
| JapaneseSettings::PunctuationStyle::kCommaPeriod}, |
| {kJpPrefPunctuationStyleKutenPeriod, |
| JapaneseSettings::PunctuationStyle::kKutenPeriod}, |
| {kJpPrefPunctuationStyleCommaTouten, |
| JapaneseSettings::PunctuationStyle::kCommaTouten}, |
| }); |
| |
| constexpr auto kSymbols = |
| base::MakeFixedFlatMap<std::string_view, JapaneseSettings::SymbolStyle>({ |
| {kJpPrefSymbolStyleCornerBracketMiddleDot, |
| JapaneseSettings::SymbolStyle::kCornerBracketMiddleDot}, |
| {kJpPrefSymbolStyleSquareBracketSlash, |
| JapaneseSettings::SymbolStyle::kSquareBracketSlash}, |
| {kJpPrefSymbolStyleCornerBracketSlash, |
| JapaneseSettings::SymbolStyle::kCornerBracketSlash}, |
| {kJpPrefSymbolStyleSquareBracketMiddleDot, |
| JapaneseSettings::SymbolStyle::kSquareBracketMiddleDot}, |
| }); |
| |
| constexpr auto kSpaceInputStyles = |
| base::MakeFixedFlatMap<std::string_view, JapaneseSettings::SpaceInputStyle>( |
| { |
| {kJpPrefSpaceInputStyleInputMode, |
| JapaneseSettings::SpaceInputStyle::kInputMode}, |
| {kJpPrefSpaceInputStyleFullwidth, |
| JapaneseSettings::SpaceInputStyle::kFullWidth}, |
| {kJpPrefSpaceInputStyleHalfwidth, |
| JapaneseSettings::SpaceInputStyle::kHalfWidth}, |
| }); |
| |
| constexpr auto kSelectionShortcuts = |
| base::MakeFixedFlatMap<std::string_view, |
| JapaneseSettings::SelectionShortcut>({ |
| {kJpPrefSelectionShortcutDigits123456789, |
| JapaneseSettings::SelectionShortcut::kDigits123456789}, |
| {kJpPrefSelectionShortcutAsdfghjkl, |
| JapaneseSettings::SelectionShortcut::kAsdfghjkl}, |
| {kJpPrefSelectionShortcutNoShortcut, |
| JapaneseSettings::SelectionShortcut::kNoShortcut}, |
| }); |
| |
| constexpr auto kKeymapStyles = |
| base::MakeFixedFlatMap<std::string_view, JapaneseSettings::KeymapStyle>({ |
| {kJpPrefKeymapStyleCustom, JapaneseSettings::KeymapStyle::kCustom}, |
| {kJpPrefKeymapStyleAtok, JapaneseSettings::KeymapStyle::kAtok}, |
| {kJpPrefKeymapStyleMsIme, JapaneseSettings::KeymapStyle::kMsime}, |
| {kJpPrefKeymapStyleKotoeri, JapaneseSettings::KeymapStyle::kKotoeri}, |
| {kJpPrefKeymapStyleMobile, JapaneseSettings::KeymapStyle::kMobile}, |
| {kJpPrefKeymapStyleChromeOs, JapaneseSettings::KeymapStyle::kChromeos}, |
| }); |
| |
| constexpr auto kShiftKeyModeStyle = |
| base::MakeFixedFlatMap<std::string_view, |
| JapaneseSettings::ShiftKeyModeStyle>({ |
| {kJpPrefShiftKeyModeStyleOff, |
| JapaneseSettings::ShiftKeyModeStyle::kOff}, |
| {kJpPrefShiftKeyModeStyleAlphanumeric, |
| JapaneseSettings::ShiftKeyModeStyle::kAlphanumeric}, |
| {kJpPrefShiftKeyModeStyleKatakana, |
| JapaneseSettings::ShiftKeyModeStyle::kKatakana}, |
| }); |
| |
| // Makes default based on what drop down menu in settings page will show if |
| // unset. |
| JapaneseSettingsPtr MakeDefaultJapaneseSettings() { |
| JapaneseSettingsPtr response = JapaneseSettings::New(); |
| // LINT.IfChange(JpPrefDefaults) |
| response->automatically_switch_to_halfwidth = true; |
| response->shift_key_mode_style = |
| JapaneseSettings::ShiftKeyModeStyle::kAlphanumeric; |
| response->use_input_history = true; |
| response->use_system_dictionary = true; |
| response->number_of_suggestions = 3; |
| response->input_mode = JapaneseSettings::InputMode::kRomaji; |
| response->punctuation_style = |
| JapaneseSettings::PunctuationStyle::kKutenTouten; |
| response->symbol_style = |
| JapaneseSettings::SymbolStyle::kCornerBracketMiddleDot; |
| response->space_input_style = JapaneseSettings::SpaceInputStyle::kInputMode; |
| response->selection_shortcut = |
| JapaneseSettings::SelectionShortcut::kDigits123456789; |
| response->keymap_style = JapaneseSettings::KeymapStyle::kCustom; |
| response->disable_personalized_suggestions = false; |
| // The below setting is unused. It was originally in the legacy Japanese |
| // config, but since all data is collected using UMA, this was ignored and the |
| // UMA setting was the main toggle for sending statistics. |
| response->unused2 = false; |
| // LINT.ThenChange(/chrome/browser/resources/ash/settings/os_languages_page/input_method_util.ts:JpPrefDefaults) |
| return response; |
| } |
| |
| } // namespace |
| |
| JapaneseSettingsPtr ToMojomInputMethodSettings(const base::Value::Dict& prefs) { |
| JapaneseSettingsPtr response = MakeDefaultJapaneseSettings(); |
| if (const std::string* val = prefs.FindString(kJpPrefInputMode); |
| val != nullptr) { |
| if (auto it = kInputModes.find(*val); it != kInputModes.end()) { |
| response->input_mode = it->second; |
| } else { |
| LOG(ERROR) << "Value not found for " << *val; |
| } |
| } |
| if (const std::string* val = prefs.FindString(kJpPrefPunctuationStyle); |
| val != nullptr) { |
| if (auto it = kPunctuations.find(*val); it != kPunctuations.end()) { |
| response->punctuation_style = it->second; |
| } else { |
| LOG(ERROR) << "Value not found for " << *val; |
| } |
| } |
| if (const std::string* val = prefs.FindString(kJpPrefSymbolStyle); |
| val != nullptr) { |
| if (auto it = kSymbols.find(*val); it != kSymbols.end()) { |
| response->symbol_style = it->second; |
| } else { |
| LOG(ERROR) << "Value not found for " << *val; |
| } |
| } |
| if (const std::string* val = prefs.FindString(kJpPrefSpaceInputStyle); |
| val != nullptr) { |
| if (auto it = kSpaceInputStyles.find(*val); it != kSpaceInputStyles.end()) { |
| response->space_input_style = it->second; |
| } else { |
| LOG(ERROR) << "Value not found for " << *val; |
| } |
| } |
| if (const std::string* val = prefs.FindString(kJpPrefSelectionShortcut); |
| val != nullptr) { |
| if (auto it = kSelectionShortcuts.find(*val); |
| it != kSelectionShortcuts.end()) { |
| response->selection_shortcut = it->second; |
| } else { |
| LOG(ERROR) << "Value not found for " << *val; |
| } |
| } |
| if (const std::string* val = prefs.FindString(kJpPrefKeymapStyle); |
| val != nullptr) { |
| if (auto it = kKeymapStyles.find(*val); it != kKeymapStyles.end()) { |
| response->keymap_style = it->second; |
| } else { |
| LOG(ERROR) << "Value not found for " << *val; |
| } |
| } |
| if (const std::string* val = prefs.FindString(kJpPrefShiftKeyModeStyle); |
| val != nullptr) { |
| if (auto it = kShiftKeyModeStyle.find(*val); |
| it != kShiftKeyModeStyle.end()) { |
| response->shift_key_mode_style = it->second; |
| } else { |
| LOG(ERROR) << "Value not found for " << *val; |
| } |
| } |
| |
| response->use_input_history = prefs.FindBool(kJpPrefUseInputHistory) |
| .value_or(response->use_input_history); |
| response->use_system_dictionary = |
| prefs.FindBool(kJpPrefUseSystemDictionary) |
| .value_or(response->use_system_dictionary); |
| response->number_of_suggestions = |
| prefs.FindInt(kJpPrefNumberOfSuggestions) |
| .value_or(response->number_of_suggestions); |
| response->disable_personalized_suggestions = |
| prefs.FindBool(kJpPrefDisablePersonalizedSuggestions) |
| .value_or(response->disable_personalized_suggestions); |
| response->automatically_switch_to_halfwidth = |
| prefs.FindBool(kJpPrefAutomaticallySwitchToHalfwidth) |
| .value_or(response->automatically_switch_to_halfwidth); |
| RecordJapaneseSettingsMetrics(*response); |
| return response; |
| } |
| |
| void RecordJapaneseSettingsMetrics( |
| const ash::ime::mojom::JapaneseSettings& settings) { |
| if (auto it = kHistValInputModes.find(settings.input_mode); |
| it != kHistValInputModes.end()) { |
| UmaHistogramEnumeration( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.InputMode", it->second); |
| } |
| |
| if (auto it = kHistValKeymapStyles.find(settings.keymap_style); |
| it != kHistValKeymapStyles.end()) { |
| UmaHistogramEnumeration( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.KeymapStyle", |
| it->second); |
| } |
| |
| if (auto it = kHistValPunctuations.find(settings.punctuation_style); |
| it != kHistValPunctuations.end()) { |
| UmaHistogramEnumeration( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.PunctuationStyle", |
| it->second); |
| } |
| |
| if (auto it = kHistValSelectionShortcuts.find(settings.selection_shortcut); |
| it != kHistValSelectionShortcuts.end()) { |
| UmaHistogramEnumeration( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.SelectionShortcut", |
| it->second); |
| } |
| |
| if (auto it = kHistValShiftKeyModeStyles.find(settings.shift_key_mode_style); |
| it != kHistValShiftKeyModeStyles.end()) { |
| UmaHistogramEnumeration( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.ShiftKeyModeStyle", |
| it->second); |
| } |
| |
| if (auto it = kHistValSpaceInputStyles.find(settings.space_input_style); |
| it != kHistValSpaceInputStyles.end()) { |
| UmaHistogramEnumeration( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.SpaceInputStyle", |
| it->second); |
| } |
| |
| if (auto it = kHistValSymbols.find(settings.symbol_style); |
| it != kHistValSymbols.end()) { |
| UmaHistogramEnumeration( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.SymbolStyle", |
| it->second); |
| } |
| |
| UmaHistogramCustomCounts( |
| /*name*/ |
| "InputMethod.PhysicalKeyboard.Japanese.Settings.NumberOfSuggestions", |
| /*sample=*/settings.number_of_suggestions, |
| /*min=*/1, |
| /*exclusive_max=*/10, |
| /*buckets=*/10); |
| |
| UmaHistogramBoolean( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings." |
| "AutoSwitchToHalfwidth", |
| settings.automatically_switch_to_halfwidth); |
| UmaHistogramBoolean( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings." |
| "DisablePersonalizedSuggestions", |
| settings.disable_personalized_suggestions); |
| UmaHistogramBoolean( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings." |
| "UseInputHistory", |
| settings.use_input_history); |
| UmaHistogramBoolean( |
| "InputMethod.PhysicalKeyboard.Japanese.Settings." |
| "UseSystemDictionary", |
| settings.use_system_dictionary); |
| } |
| |
| } // namespace ash::input_method |