blob: 1eda7193c99d3f3a8f8499e6c9f44b7186ca3836 [file] [log] [blame]
David Black71ab74d2018-04-12 06:52:311// Copyright 2018 The Chromium Authors. All rights reserved.
David Blacke8f815042018-03-28 18:59:372// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
David Black00fdce32018-05-10 20:59:145#include "ash/assistant/assistant_controller.h"
David Blacke8f815042018-03-28 18:59:376
David Blacke802d4062018-06-29 01:59:057#include "ash/assistant/assistant_controller_observer.h"
David Black9766ecd2018-06-20 18:29:118#include "ash/assistant/assistant_interaction_controller.h"
wutao16db603c2018-07-10 06:43:599#include "ash/assistant/assistant_notification_controller.h"
David Blackc22e4352018-07-11 21:29:4810#include "ash/assistant/assistant_screen_context_controller.h"
David Black1d1b1b672018-06-20 21:41:5711#include "ash/assistant/assistant_ui_controller.h"
David Blackedaf0c32018-06-28 22:06:3912#include "ash/assistant/util/deep_link_util.h"
David Black2f7a70c32018-06-26 02:14:2213#include "ash/new_window_controller.h"
David Blacke1a4b9ed2018-04-19 19:55:0814#include "ash/session/session_controller.h"
David Blacke8f815042018-03-28 18:59:3715#include "ash/shell.h"
Muyuan Li0070f44d2018-05-16 02:57:2316#include "base/bind.h"
17#include "base/memory/scoped_refptr.h"
David Blacke1a4b9ed2018-04-19 19:55:0818#include "base/unguessable_token.h"
David Blacke8f815042018-03-28 18:59:3719
20namespace ash {
21
David Black00fdce32018-05-10 20:59:1422AssistantController::AssistantController()
David Black9766ecd2018-06-20 18:29:1123 : assistant_interaction_controller_(
David Black2f7a70c32018-06-26 02:14:2224 std::make_unique<AssistantInteractionController>(this)),
wutao16db603c2018-07-10 06:43:5925 assistant_notification_controller_(
26 std::make_unique<AssistantNotificationController>(this)),
David Blackc22e4352018-07-11 21:29:4827 assistant_screen_context_controller_(
David Black1f58bcc2018-07-12 17:59:4028 std::make_unique<AssistantScreenContextController>(this)),
David Blackc22e4352018-07-11 21:29:4829 assistant_ui_controller_(std::make_unique<AssistantUiController>(this)),
wutao16db603c2018-07-10 06:43:5930 weak_factory_(this) {
David Blackf946f832018-07-13 17:29:0931 AddObserver(this);
David Black1f58bcc2018-07-12 17:59:4032 NotifyConstructed();
David Black4703d7b2018-06-22 00:16:3933}
David Blacke8f815042018-03-28 18:59:3734
David Black4703d7b2018-06-22 00:16:3935AssistantController::~AssistantController() {
David Black1f58bcc2018-07-12 17:59:4036 NotifyDestroying();
David Blackf946f832018-07-13 17:29:0937 RemoveObserver(this);
David Black4703d7b2018-06-22 00:16:3938}
David Blacke8f815042018-03-28 18:59:3739
David Black00fdce32018-05-10 20:59:1440void AssistantController::BindRequest(
41 mojom::AssistantControllerRequest request) {
David Black75f9fec2018-05-17 22:10:3942 assistant_controller_bindings_.AddBinding(this, std::move(request));
David Blacke8f815042018-03-28 18:59:3743}
44
David Blacke802d4062018-06-29 01:59:0545void AssistantController::AddObserver(AssistantControllerObserver* observer) {
46 observers_.AddObserver(observer);
47}
48
49void AssistantController::RemoveObserver(
50 AssistantControllerObserver* observer) {
51 observers_.RemoveObserver(observer);
52}
53
David Black00fdce32018-05-10 20:59:1454void AssistantController::SetAssistant(
David Blacke8f815042018-03-28 18:59:3755 chromeos::assistant::mojom::AssistantPtr assistant) {
David Black4c3656c2018-04-19 17:31:4756 assistant_ = std::move(assistant);
57
David Black4703d7b2018-06-22 00:16:3958 // Provide reference to sub-controllers.
David Black9766ecd2018-06-20 18:29:1159 assistant_interaction_controller_->SetAssistant(assistant_.get());
wutao16db603c2018-07-10 06:43:5960 assistant_notification_controller_->SetAssistant(assistant_.get());
David Blackc22e4352018-07-11 21:29:4861 assistant_screen_context_controller_->SetAssistant(assistant_.get());
62 assistant_ui_controller_->SetAssistant(assistant_.get());
David Black4c3656c2018-04-19 17:31:4763}
64
David Black7ffd2842018-05-25 01:25:5365void AssistantController::SetAssistantImageDownloader(
66 mojom::AssistantImageDownloaderPtr assistant_image_downloader) {
67 assistant_image_downloader_ = std::move(assistant_image_downloader);
68}
69
Yue Libf89f72a2018-06-18 16:51:1670void AssistantController::SetAssistantSetup(
71 mojom::AssistantSetupPtr assistant_setup) {
72 assistant_setup_ = std::move(assistant_setup);
David Black9766ecd2018-06-20 18:29:1173}
74
75void AssistantController::SetWebContentsManager(
76 mojom::WebContentsManagerPtr web_contents_manager) {
77 web_contents_manager_ = std::move(web_contents_manager);
Yue Libf89f72a2018-06-18 16:51:1678}
79
David Blackc22e4352018-07-11 21:29:4880// TODO(dmblack): Expose AssistantScreenContextController over mojo rather
81// than implementing RequestScreenshot here in AssistantController.
Muyuan Li0070f44d2018-05-16 02:57:2382void AssistantController::RequestScreenshot(
83 const gfx::Rect& rect,
84 RequestScreenshotCallback callback) {
David Blackc22e4352018-07-11 21:29:4885 assistant_screen_context_controller_->RequestScreenshot(rect,
86 std::move(callback));
Muyuan Li0070f44d2018-05-16 02:57:2387}
88
David Black5326a8eb2018-06-12 22:05:3489void AssistantController::ManageWebContents(
David Blacke1a4b9ed2018-04-19 19:55:0890 const base::UnguessableToken& id_token,
David Black5326a8eb2018-06-12 22:05:3491 mojom::ManagedWebContentsParamsPtr params,
92 mojom::WebContentsManager::ManageWebContentsCallback callback) {
93 DCHECK(web_contents_manager_);
David Blacke1a4b9ed2018-04-19 19:55:0894
95 const mojom::UserSession* user_session =
96 Shell::Get()->session_controller()->GetUserSession(0);
97
98 if (!user_session) {
99 LOG(WARNING) << "Unable to retrieve active user session.";
David Black5326a8eb2018-06-12 22:05:34100 std::move(callback).Run(base::nullopt);
David Blacke1a4b9ed2018-04-19 19:55:08101 return;
102 }
103
David Black5326a8eb2018-06-12 22:05:34104 // Supply account ID.
105 params->account_id = user_session->user_info->account_id;
106
107 // Specify that we will handle top level browser requests.
David Black5326a8eb2018-06-12 22:05:34108 ash::mojom::ManagedWebContentsOpenUrlDelegatePtr ptr;
David Black2f7a70c32018-06-26 02:14:22109 web_contents_open_url_delegate_bindings_.AddBinding(this,
110 mojo::MakeRequest(&ptr));
David Black5326a8eb2018-06-12 22:05:34111 params->open_url_delegate_ptr_info = ptr.PassInterface();
112
113 web_contents_manager_->ManageWebContents(id_token, std::move(params),
114 std::move(callback));
David Blacke1a4b9ed2018-04-19 19:55:08115}
116
David Black5326a8eb2018-06-12 22:05:34117void AssistantController::ReleaseWebContents(
118 const base::UnguessableToken& id_token) {
119 web_contents_manager_->ReleaseWebContents(id_token);
David Blacke1a4b9ed2018-04-19 19:55:08120}
121
David Black5326a8eb2018-06-12 22:05:34122void AssistantController::ReleaseWebContents(
David Black3bfd968602018-04-24 22:07:46123 const std::vector<base::UnguessableToken>& id_tokens) {
David Black5326a8eb2018-06-12 22:05:34124 web_contents_manager_->ReleaseAllWebContents(id_tokens);
David Black3bfd968602018-04-24 22:07:46125}
126
David Black7ffd2842018-05-25 01:25:53127void AssistantController::DownloadImage(
128 const GURL& url,
129 mojom::AssistantImageDownloader::DownloadCallback callback) {
130 DCHECK(assistant_image_downloader_);
131
132 const mojom::UserSession* user_session =
133 Shell::Get()->session_controller()->GetUserSession(0);
134
135 if (!user_session) {
136 LOG(WARNING) << "Unable to retrieve active user session.";
David Black5326a8eb2018-06-12 22:05:34137 std::move(callback).Run(gfx::ImageSkia());
David Black7ffd2842018-05-25 01:25:53138 return;
139 }
140
141 AccountId account_id = user_session->user_info->account_id;
142 assistant_image_downloader_->Download(account_id, url, std::move(callback));
143}
144
David Blackb0749ca52018-07-13 21:30:02145void AssistantController::OnDeepLinkReceived(
146 assistant::util::DeepLinkType type,
147 const std::map<std::string, std::string>& params) {
David Black7c07e30e2018-07-25 02:27:19148 using namespace assistant::util;
149
David Blackb0749ca52018-07-13 21:30:02150 switch (type) {
David Black7c07e30e2018-07-25 02:27:19151 case DeepLinkType::kFeedback:
David Blackb0749ca52018-07-13 21:30:02152 // TODO(dmblack): Possibly use a new FeedbackSource (this method defaults
153 // to kFeedbackSourceAsh). This may be useful for differentiating feedback
154 // UI and behavior for Assistant.
155 Shell::Get()->new_window_controller()->OpenFeedbackPage();
156 break;
David Black7c07e30e2018-07-25 02:27:19157 case DeepLinkType::kOnboarding:
158 if (GetDeepLinkParamAsBool(params, DeepLinkParam::kRelaunch)) {
Yue Li3a41afb42018-07-18 17:50:37159 assistant_setup_->StartAssistantOptInFlow(base::BindOnce(
160 [](AssistantUiController* ui_controller, bool completed) {
161 if (completed)
162 ui_controller->ShowUi(AssistantSource::kSetup);
163 },
164 // |assistant_setup_| and |assistant_ui_controller_| are both owned
165 // by this class, so a raw pointer is safe here.
166 assistant_ui_controller_.get()));
167 } else {
168 assistant_setup_->StartAssistantOptInFlow(base::DoNothing());
169 }
170 assistant_ui_controller_->HideUi(AssistantSource::kSetup);
David Blackb0749ca52018-07-13 21:30:02171 break;
David Black7c07e30e2018-07-25 02:27:19172 case DeepLinkType::kUnsupported:
173 case DeepLinkType::kExplore:
174 case DeepLinkType::kQuery:
175 case DeepLinkType::kReminders:
176 case DeepLinkType::kSettings:
David Blackb0749ca52018-07-13 21:30:02177 // No action needed.
178 break;
David Black1859f9f2018-07-13 18:03:34179 }
David Blackf946f832018-07-13 17:29:09180}
181
David Black2f7a70c32018-06-26 02:14:22182void AssistantController::OnOpenUrlFromTab(const GURL& url) {
183 OpenUrl(url);
184}
185
186void AssistantController::OpenUrl(const GURL& url) {
David Blackedaf0c32018-06-28 22:06:39187 if (assistant::util::IsDeepLinkUrl(url)) {
David Black1f58bcc2018-07-12 17:59:40188 NotifyDeepLinkReceived(url);
David Blackedaf0c32018-06-28 22:06:39189 return;
190 }
David Black2f7a70c32018-06-26 02:14:22191
David Blackedaf0c32018-06-28 22:06:39192 Shell::Get()->new_window_controller()->NewTabWithUrl(url);
David Black1f58bcc2018-07-12 17:59:40193 NotifyUrlOpened(url);
194}
David Blacke802d4062018-06-29 01:59:05195
David Black1f58bcc2018-07-12 17:59:40196void AssistantController::NotifyConstructed() {
197 for (AssistantControllerObserver& observer : observers_)
198 observer.OnAssistantControllerConstructed();
199}
200
201void AssistantController::NotifyDestroying() {
202 for (AssistantControllerObserver& observer : observers_)
203 observer.OnAssistantControllerDestroying();
204}
205
206void AssistantController::NotifyDeepLinkReceived(const GURL& deep_link) {
David Blackb0749ca52018-07-13 21:30:02207 using namespace assistant::util;
208
209 // Retrieve deep link type and parsed parameters.
210 DeepLinkType type = GetDeepLinkType(deep_link);
211 const std::map<std::string, std::string> params =
212 GetDeepLinkParams(deep_link);
213
David Black1f58bcc2018-07-12 17:59:40214 for (AssistantControllerObserver& observer : observers_)
David Blackb0749ca52018-07-13 21:30:02215 observer.OnDeepLinkReceived(type, params);
David Black1f58bcc2018-07-12 17:59:40216}
217
218void AssistantController::NotifyUrlOpened(const GURL& url) {
David Blacke802d4062018-06-29 01:59:05219 for (AssistantControllerObserver& observer : observers_)
220 observer.OnUrlOpened(url);
David Black2f7a70c32018-06-26 02:14:22221}
222
wutao16db603c2018-07-10 06:43:59223base::WeakPtr<AssistantController> AssistantController::GetWeakPtr() {
224 return weak_factory_.GetWeakPtr();
225}
226
David Blacke8f815042018-03-28 18:59:37227} // namespace ash