blob: fdaacbab5e86ae88d0845ba0bf55b1246de974d4 [file] [log] [blame]
David Black6b4b1ad22018-08-21 02:45:081// Copyright 2018 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#include "ash/assistant/assistant_cache_controller.h"
6
7#include <vector>
8
David Black02974f82018-08-21 22:56:059#include "ash/assistant/assistant_controller.h"
10#include "ash/assistant/assistant_ui_controller.h"
David Black4c6b9e22018-08-27 20:31:3111#include "ash/assistant/util/assistant_util.h"
David Blackd08c0512018-08-21 17:18:2612#include "ash/assistant/util/deep_link_util.h"
David Black6b4b1ad22018-08-21 02:45:0813#include "ash/shell.h"
14#include "ash/strings/grit/ash_strings.h"
15#include "ash/voice_interaction/voice_interaction_controller.h"
David Black5a1c68932018-08-29 20:11:4316#include "base/metrics/field_trial_params.h"
David Black02974f82018-08-21 22:56:0517#include "base/rand_util.h"
David Black6b4b1ad22018-08-21 02:45:0818#include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
19#include "ui/base/l10n/l10n_util.h"
20
21namespace ash {
22
David Black02974f82018-08-21 22:56:0523namespace {
24
David Black5a1c68932018-08-29 20:11:4325// Conversation starters -------------------------------------------------------
26
27const base::Feature kConversationStartersFeature{
28 "ChromeOSAssistantConversationStarters", base::FEATURE_DISABLED_BY_DEFAULT};
29
30constexpr base::FeatureParam<bool> kImBoredChipEnabled{
31 &kConversationStartersFeature, "im-bored-chip-enabled", false};
32
33constexpr base::FeatureParam<bool> kOpenFilesChipEnabled{
34 &kConversationStartersFeature, "open-files-chip-enabled", false};
35
36constexpr base::FeatureParam<bool> kPlayMusicChipEnabled{
37 &kConversationStartersFeature, "play-music-chip-enabled", false};
38
39constexpr base::FeatureParam<bool> kSendAnEmailChipEnabled{
40 &kConversationStartersFeature, "send-an-email-chip-enabled", false};
41
42constexpr base::FeatureParam<bool> kSetAReminderChipEnabled{
43 &kConversationStartersFeature, "set-a-reminder-chip-enabled", false};
44
45constexpr base::FeatureParam<bool> kWhatCanYouDoChipEnabled{
46 &kConversationStartersFeature, "what-can-you-do-chip-enabled", false};
47
48constexpr base::FeatureParam<bool> kWhatsOnMyCalendarChipEnabled{
49 &kConversationStartersFeature, "whats-on-my-calendar-chip-enabled", false};
50
51constexpr base::FeatureParam<bool> kWhatsOnMyScreenChipEnabled{
52 &kConversationStartersFeature, "whats-on-my-screen-chip-enabled", false};
53
54constexpr base::FeatureParam<bool> kWhatsTheWeatherChipEnabled{
55 &kConversationStartersFeature, "whats-the-weather-chip-enabled", false};
56
57constexpr int kMaxNumOfConversationStarters = 3;
David Black02974f82018-08-21 22:56:0558
59} // namespace
60
David Black5a1c68932018-08-29 20:11:4361// AssistantCacheController ----------------------------------------------------
62
David Black02974f82018-08-21 22:56:0563AssistantCacheController::AssistantCacheController(
64 AssistantController* assistant_controller)
65 : assistant_controller_(assistant_controller),
66 voice_interaction_binding_(this) {
David Black6b4b1ad22018-08-21 02:45:0867 UpdateConversationStarters();
68
David Black02974f82018-08-21 22:56:0569 assistant_controller_->AddObserver(this);
70
David Black6b4b1ad22018-08-21 02:45:0871 // Bind to observe changes to screen context preference.
72 mojom::VoiceInteractionObserverPtr ptr;
73 voice_interaction_binding_.Bind(mojo::MakeRequest(&ptr));
74 Shell::Get()->voice_interaction_controller()->AddObserver(std::move(ptr));
75}
76
David Black02974f82018-08-21 22:56:0577AssistantCacheController::~AssistantCacheController() {
78 assistant_controller_->RemoveObserver(this);
79}
David Black6b4b1ad22018-08-21 02:45:0880
81void AssistantCacheController::AddModelObserver(
82 AssistantCacheModelObserver* observer) {
83 model_.AddObserver(observer);
84}
85
86void AssistantCacheController::RemoveModelObserver(
87 AssistantCacheModelObserver* observer) {
88 model_.RemoveObserver(observer);
89}
90
David Black02974f82018-08-21 22:56:0591void AssistantCacheController::OnAssistantControllerConstructed() {
92 assistant_controller_->ui_controller()->AddModelObserver(this);
93}
94
95void AssistantCacheController::OnAssistantControllerDestroying() {
96 assistant_controller_->ui_controller()->RemoveModelObserver(this);
97}
98
David Black4c6b9e22018-08-27 20:31:3199void AssistantCacheController::OnUiVisibilityChanged(
100 AssistantVisibility new_visibility,
101 AssistantVisibility old_visibility,
102 AssistantSource source) {
103 // When Assistant is finishing a session, we update our cache of conversation
104 // starters so that they're fresh for the next launch.
105 if (assistant::util::IsFinishingSession(new_visibility))
David Black02974f82018-08-21 22:56:05106 UpdateConversationStarters();
107}
108
David Black6b4b1ad22018-08-21 02:45:08109void AssistantCacheController::OnVoiceInteractionContextEnabled(bool enabled) {
110 UpdateConversationStarters();
111}
112
113// TODO(dmblack): The conversation starter cache should receive its contents
114// from the server. Hard-coding for the time being.
115void AssistantCacheController::UpdateConversationStarters() {
David Black5a1c68932018-08-29 20:11:43116 if (!base::FeatureList::IsEnabled(kConversationStartersFeature))
117 return;
118
David Black6b4b1ad22018-08-21 02:45:08119 using namespace chromeos::assistant::mojom;
120
121 std::vector<AssistantSuggestionPtr> conversation_starters;
122
David Blackd08c0512018-08-21 17:18:26123 auto AddConversationStarter = [&conversation_starters](
124 int message_id, GURL action_url = GURL()) {
David Black6b4b1ad22018-08-21 02:45:08125 AssistantSuggestionPtr starter = AssistantSuggestion::New();
126 starter->text = l10n_util::GetStringUTF8(message_id);
David Blackd08c0512018-08-21 17:18:26127 starter->action_url = action_url;
David Black6b4b1ad22018-08-21 02:45:08128 conversation_starters.push_back(std::move(starter));
129 };
130
David Black5a1c68932018-08-29 20:11:43131 // If enabled, always show the "What can you do?" conversation starter.
132 if (kWhatCanYouDoChipEnabled.Get())
133 AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHAT_CAN_YOU_DO);
David Black6b4b1ad22018-08-21 02:45:08134
David Black5a1c68932018-08-29 20:11:43135 // If enabled, always show the "What's on my screen?" conversation starter.
136 if (kWhatsOnMyScreenChipEnabled.Get() &&
137 Shell::Get()->voice_interaction_controller()->context_enabled()) {
David Blackd08c0512018-08-21 17:18:26138 AddConversationStarter(IDS_ASH_ASSISTANT_CHIP_WHATS_ON_MY_SCREEN,
139 assistant::util::CreateWhatsOnMyScreenDeepLink());
140 }
David Black6b4b1ad22018-08-21 02:45:08141
David Black02974f82018-08-21 22:56:05142 // The rest of the conversation starters will be shuffled...
David Black5a1c68932018-08-29 20:11:43143 std::vector<int> shuffled_message_ids;
David Black6b4b1ad22018-08-21 02:45:08144
David Black5a1c68932018-08-29 20:11:43145 if (kImBoredChipEnabled.Get())
146 shuffled_message_ids.push_back(IDS_ASH_ASSISTANT_CHIP_IM_BORED);
David Black02974f82018-08-21 22:56:05147
David Black5a1c68932018-08-29 20:11:43148 if (kOpenFilesChipEnabled.Get())
149 shuffled_message_ids.push_back(IDS_ASH_ASSISTANT_CHIP_OPEN_FILES);
150
151 if (kPlayMusicChipEnabled.Get())
152 shuffled_message_ids.push_back(IDS_ASH_ASSISTANT_CHIP_PLAY_MUSIC);
153
154 if (kSendAnEmailChipEnabled.Get())
155 shuffled_message_ids.push_back(IDS_ASH_ASSISTANT_CHIP_SEND_AN_EMAIL);
156
157 if (kSetAReminderChipEnabled.Get())
158 shuffled_message_ids.push_back(IDS_ASH_ASSISTANT_CHIP_SET_A_REMINDER);
159
160 if (kWhatsOnMyCalendarChipEnabled.Get())
161 shuffled_message_ids.push_back(IDS_ASH_ASSISTANT_CHIP_WHATS_ON_MY_CALENDAR);
162
163 if (kWhatsTheWeatherChipEnabled.Get())
164 shuffled_message_ids.push_back(IDS_ASH_ASSISTANT_CHIP_WHATS_THE_WEATHER);
165
166 base::RandomShuffle(shuffled_message_ids.begin(), shuffled_message_ids.end());
167
168 // ...and added until we have no more than |kMaxNumOfConversationStarters|.
169 for (int i = 0;
170 conversation_starters.size() < kMaxNumOfConversationStarters &&
171 i < static_cast<int>(shuffled_message_ids.size());
David Black02974f82018-08-21 22:56:05172 ++i) {
173 AddConversationStarter(shuffled_message_ids[i]);
174 }
David Black6b4b1ad22018-08-21 02:45:08175
176 model_.SetConversationStarters(std::move(conversation_starters));
177}
178
179} // namespace ash