1 // Copyright 2020 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 ASH_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_
6 #define ASH_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "ash/ash_export.h"
12 #include "ash/public/cpp/quick_answers/controller/quick_answers_controller.h"
13 #include "chromeos/components/quick_answers/quick_answers_client.h"
14 #include "chromeos/components/quick_answers/quick_answers_model.h"
15 #include "ui/gfx/geometry/rect.h"
16 
17 namespace chromeos {
18 namespace quick_answers {
19 class QuickAnswersNotice;
20 }  // namespace quick_answers
21 }  // namespace chromeos
22 
23 namespace ash {
24 class QuickAnswersUiController;
25 
26 enum class QuickAnswersVisibility {
27   // Quick Answers UI is hidden and the previous session has finished.
28   kClosed = 0,
29   // Quick Answers session is initializing and the UI will be shown when the
30   // context is ready.
31   kPending = 1,
32   // Quick Answers UI is visible.
33   kVisible = 2,
34 };
35 
36 // Implementation of QuickAnswerController. It fetches quick answers
37 // result via QuickAnswersClient and manages quick answers UI.
38 class ASH_EXPORT QuickAnswersControllerImpl
39     : public QuickAnswersController,
40       public chromeos::quick_answers::QuickAnswersDelegate {
41  public:
42   explicit QuickAnswersControllerImpl();
43   QuickAnswersControllerImpl(const QuickAnswersControllerImpl&) = delete;
44   QuickAnswersControllerImpl& operator=(const QuickAnswersControllerImpl&) =
45       delete;
46   ~QuickAnswersControllerImpl() override;
47 
48   // QuickAnswersController:
49   void SetClient(std::unique_ptr<chromeos::quick_answers::QuickAnswersClient>
50                      client) override;
51 
52   // SetClient is required to be called before using these methods.
53   // TODO(yanxiao): refactor to delegate to browser.
54   void MaybeShowQuickAnswers(
55       const gfx::Rect& anchor_bounds,
56       const std::string& title,
57       const chromeos::quick_answers::Context& context) override;
58 
59   void DismissQuickAnswers(bool is_active) override;
60 
61   // Update the bounds of the anchor view.
62   void UpdateQuickAnswersAnchorBounds(const gfx::Rect& anchor_bounds) override;
63 
64   void SetPendingShowQuickAnswers() override;
65 
66   chromeos::quick_answers::QuickAnswersDelegate* GetQuickAnswersDelegate()
67       override;
68 
69   // QuickAnswersDelegate:
70   void OnQuickAnswerReceived(
71       std::unique_ptr<chromeos::quick_answers::QuickAnswer> answer) override;
72   void OnEligibilityChanged(bool eligible) override;
73   void OnNetworkError() override;
74   void OnRequestPreprocessFinished(
75       const chromeos::quick_answers::QuickAnswersRequest& processed_request)
76       override;
77 
78   // Retry sending quick answers request to backend.
79   void OnRetryQuickAnswersRequest();
80 
81   // User clicks on the quick answer result.
82   void OnQuickAnswerClick();
83 
84   // Called by the UI Controller when user accepts the notice for the
85   // Quick Answers feature.
86   void OnUserNoticeAccepted();
87 
88   // Called by the UI Controller when user requests detailed settings from the
89   // notice screen for the Quick Answers feature.
90   void OnNoticeSettingsRequestedByUser();
91 
92   // Open Quick-Answers dogfood URL.
93   void OpenQuickAnswersDogfoodLink();
94 
quick_answers_ui_controller()95   QuickAnswersUiController* quick_answers_ui_controller() {
96     return quick_answers_ui_controller_.get();
97   }
98 
visibility()99   QuickAnswersVisibility visibility() const { return visibility_; }
100 
GetNoticeControllerForTesting()101   chromeos::quick_answers::QuickAnswersNotice* GetNoticeControllerForTesting() {
102     return notice_controller_.get();
103   }
104 
SetVisibilityForTesting(QuickAnswersVisibility visibility)105   void SetVisibilityForTesting(QuickAnswersVisibility visibility) {
106     visibility_ = visibility;
107   }
108 
109  private:
110   void MaybeDismissQuickAnswersNotice();
111 
112   void HandleQuickAnswerRequest(
113       const chromeos::quick_answers::QuickAnswersRequest& request);
114 
115   bool ShouldShowUserNotice() const;
116   // Show the user notice view. Does nothing if the view is already
117   // visible.
118   void ShowUserNotice(const base::string16& intent_type,
119                       const base::string16& intent_text);
120 
121   chromeos::quick_answers::QuickAnswersRequest BuildRequest();
122 
123   // Bounds of the anchor view.
124   gfx::Rect anchor_bounds_;
125 
126   // Query used to retrieve quick answer.
127   std::string query_;
128 
129   // Title to be shown on the QuickAnswers view.
130   std::string title_;
131 
132   // Context information, including surrounding text and device properties.
133   chromeos::quick_answers::Context context_;
134 
135   std::unique_ptr<chromeos::quick_answers::QuickAnswersClient>
136       quick_answers_client_;
137   std::unique_ptr<chromeos::quick_answers::QuickAnswersNotice>
138       notice_controller_;
139 
140   // Whether the feature is enabled and all eligibility criteria are met (
141   // locale, consents, etc).
142   bool is_eligible_ = false;
143 
144   std::unique_ptr<QuickAnswersUiController> quick_answers_ui_controller_;
145 
146   // The last received QuickAnswer from client.
147   std::unique_ptr<chromeos::quick_answers::QuickAnswer> quick_answer_;
148 
149   QuickAnswersVisibility visibility_ = QuickAnswersVisibility::kClosed;
150 };
151 
152 }  // namespace ash
153 #endif  // ASH_QUICK_ANSWERS_QUICK_ANSWERS_CONTROLLER_IMPL_H_
154