1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_MAHI_MAHI_MANAGER_IMPL_H_
#define CHROME_BROWSER_ASH_MAHI_MAHI_MANAGER_IMPL_H_
#include <memory>
#include <string>
#include "ash/system/mahi/mahi_ui_controller.h"
#include "base/memory/raw_ptr.h"
#include "base/unguessable_token.h"
#include "chrome/browser/ash/mahi/mahi_cache_manager.h"
#include "chromeos/components/magic_boost/public/cpp/magic_boost_state.h"
#include "chromeos/components/mahi/public/cpp/mahi_manager.h"
#include "chromeos/components/mahi/public/cpp/mahi_web_contents_manager.h"
#include "chromeos/crosapi/mojom/mahi.mojom-forward.h"
#include "chromeos/crosapi/mojom/mahi.mojom.h"
#include "components/history/core/browser/history_service.h"
#include "components/history/core/browser/history_service_observer.h"
#include "components/manta/mahi_provider.h"
#include "ui/gfx/image/image_skia.h"
namespace gfx {
class Rect;
} // namespace gfx
namespace ash {
class MahiNudgeController;
// Implementation of `MahiManager`.
class MahiManagerImpl : public chromeos::MahiManager,
public chromeos::MagicBoostState::Observer,
public history::HistoryServiceObserver {
public:
MahiManagerImpl();
MahiManagerImpl(const MahiManagerImpl&) = delete;
MahiManagerImpl& operator=(const MahiManagerImpl&) = delete;
~MahiManagerImpl() override;
// chromeos::MahiManager:
std::u16string GetContentTitle() override;
gfx::ImageSkia GetContentIcon() override;
GURL GetContentUrl() override;
std::u16string GetSelectedText() override;
void GetContent(MahiContentCallback callback) override;
void GetSummary(MahiSummaryCallback callback) override;
void GetElucidation(MahiElucidationCallback callback) override;
void GetOutlines(MahiOutlinesCallback callback) override;
void GoToOutlineContent(int outline_id) override;
void AnswerQuestion(const std::u16string& question,
bool current_panel_content,
MahiAnswerQuestionCallback callback) override;
void AnswerQuestionRepeating(
const std::u16string& question,
bool current_panel_content,
MahiAnswerQuestionCallbackRepeating callback) override;
void GetSuggestedQuestion(MahiGetSuggestedQuestionCallback callback) override;
void SetCurrentFocusedPageInfo(crosapi::mojom::MahiPageInfoPtr info) override;
void OnContextMenuClicked(
crosapi::mojom::MahiContextMenuRequestPtr context_menu_request) override;
void OpenFeedbackDialog() override;
void OpenMahiPanel(int64_t display_id,
const gfx::Rect& mahi_menu_bounds) override;
bool IsEnabled() override;
void SetMediaAppPDFFocused() override;
void MediaAppPDFClosed(
const base::UnguessableToken media_app_client_id) override;
std::optional<base::UnguessableToken> GetMediaAppPDFClientId() const override;
void ClearCache() override;
bool AllowRepeatingAnswers() override;
// Called when availability for a refresh changes based on the shown content.
void NotifyRefreshAvailability(bool available);
MahiUiController* ui_controller_for_test() { return &ui_controller_; }
// history::HistoryServiceObserver:
void OnHistoryDeletions(history::HistoryService* history_service,
const history::DeletionInfo& deletion_info) override;
private:
friend class MahiManagerImplTest;
friend class MahiManagerImplFeatureKeyTest;
// chromeos::MagicBoostState::Observer:
void OnHMREnabledUpdated(bool enabled) override;
void OnIsDeleting() override;
// Interrupts the flow of `context_menu_request` handling by showing a
// disclaimer view. The original flow will be resumed if the consent status
// becomes approved. NOTE: This function should be called only if the magic
// boost feature is enabled.
void InterrputRequestHandlingWithDisclaimerView(
crosapi::mojom::MahiContextMenuRequestPtr context_menu_request);
// Initialize required provider if it is not initialized yet, and discard
// pending requests to avoid racing condition.
// Returns true if successfully initialized.
bool MaybeInitializeAndDiscardPendingRequests();
void MaybeObserveHistoryService();
void OpenMahiPanelForElucidation(int64_t display_id,
const gfx::Rect& mahi_menu_bounds);
void OnGetPageContent(crosapi::mojom::MahiPageInfoPtr request_page_info,
MahiContentCallback callback,
crosapi::mojom::MahiPageContentPtr mahi_content_ptr);
void OnGetPageContentForSummary(
crosapi::mojom::MahiPageInfoPtr request_page_info,
MahiSummaryCallback callback,
crosapi::mojom::MahiPageContentPtr mahi_content_ptr);
void OnGetPageContentForElucidation(
const std::u16string& selected_text,
crosapi::mojom::MahiPageInfoPtr request_page_info,
MahiElucidationCallback callback,
crosapi::mojom::MahiPageContentPtr mahi_content_ptr);
void OnGetPageContentForQA(
crosapi::mojom::MahiPageInfoPtr request_page_info,
const std::u16string& question,
MahiAnswerQuestionCallback callback,
crosapi::mojom::MahiPageContentPtr mahi_content_ptr);
void OnMahiProviderSummaryResponse(
crosapi::mojom::MahiPageInfoPtr request_page_info,
MahiSummaryCallback summary_callback,
base::Value::Dict dict,
manta::MantaStatus status);
void OnMahiProviderElucidationResponse(
crosapi::mojom::MahiPageInfoPtr request_page_info,
const std::u16string& selected_text,
MahiElucidationCallback elucidation_callback,
base::Value::Dict dict,
manta::MantaStatus status);
void OnMahiProviderQAResponse(
crosapi::mojom::MahiPageInfoPtr request_page_info,
const std::u16string& question,
MahiAnswerQuestionCallback callback,
base::Value::Dict dict,
manta::MantaStatus status);
void CacheCurrentPanelContent(crosapi::mojom::MahiPageInfo request_page_info,
crosapi::mojom::MahiPageContent mahi_content);
// Updates `current_selected_text_` from web contents manager or media app
// content manager.
void UpdateCurrentSelectedText();
base::ScopedObservation<chromeos::MagicBoostState,
chromeos::MagicBoostState::Observer>
magic_boost_state_observation_{this};
// These `Ptr`s should never be null. To invalidate them, assign them a
// `New()` instead of calling `reset()`.
crosapi::mojom::MahiPageInfoPtr current_page_info_ =
crosapi::mojom::MahiPageInfo::New();
crosapi::mojom::MahiPageContentPtr current_panel_content_ =
crosapi::mojom::MahiPageContent::New();
// Stores metadata of the current content in the panel.
crosapi::mojom::MahiPageInfoPtr current_panel_info_ =
crosapi::mojom::MahiPageInfo::New();
// Stores current selected text when the user triggers feature that works for
// selected text, e.g. Elucidation, or Summary for selection.
// Unlike `current_page_info_` that may change when the user activates another
// browser tab, therefore we need `current_panel_info_` to keep track of the
// page info used by the existing result panel for future interactions
// launched from the panel (e.g. QA), `current_selected_text_` is only updated
// when user explicitly triggers Mahi functions from the widget, therefore it
// is always the source of truth if an existing result panel is based on user
// selected text.
// That's to say, if `current_selected_text_` is not nullopt, the existing
// result panel must be based on it. We rely on this fact for a few checks.
std::optional<std::u16string> current_selected_text_;
// Pair of question and their corresponding answer for the current panel
// content
std::vector<std::pair<std::string, std::string>> current_panel_qa_;
std::unique_ptr<manta::MahiProvider> mahi_provider_;
raw_ptr<chromeos::MahiWebContentsManager> mahi_web_contents_manager_ =
nullptr;
// Keeps track of the latest result and code, used for feedback.
std::u16string latest_summary_;
std::u16string latest_elucidation_;
chromeos::MahiResponseStatus latest_response_status_;
MahiUiController ui_controller_;
std::unique_ptr<MahiCacheManager> cache_manager_;
std::unique_ptr<MahiNudgeController> mahi_nudge_controller_;
// If true, tries to get content from MediaAppContentManager instead.
bool media_app_pdf_focused_ = false;
base::UnguessableToken media_app_client_id_;
// Runs the specified closures when the consent state becomes approved or
// declined. Built when handling particular context menu actions without the
// Mahi feature approved by user. Destroyed when user responds to the
// disclaimer view.
// NOTE: It is used only when the magic boost feature is enabled.
std::unique_ptr<chromeos::MagicBoostState::Observer>
on_consent_state_update_closure_runner_;
base::ScopedObservation<history::HistoryService,
history::HistoryServiceObserver>
scoped_history_service_observer_{this};
base::WeakPtrFactory<MahiManagerImpl> weak_ptr_factory_for_closure_runner_{
this};
base::WeakPtrFactory<MahiManagerImpl> weak_ptr_factory_for_requests_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_MAHI_MAHI_MANAGER_IMPL_H_
|