blob: c0967721a292a7c2af3c2fbad95d35111361d377 [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"
David Black1d1b1b672018-06-20 21:41:579#include "ash/assistant/assistant_ui_controller.h"
David Blackedaf0c32018-06-28 22:06:3910#include "ash/assistant/util/deep_link_util.h"
David Black2f7a70c32018-06-26 02:14:2211#include "ash/new_window_controller.h"
David Blacke1a4b9ed2018-04-19 19:55:0812#include "ash/session/session_controller.h"
David Blacke8f815042018-03-28 18:59:3713#include "ash/shell.h"
Muyuan Li0070f44d2018-05-16 02:57:2314#include "base/bind.h"
15#include "base/memory/scoped_refptr.h"
David Blacke1a4b9ed2018-04-19 19:55:0816#include "base/unguessable_token.h"
Muyuan Li0070f44d2018-05-16 02:57:2317#include "ui/snapshot/snapshot.h"
David Blacke8f815042018-03-28 18:59:3718
19namespace ash {
20
David Black00fdce32018-05-10 20:59:1421AssistantController::AssistantController()
David Black9766ecd2018-06-20 18:29:1122 : assistant_interaction_controller_(
David Black2f7a70c32018-06-26 02:14:2223 std::make_unique<AssistantInteractionController>(this)),
David Black4703d7b2018-06-22 00:16:3924 assistant_ui_controller_(std::make_unique<AssistantUiController>(this)) {
25 // Note that the sub-controllers have a circular dependency.
26 // TODO(dmblack): Remove this circular dependency.
27 assistant_interaction_controller_->SetAssistantUiController(
28 assistant_ui_controller_.get());
29 assistant_ui_controller_->SetAssistantInteractionController(
30 assistant_interaction_controller_.get());
David Black315ac2c2018-06-25 22:25:2031
32 // Observe HighlighterController for region selections.
33 Shell::Get()->highlighter_controller()->AddObserver(this);
David Black4703d7b2018-06-22 00:16:3934}
David Blacke8f815042018-03-28 18:59:3735
David Black4703d7b2018-06-22 00:16:3936AssistantController::~AssistantController() {
David Black315ac2c2018-06-25 22:25:2037 Shell::Get()->highlighter_controller()->RemoveObserver(this);
38
David Black4703d7b2018-06-22 00:16:3939 // Explicitly clean up the circular dependency in the sub-controllers.
40 assistant_interaction_controller_->SetAssistantUiController(nullptr);
41 assistant_ui_controller_->SetAssistantInteractionController(nullptr);
42}
David Blacke8f815042018-03-28 18:59:3743
David Black00fdce32018-05-10 20:59:1444void AssistantController::BindRequest(
45 mojom::AssistantControllerRequest request) {
David Black75f9fec2018-05-17 22:10:3946 assistant_controller_bindings_.AddBinding(this, std::move(request));
David Blacke8f815042018-03-28 18:59:3747}
48
David Blacke802d4062018-06-29 01:59:0549void AssistantController::AddObserver(AssistantControllerObserver* observer) {
50 observers_.AddObserver(observer);
51}
52
53void AssistantController::RemoveObserver(
54 AssistantControllerObserver* observer) {
55 observers_.RemoveObserver(observer);
56}
57
David Black00fdce32018-05-10 20:59:1458void AssistantController::SetAssistant(
David Blacke8f815042018-03-28 18:59:3759 chromeos::assistant::mojom::AssistantPtr assistant) {
David Black4c3656c2018-04-19 17:31:4760 assistant_ = std::move(assistant);
61
David Black4703d7b2018-06-22 00:16:3962 // Provide reference to sub-controllers.
David Black9766ecd2018-06-20 18:29:1163 assistant_interaction_controller_->SetAssistant(assistant_.get());
David Black4703d7b2018-06-22 00:16:3964 assistant_ui_controller_->SetAssistant(assistant_.get());
David Black4c3656c2018-04-19 17:31:4765}
66
David Black7ffd2842018-05-25 01:25:5367void AssistantController::SetAssistantImageDownloader(
68 mojom::AssistantImageDownloaderPtr assistant_image_downloader) {
69 assistant_image_downloader_ = std::move(assistant_image_downloader);
70}
71
Yue Libf89f72a2018-06-18 16:51:1672void AssistantController::SetAssistantSetup(
73 mojom::AssistantSetupPtr assistant_setup) {
74 assistant_setup_ = std::move(assistant_setup);
David Black9766ecd2018-06-20 18:29:1175
David Black4703d7b2018-06-22 00:16:3976 // Provide reference to UI controller.
77 assistant_ui_controller_->SetAssistantSetup(assistant_setup_.get());
David Black9766ecd2018-06-20 18:29:1178}
79
80void AssistantController::SetWebContentsManager(
81 mojom::WebContentsManagerPtr web_contents_manager) {
82 web_contents_manager_ = std::move(web_contents_manager);
Yue Libf89f72a2018-06-18 16:51:1683}
84
Muyuan Li0070f44d2018-05-16 02:57:2385void AssistantController::RequestScreenshot(
86 const gfx::Rect& rect,
87 RequestScreenshotCallback callback) {
88 // TODO(muyuanli): handle multi-display when assistant's behavior is defined.
89 auto* root_window = Shell::GetPrimaryRootWindow();
90 gfx::Rect source_rect =
91 rect.IsEmpty() ? gfx::Rect(root_window->bounds().size()) : rect;
92 ui::GrabWindowSnapshotAsyncJPEG(
93 root_window, source_rect,
94 base::BindRepeating(
95 [](RequestScreenshotCallback callback,
96 scoped_refptr<base::RefCountedMemory> data) {
97 std::move(callback).Run(std::vector<uint8_t>(
98 data->front(), data->front() + data->size()));
99 },
100 base::Passed(&callback)));
101}
102
David Black5326a8eb2018-06-12 22:05:34103void AssistantController::ManageWebContents(
David Blacke1a4b9ed2018-04-19 19:55:08104 const base::UnguessableToken& id_token,
David Black5326a8eb2018-06-12 22:05:34105 mojom::ManagedWebContentsParamsPtr params,
106 mojom::WebContentsManager::ManageWebContentsCallback callback) {
107 DCHECK(web_contents_manager_);
David Blacke1a4b9ed2018-04-19 19:55:08108
109 const mojom::UserSession* user_session =
110 Shell::Get()->session_controller()->GetUserSession(0);
111
112 if (!user_session) {
113 LOG(WARNING) << "Unable to retrieve active user session.";
David Black5326a8eb2018-06-12 22:05:34114 std::move(callback).Run(base::nullopt);
David Blacke1a4b9ed2018-04-19 19:55:08115 return;
116 }
117
David Black5326a8eb2018-06-12 22:05:34118 // Supply account ID.
119 params->account_id = user_session->user_info->account_id;
120
121 // Specify that we will handle top level browser requests.
David Black5326a8eb2018-06-12 22:05:34122 ash::mojom::ManagedWebContentsOpenUrlDelegatePtr ptr;
David Black2f7a70c32018-06-26 02:14:22123 web_contents_open_url_delegate_bindings_.AddBinding(this,
124 mojo::MakeRequest(&ptr));
David Black5326a8eb2018-06-12 22:05:34125 params->open_url_delegate_ptr_info = ptr.PassInterface();
126
127 web_contents_manager_->ManageWebContents(id_token, std::move(params),
128 std::move(callback));
David Blacke1a4b9ed2018-04-19 19:55:08129}
130
David Black5326a8eb2018-06-12 22:05:34131void AssistantController::ReleaseWebContents(
132 const base::UnguessableToken& id_token) {
133 web_contents_manager_->ReleaseWebContents(id_token);
David Blacke1a4b9ed2018-04-19 19:55:08134}
135
David Black5326a8eb2018-06-12 22:05:34136void AssistantController::ReleaseWebContents(
David Black3bfd968602018-04-24 22:07:46137 const std::vector<base::UnguessableToken>& id_tokens) {
David Black5326a8eb2018-06-12 22:05:34138 web_contents_manager_->ReleaseAllWebContents(id_tokens);
David Black3bfd968602018-04-24 22:07:46139}
140
David Black7ffd2842018-05-25 01:25:53141void AssistantController::DownloadImage(
142 const GURL& url,
143 mojom::AssistantImageDownloader::DownloadCallback callback) {
144 DCHECK(assistant_image_downloader_);
145
146 const mojom::UserSession* user_session =
147 Shell::Get()->session_controller()->GetUserSession(0);
148
149 if (!user_session) {
150 LOG(WARNING) << "Unable to retrieve active user session.";
David Black5326a8eb2018-06-12 22:05:34151 std::move(callback).Run(gfx::ImageSkia());
David Black7ffd2842018-05-25 01:25:53152 return;
153 }
154
155 AccountId account_id = user_session->user_info->account_id;
156 assistant_image_downloader_->Download(account_id, url, std::move(callback));
157}
158
David Black315ac2c2018-06-25 22:25:20159void AssistantController::OnHighlighterSelectionRecognized(
160 const gfx::Rect& rect) {
161 // TODO(muyuanli): Request screen context for |rect|.
162 NOTIMPLEMENTED();
163}
164
David Black2f7a70c32018-06-26 02:14:22165void AssistantController::OnOpenUrlFromTab(const GURL& url) {
166 OpenUrl(url);
167}
168
169void AssistantController::OpenUrl(const GURL& url) {
David Blackedaf0c32018-06-28 22:06:39170 if (assistant::util::IsDeepLinkUrl(url)) {
David Blacke802d4062018-06-29 01:59:05171 for (AssistantControllerObserver& observer : observers_)
172 observer.OnDeepLinkReceived(url);
David Blackedaf0c32018-06-28 22:06:39173 return;
174 }
David Black2f7a70c32018-06-26 02:14:22175
David Blackedaf0c32018-06-28 22:06:39176 Shell::Get()->new_window_controller()->NewTabWithUrl(url);
David Blacke802d4062018-06-29 01:59:05177
178 for (AssistantControllerObserver& observer : observers_)
179 observer.OnUrlOpened(url);
David Black2f7a70c32018-06-26 02:14:22180}
181
David Blacke8f815042018-03-28 18:59:37182} // namespace ash