chromium/ash/assistant/assistant_view_delegate_impl.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/assistant/assistant_view_delegate_impl.h"

#include <utility>

#include "ash/assistant/assistant_controller_impl.h"
#include "ash/assistant/assistant_notification_controller_impl.h"
#include "ash/assistant/model/assistant_interaction_model.h"
#include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "ash/assistant/model/assistant_notification_model.h"
#include "ash/assistant/model/assistant_notification_model_observer.h"
#include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/public/cpp/assistant/assistant_state_base.h"
#include "ash/public/cpp/session/session_types.h"
#include "ash/public/cpp/session/user_info.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "base/command_line.h"
#include "chromeos/ash/services/assistant/public/cpp/features.h"
#include "chromeos/ash/services/assistant/public/cpp/switches.h"
#include "ui/display/screen.h"

namespace ash {

namespace {

using assistant::ui::kOnboardingMaxSessionsShown;

}  // namespace

AssistantViewDelegateImpl::AssistantViewDelegateImpl(
    AssistantControllerImpl* assistant_controller)
    : assistant_controller_(assistant_controller) {}

AssistantViewDelegateImpl::~AssistantViewDelegateImpl() = default;

const AssistantNotificationModel*
AssistantViewDelegateImpl::GetNotificationModel() const {
  return assistant_controller_->notification_controller()->model();
}

void AssistantViewDelegateImpl::AddObserver(
    AssistantViewDelegateObserver* observer) {
  view_delegate_observers_.AddObserver(observer);
}

void AssistantViewDelegateImpl::RemoveObserver(
    AssistantViewDelegateObserver* observer) {
  view_delegate_observers_.RemoveObserver(observer);
}

void AssistantViewDelegateImpl::DownloadImage(
    const GURL& url,
    ImageDownloader::DownloadCallback callback) {
  assistant_controller_->DownloadImage(url, std::move(callback));
}

::wm::CursorManager* AssistantViewDelegateImpl::GetCursorManager() {
  return Shell::Get()->cursor_manager();
}

std::string AssistantViewDelegateImpl::GetPrimaryUserGivenName() const {
  return Shell::Get()
      ->session_controller()
      ->GetPrimaryUserSession()
      ->user_info.given_name;
}

aura::Window* AssistantViewDelegateImpl::GetRootWindowForDisplayId(
    int64_t display_id) {
  return Shell::Get()->GetRootWindowForDisplayId(display_id);
}

aura::Window* AssistantViewDelegateImpl::GetRootWindowForNewWindows() {
  return Shell::Get()->GetRootWindowForNewWindows();
}

bool AssistantViewDelegateImpl::IsTabletMode() const {
  return display::Screen::GetScreen()->InTabletMode();
}

void AssistantViewDelegateImpl::OnDialogPlateButtonPressed(
    AssistantButtonId id) {
  for (auto& observer : view_delegate_observers_)
    observer.OnDialogPlateButtonPressed(id);
}

void AssistantViewDelegateImpl::OnDialogPlateContentsCommitted(
    const std::string& text) {
  for (auto& observer : view_delegate_observers_)
    observer.OnDialogPlateContentsCommitted(text);
}

void AssistantViewDelegateImpl::OnNotificationButtonPressed(
    const std::string& notification_id,
    int notification_button_index) {
  assistant_controller_->notification_controller()->OnNotificationClicked(
      notification_id, notification_button_index, /*reply=*/std::nullopt);
}

void AssistantViewDelegateImpl::OnOnboardingShown() {
  for (auto& observer : view_delegate_observers_)
    observer.OnOnboardingShown();
}

void AssistantViewDelegateImpl::OnOptInButtonPressed() {
  for (auto& observer : view_delegate_observers_)
    observer.OnOptInButtonPressed();
}

void AssistantViewDelegateImpl::OnSuggestionPressed(
    const base::UnguessableToken& suggestion_id) {
  for (AssistantViewDelegateObserver& observer : view_delegate_observers_)
    observer.OnSuggestionPressed(suggestion_id);
}

bool AssistantViewDelegateImpl::ShouldShowOnboarding() const {
  // UI developers need to be able to force the onboarding flow.
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          assistant::switches::kForceAssistantOnboarding)) {
    return true;
  }

  if (!assistant::features::IsOnboardingEnabled()) {
    return false;
  }

  // Once a user has had an interaction with Assistant, we will no longer show
  // onboarding in that user session.
  auto* interaction_controller = AssistantInteractionController::Get();
  const bool has_had_interaction = interaction_controller->HasHadInteraction();
  if (has_had_interaction)
    return false;

  // If we do show onboarding to a user in a session, we will keep showing it
  // for that session until an Assistant interaction takes place.
  auto* ui_controller = AssistantUiController::Get();
  const bool has_shown_onboarding = ui_controller->HasShownOnboarding();
  if (has_shown_onboarding)
    return true;

  // Once a user has seen onboarding in any session, they will continue to see
  // onboarding each session until the maximum number of sessions is reached.
  const int number_of_sessions_where_onboarding_shown =
      ui_controller->GetNumberOfSessionsWhereOnboardingShown();
  if (number_of_sessions_where_onboarding_shown > 0) {
    return number_of_sessions_where_onboarding_shown <
           kOnboardingMaxSessionsShown;
  }

  // The feature will start to show only for new users which we define as users
  // who haven't had an interaction with Assistant in the last 28 days.
  return interaction_controller->GetTimeDeltaSinceLastInteraction() >=
         base::Days(28);
}

void AssistantViewDelegateImpl::OnLauncherSearchChipPressed(
    const std::u16string& query) {
  for (auto& observer : view_delegate_observers_) {
    observer.OnLauncherSearchChipPressed(query);
  }
}

}  // namespace ash