1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_PERSONAL_INFO_SUGGESTER_H_
6 #define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_PERSONAL_INFO_SUGGESTER_H_
7 
8 #include <string>
9 
10 #include "base/optional.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/chromeos/input_method/input_method_engine_base.h"
13 #include "chrome/browser/chromeos/input_method/suggester.h"
14 #include "chrome/browser/chromeos/input_method/suggestion_enums.h"
15 #include "chrome/browser/chromeos/input_method/suggestion_handler_interface.h"
16 #include "chrome/browser/extensions/api/input_ime/input_ime_api.h"
17 #include "content/public/browser/tts_controller.h"
18 
19 namespace autofill {
20 class PersonalDataManager;
21 }  // namespace autofill
22 
23 class Profile;
24 
25 namespace chromeos {
26 
27 const char kPersonalInfoSuggesterAcceptanceCount[] =
28     "personal_info_suggester_acceptance_count";
29 const int kMaxAcceptanceCount = 10;
30 const char kPersonalInfoSuggesterShowSettingCount[] =
31     "personal_info_suggester_show_setting_count";
32 const int kMaxShowSettingCount = 10;
33 
34 AssistiveType ProposePersonalInfoAssistiveAction(const base::string16& text);
35 
36 class TtsHandler : public content::UtteranceEventDelegate {
37  public:
38   explicit TtsHandler(Profile* profile);
39   ~TtsHandler() override;
40 
41   // Announce |text| after some |delay|. The delay is to avoid conflict with
42   // other ChromeVox announcements. This should be no-op if ChromeVox is not
43   // enabled.
44   void Announce(const std::string& text,
45                 const base::TimeDelta delay = base::TimeDelta());
46 
47   // UtteranceEventDelegate implementation.
48   void OnTtsEvent(content::TtsUtterance* utterance,
49                   content::TtsEventType event_type,
50                   int char_index,
51                   int length,
52                   const std::string& error_message) override;
53 
54  private:
55   virtual void Speak(const std::string& text);
56 
57   Profile* const profile_;
58   std::unique_ptr<base::OneShotTimer> delay_timer_;
59 };
60 
61 // An agent to suggest personal information when the user types, and adopt or
62 // dismiss the suggestion according to the user action.
63 class PersonalInfoSuggester : public Suggester {
64  public:
65   // If |personal_data_manager| is nullptr, we will obtain it from
66   // |PersonalDataManagerFactory| according to |profile|.
67   PersonalInfoSuggester(
68       SuggestionHandlerInterface* suggestion_handler,
69       Profile* profile,
70       autofill::PersonalDataManager* personal_data_manager = nullptr,
71       std::unique_ptr<TtsHandler> tts_handler = nullptr);
72   ~PersonalInfoSuggester() override;
73 
IsFirstShown()74   bool IsFirstShown() { return first_shown_; }
75 
76   // Suggester overrides:
77   void OnFocus(int context_id) override;
78   void OnBlur() override;
79   SuggestionStatus HandleKeyEvent(
80       const InputMethodEngineBase::KeyboardEvent& event) override;
81   bool Suggest(const base::string16& text) override;
82   // index defaults to 0 as not required for this suggester.
83   bool AcceptSuggestion(size_t index = 0) override;
84   void DismissSuggestion() override;
85   AssistiveType GetProposeActionType() override;
86 
87  private:
88   // Get the suggestion according to |text|.
89   base::string16 GetSuggestion(const base::string16& text);
90 
91   void ShowSuggestion(const base::string16& text,
92                       const size_t confirmed_length);
93 
94   int GetPrefValue(const std::string& pref_name);
95 
96   // Increment int value for the given pref_name by 1 every time the function is
97   // called. The function has no effect after the int value becomes equal to the
98   // max_value.
99   void IncrementPrefValueTilCapped(const std::string& pref_name, int max_value);
100 
101   void SetButtonHighlighted(const ui::ime::AssistiveWindowButton& button,
102                             bool highlighted);
103 
104   SuggestionHandlerInterface* const suggestion_handler_;
105 
106   // ID of the focused text field, 0 if none is focused.
107   int context_id_ = -1;
108 
109   // Assistive type of the last proposed assistive action.
110   AssistiveType proposed_action_type_ = AssistiveType::kGenericAction;
111 
112   // User's Chrome user profile.
113   Profile* const profile_;
114 
115   // Personal data manager provided by autofill service.
116   autofill::PersonalDataManager* const personal_data_manager_;
117 
118   // The handler to handle Text-to-Speech (TTS) request.
119   std::unique_ptr<TtsHandler> const tts_handler_;
120 
121   // If we are showing a suggestion right now.
122   bool suggestion_shown_ = false;
123 
124   // If we are showing the suggestion for the first time.
125   bool first_shown_ = false;
126 
127   // The current suggestion text shown.
128   base::string16 suggestion_;
129 
130   std::vector<ui::ime::AssistiveWindowButton> buttons_;
131   int highlighted_index_;
132   ui::ime::AssistiveWindowButton suggestion_button_;
133   ui::ime::AssistiveWindowButton settings_button_;
134 
135   base::TimeTicks session_start_;
136 };
137 
138 }  // namespace chromeos
139 
140 #endif  // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_PERSONAL_INFO_SUGGESTER_H_
141