0

Create annotator controller

This controller is responsible for communicating with annotator browser client and will handle all ash UI logic related to annotations. So far only SetAnnotatorTool and ResetTools methods are moved to the AnnotatorController, to keep the CL small. In the future, we will move all annotator related methods from ProjectorUiController.

In this CL we also delete duplicate interface AnnotatorToolController, as there is the AnnotatorClient interface which exposes same methods.

NO_METRICS_CHANGED

Bug: 342104047
Change-Id: Id6413346fb8343e932d425352ccd2bfa22ff18b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5598530
Reviewed-by: Ahmed Fakhry <afakhry@chromium.org>
Commit-Queue: Sanja Perisic <sanjaperisic@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1316538}
This commit is contained in:
Sanja Perisic
2024-06-18 17:13:55 +00:00
committed by Chromium LUCI CQ
parent 85e02b9f25
commit b3c3735612
36 changed files with 346 additions and 223 deletions

@ -295,6 +295,10 @@ component("ash") {
"ambient/util/time_of_day_utils.cc",
"ambient/util/time_of_day_utils.h",
"animation/animation_change_type.h",
"annotator/annotator_controller.cc",
"annotator/annotator_controller.h",
"annotator/annotator_metrics.cc",
"annotator/annotator_metrics.h",
"api/tasks/tasks_client.h",
"api/tasks/tasks_controller.cc",
"api/tasks/tasks_controller.h",
@ -3194,6 +3198,7 @@ component("ash") {
"//ash/style",
"//ash/system/mahi/resources:mahi_resources_grit",
"//ash/system/video_conference/resources:vc_resources_grit",
"//ash/webui/annotator/public/cpp",
"//ash/webui/common/mojom:sea_pen",
"//ash/webui/diagnostics_ui/mojom:mojom",
"//ash/webui/eche_app_ui:eche_connection_status",
@ -3565,6 +3570,7 @@ test("ash_unittests") {
"ambient/ui/photo_view_unittest.cc",
"ambient/util/ambient_util_unittest.cc",
"ambient/util/time_of_day_utils_unittest.cc",
"annotator/annotator_controller_unittest.cc",
"app_menu/app_menu_model_adapter_unittest.cc",
"app_menu/notification_menu_controller_unittest.cc",
"app_menu/notification_menu_view_unittest.cc",
@ -5070,6 +5076,7 @@ static_library("test_support") {
public_deps = [
"//ash",
"//ash/webui/annotator:test_support",
"//chromeos/ash/components/multidevice:test_support",
"//chromeos/ash/services/assistant/public/mojom",
"//chromeos/ash/services/network_config/public/cpp:test_support",

@ -0,0 +1,51 @@
// 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.
#include "ash/annotator/annotator_controller.h"
#include "ash/annotator/annotator_metrics.h"
#include "ash/projector/projector_annotation_tray.h"
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/webui/annotator/public/cpp/annotator_client.h"
#include "base/check.h"
namespace ash {
namespace {
AnnotatorMarkerColor GetMarkerColorForMetrics(SkColor color) {
// TODO(b/342104047): Rename colors to remove projector from the name.
switch (color) {
case kProjectorMagentaPenColor:
return AnnotatorMarkerColor::kMagenta;
case kProjectorBluePenColor:
return AnnotatorMarkerColor::kBlue;
case kProjectorRedPenColor:
return AnnotatorMarkerColor::kRed;
case kProjectorYellowPenColor:
return AnnotatorMarkerColor::kYellow;
}
return AnnotatorMarkerColor::kMaxValue;
}
} // namespace
AnnotatorController::AnnotatorController() = default;
AnnotatorController::~AnnotatorController() {
client_ = nullptr;
}
void AnnotatorController::SetAnnotatorTool(const AnnotatorTool& tool) {
DCHECK(client_);
client_->SetTool(tool);
RecordMarkerColorMetrics(GetMarkerColorForMetrics(tool.color));
}
void AnnotatorController::ResetTools() {
DCHECK(client_);
client_->Clear();
}
void AnnotatorController::SetToolClient(AnnotatorClient* client) {
client_ = client;
}
} // namespace ash

@ -0,0 +1,39 @@
// 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 ASH_ANNOTATOR_ANNOTATOR_CONTROLLER_H_
#define ASH_ANNOTATOR_ANNOTATOR_CONTROLLER_H_
#include "ash/annotator/annotator_metrics.h"
#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "third_party/skia/include/core/SkColor.h"
namespace ash {
struct AnnotatorTool;
class AnnotatorClient;
// The controller in charge of annotator UI.
class ASH_EXPORT AnnotatorController {
public:
AnnotatorController();
AnnotatorController(const AnnotatorController&) = delete;
AnnotatorController& operator=(const AnnotatorController&) = delete;
virtual ~AnnotatorController();
// Sets the annotator tool.
virtual void SetAnnotatorTool(const AnnotatorTool& tool);
// Resets annotator tools and clears the canvas.
void ResetTools();
// Sets browser client.
void SetToolClient(AnnotatorClient* client);
private:
raw_ptr<AnnotatorClient> client_ = nullptr;
};
} // namespace ash
#endif // ASH_ANNOTATOR_ANNOTATOR_CONTROLLER_H_

@ -0,0 +1,67 @@
// 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.
#include "ash/annotator/annotator_controller.h"
#include "ash/annotator/annotator_metrics.h"
#include "ash/projector/projector_annotation_tray.h"
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/webui/annotator/test/mock_annotator_client.h"
#include "base/test/metrics/histogram_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ash {
namespace {
constexpr char kAnnotatorMarkerColorHistogramName[] =
"Ash.Projector.MarkerColor.ClamshellMode";
} // namespace
class AnnotatorControllerTest : public AshTestBase {
public:
AnnotatorControllerTest() = default;
AnnotatorControllerTest(const AnnotatorControllerTest&) = delete;
AnnotatorControllerTest& operator=(const AnnotatorControllerTest&) = delete;
// AshTestBase:
void SetUp() override {
AshTestBase::SetUp();
auto* annotator_controller = Shell::Get()->annotator_controller();
annotator_controller->SetToolClient(&client_);
}
AnnotatorController* annotator_controller() {
return Shell::Get()->annotator_controller();
}
protected:
MockAnnotatorClient client_;
};
TEST_F(AnnotatorControllerTest, SetAnnotatorTool) {
base::HistogramTester histogram_tester;
AnnotatorTool tool;
tool.color = kProjectorDefaultPenColor;
EXPECT_CALL(client_, SetTool(tool));
annotator_controller()->SetAnnotatorTool(tool);
histogram_tester.ExpectUniqueSample(kAnnotatorMarkerColorHistogramName,
AnnotatorMarkerColor::kMagenta,
/*count=*/1);
}
TEST_F(AnnotatorControllerTest, ResetTools) {
EXPECT_CALL(client_, Clear());
annotator_controller()->ResetTools();
}
} // namespace ash

@ -0,0 +1,32 @@
// 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.
#include "ash/annotator/annotator_metrics.h"
#include "ash/shell.h"
#include "base/metrics/histogram_functions.h"
namespace ash {
namespace {
constexpr char kAnnotatorMarkerColorHistogramName[] =
"Ash.Projector.MarkerColor";
// Appends the proper suffix to |prefix| based on whether the user is in tablet
// mode or not.
std::string GetHistogramName(const std::string& prefix) {
std::string mode =
Shell::Get()->IsInTabletMode() ? ".TabletMode" : ".ClamshellMode";
return prefix + mode;
}
} // namespace
void RecordMarkerColorMetrics(AnnotatorMarkerColor color) {
base::UmaHistogramEnumeration(
GetHistogramName(kAnnotatorMarkerColorHistogramName), color);
}
} // namespace ash

@ -0,0 +1,34 @@
// 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 ASH_ANNOTATOR_ANNOTATOR_METRICS_H_
#define ASH_ANNOTATOR_ANNOTATOR_METRICS_H_
namespace ash {
// These enum values represent marker colors on the annotator toolbar and log to
// UMA. Entries should not be renumbered and numeric values should never be
// reused. Please keep in sync with "ProjectorMarkerColor" in
// src/tools/metrics/histograms/metadata/ash/enums.xml.
enum class AnnotatorMarkerColor {
// kBlack = 0,
// kWhite = 1,
kBlue = 2,
kRed = 3,
kYellow = 4,
kMagenta = 5,
// Add future entries above this comment, in sync with
// "ProjectorMarkerColor" in
// src/tools/metrics/histograms/metadata/ash/enums.xml.
// Update kMaxValue to the last value.
kMaxValue = kMagenta
};
// Records the marker colors the user chooses to use. Only records if the user
// switches from the default color.
void RecordMarkerColorMetrics(AnnotatorMarkerColor color);
} // namespace ash
#endif // ASH_ANNOTATOR_ANNOTATOR_METRICS_H_

@ -7,6 +7,7 @@
#include "ash/accessibility/a11y_feature_type.h"
#include "ash/accessibility/accessibility_controller.h"
#include "ash/accessibility/autoclick/autoclick_controller.h"
#include "ash/annotator/annotator_controller.h"
#include "ash/capture_mode/capture_mode_bar_view.h"
#include "ash/capture_mode/capture_mode_controller.h"
#include "ash/capture_mode/capture_mode_session.h"
@ -395,6 +396,8 @@ ProjectorCaptureModeIntegrationHelper::ProjectorCaptureModeIntegrationHelper() =
void ProjectorCaptureModeIntegrationHelper::SetUp() {
auto* projector_controller = ProjectorController::Get();
projector_controller->SetClient(&projector_client_);
auto* annotator_controller = Shell::Get()->annotator_controller();
annotator_controller->SetToolClient(&annotator_client_);
ON_CALL(projector_client_, StopSpeechRecognition)
.WillByDefault(testing::Invoke([]() {
ProjectorController::Get()->OnSpeechRecognitionStopped(

@ -13,6 +13,7 @@
#include "ash/capture_mode/test_capture_mode_delegate.h"
#include "ash/capture_mode/user_nudge_controller.h"
#include "ash/public/cpp/test/mock_projector_client.h"
#include "ash/webui/annotator/test/mock_annotator_client.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "ui/events/event_constants.h"
@ -191,6 +192,7 @@ class ProjectorCaptureModeIntegrationHelper {
private:
MockProjectorClient projector_client_;
MockAnnotatorClient annotator_client_;
};
// Defines a waiter to observe the visibility change of the view.

@ -6,6 +6,7 @@
#include <vector>
#include "ash/annotator/annotator_controller.h"
#include "ash/capture_mode/capture_mode_controller.h"
#include "ash/capture_mode/capture_mode_metrics.h"
#include "ash/constants/ash_pref_names.h"
@ -376,13 +377,13 @@ void ProjectorControllerImpl::EnableAnnotatorTool() {
}
void ProjectorControllerImpl::SetAnnotatorTool(const AnnotatorTool& tool) {
DCHECK(ui_controller_);
ui_controller_->SetAnnotatorTool(tool);
DCHECK(Shell::Get()->annotator_controller());
Shell::Get()->annotator_controller()->SetAnnotatorTool(tool);
}
void ProjectorControllerImpl::ResetTools() {
if (ui_controller_) {
ui_controller_->ResetTools();
ui_controller_->ResetCanvas();
}
}

@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/projector/projector_controller_impl.h"
#include <initializer_list>
#include <memory>
#include <string>
#include <vector>
#include "ash/annotator/annotator_controller.h"
#include "ash/constants/ash_features.h"
#include "ash/projector/model/projector_session_impl.h"
#include "ash/projector/projector_controller_impl.h"
#include "ash/projector/projector_metadata_controller.h"
#include "ash/projector/projector_metrics.h"
#include "ash/projector/test/mock_projector_metadata_controller.h"
@ -20,6 +20,7 @@
#include "ash/public/cpp/test/mock_projector_client.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/webui/annotator/test/mock_annotator_client.h"
#include "ash/webui/projector_app/public/cpp/projector_app_constants.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
@ -156,6 +157,9 @@ class ProjectorControllerTest : public AshTestBase {
ON_CALL(mock_client_, GetSpeechRecognitionAvailability)
.WillByDefault(testing::Return(availability));
controller_->SetClient(&mock_client_);
auto* annotator_controller = Shell::Get()->annotator_controller();
annotator_controller->SetToolClient(&mock_annotator_client_);
}
void InitializeRealMetadataController() {
@ -196,6 +200,7 @@ class ProjectorControllerTest : public AshTestBase {
metadata_controller_;
raw_ptr<ProjectorControllerImpl, DanglingUntriaged> controller_;
MockProjectorClient mock_client_;
MockAnnotatorClient mock_annotator_client_;
base::HistogramTester histogram_tester_;
base::ScopedTempDir temp_dir_;
base::test::ScopedFeatureList scoped_feature_list_;
@ -286,8 +291,8 @@ TEST_F(ProjectorControllerTest, EnableAnnotatorTool) {
TEST_F(ProjectorControllerTest, SetAnnotatorTool) {
AnnotatorTool tool;
// Verify that |SetAnnotatorTool| in |ProjectorUiController| is called.
EXPECT_CALL(*mock_ui_controller_, SetAnnotatorTool(tool));
// Verify that |SetTool| in |AnnotatorClient| is called.
EXPECT_CALL(mock_annotator_client_, SetTool(tool));
controller_->SetAnnotatorTool(tool);
}

@ -16,9 +16,6 @@ namespace {
constexpr char kProjectorToolbarHistogramName[] = "Ash.Projector.Toolbar";
constexpr char kProjectorMarkerColorHistogramName[] =
"Ash.Projector.MarkerColor";
constexpr char kProjectorCreationFlowHistogramName[] =
"Ash.Projector.CreationFlow";
@ -64,11 +61,6 @@ void RecordToolbarMetrics(ProjectorToolbar button) {
GetHistogramName(kProjectorToolbarHistogramName), button);
}
void RecordMarkerColorMetrics(ProjectorMarkerColor color) {
base::UmaHistogramEnumeration(
GetHistogramName(kProjectorMarkerColorHistogramName), color);
}
void RecordCreationFlowMetrics(ProjectorCreationFlow step) {
base::UmaHistogramEnumeration(
GetHistogramName(kProjectorCreationFlowHistogramName), step);

@ -47,24 +47,6 @@ enum class ProjectorToolbar {
kMaxValue = kMarkerTool
};
// These enum values represent marker colors on the Projector toolbar and log to
// UMA. Entries should not be renumbered and numeric values should never be
// reused. Please keep in sync with "ProjectorMarkerColor" in
// src/tools/metrics/histograms/metadata/ash/enums.xml.
enum class ProjectorMarkerColor {
// kBlack = 0,
// kWhite = 1,
kBlue = 2,
kRed = 3,
kYellow = 4,
kMagenta = 5,
// Add future entries above this comment, in sync with
// "ProjectorMarkerColor" in
// src/tools/metrics/histograms/metadata/ash/enums.xml.
// Update kMaxValue to the last value.
kMaxValue = kMagenta
};
// These enum values represent steps in the Projector creation flow and log to
// UMA. Entries should not be renumbered and numeric values should never be
// reused. Please keep in sync with "ProjectorCreationFlow" in
@ -141,10 +123,6 @@ enum class SpeechRecognitionEndState {
// Records the buttons the user presses on the Projector toolbar.
void RecordToolbarMetrics(ProjectorToolbar button);
// Records the marker colors the user chooses to use. Only records if the user
// switches from the default color.
void RecordMarkerColorMetrics(ProjectorMarkerColor color);
// Records the user's progress in the Projector creation flow.
void RecordCreationFlowMetrics(ProjectorCreationFlow step);

@ -5,14 +5,13 @@
#include "ash/projector/projector_ui_controller.h"
#include "ash/accessibility/caption_bubble_context_ash.h"
#include "ash/annotator/annotator_controller.h"
#include "ash/capture_mode/capture_mode_controller.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/notifier_catalogs.h"
#include "ash/projector/projector_annotation_tray.h"
#include "ash/projector/projector_controller_impl.h"
#include "ash/projector/projector_metrics.h"
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/public/cpp/annotator/annotator_tool_controller.h"
#include "ash/public/cpp/notification_utils.h"
#include "ash/public/cpp/projector/projector_client.h"
#include "ash/public/cpp/system/toast_data.h"
@ -160,7 +159,7 @@ void ProjectorUiController::ShowAnnotationTray(aura::Window* current_root) {
}
void ProjectorUiController::HideAnnotationTray() {
ResetTools();
ResetCanvas();
// Hide the tray icon.
if (auto* projector_annotation_tray =
GetProjectorAnnotationTrayForRoot(current_root_)) {
@ -179,16 +178,11 @@ void ProjectorUiController::EnableAnnotatorTool() {
}
}
void ProjectorUiController::SetAnnotatorTool(const AnnotatorTool& tool) {
ash::AnnotatorToolController::Get()->SetTool(tool);
RecordMarkerColorMetrics(GetMarkerColorForMetrics(tool.color));
}
void ProjectorUiController::ResetTools() {
void ProjectorUiController::ResetCanvas() {
if (annotator_enabled_) {
ToggleAnnotatorCanvas();
annotator_enabled_ = false;
ash::AnnotatorToolController::Get()->Clear();
Shell::Get()->annotator_controller()->ResetTools();
}
}
@ -224,17 +218,7 @@ void ProjectorUiController::OnRecordedWindowChangingRoot(
void ProjectorUiController::OnProjectorSessionActiveStateChanged(bool active) {
if (!active)
ResetTools();
}
ProjectorMarkerColor ProjectorUiController::GetMarkerColorForMetrics(
SkColor color) {
std::map<SkColor, ProjectorMarkerColor> marker_colors_map = {
{kProjectorMagentaPenColor, ProjectorMarkerColor::kMagenta},
{kProjectorBluePenColor, ProjectorMarkerColor::kBlue},
{kProjectorRedPenColor, ProjectorMarkerColor::kRed},
{kProjectorYellowPenColor, ProjectorMarkerColor::kYellow}};
return marker_colors_map[color];
ResetCanvas();
}
void ProjectorUiController::UpdateTrayEnabledState() {

@ -13,7 +13,6 @@
#include "ash/strings/grit/ash_strings.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "third_party/skia/include/core/SkColor.h"
namespace aura {
class Window;
@ -22,7 +21,6 @@ class Window;
namespace ash {
class ProjectorControllerImpl;
struct AnnotatorTool;
// The controller in charge of UI.
class ASH_EXPORT ProjectorUiController : public ProjectorSessionObserver {
@ -48,10 +46,8 @@ class ASH_EXPORT ProjectorUiController : public ProjectorSessionObserver {
virtual void HideAnnotationTray();
// Invoked when marker button is pressed. Virtual for testing.
virtual void EnableAnnotatorTool();
// Sets the annotator tool.
virtual void SetAnnotatorTool(const AnnotatorTool& tool);
// Resets and disables the annotator tools and clears the canvas.
void ResetTools();
// Resets the canvas.
void ResetCanvas();
// Invoked when the canvas has either succeeded or failed to initialize.
void OnCanvasInitialized(bool success);
// Returns if the annotation canvas has been initialized.
@ -67,8 +63,6 @@ class ASH_EXPORT ProjectorUiController : public ProjectorSessionObserver {
// ProjectorSessionObserver:
void OnProjectorSessionActiveStateChanged(bool active) override;
ProjectorMarkerColor GetMarkerColorForMetrics(SkColor color);
void UpdateTrayEnabledState();
bool annotator_enabled_ = false;

@ -7,6 +7,7 @@
#include <memory>
#include <string>
#include "ash/annotator/annotator_controller.h"
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/projector/projector_annotation_tray.h"
@ -19,6 +20,7 @@
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/tray/tray_container.h"
#include "ash/test/ash_test_base.h"
#include "ash/webui/annotator/test/mock_annotator_client.h"
#include "base/memory/raw_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/metrics/histogram_tester.h"
@ -41,8 +43,6 @@ namespace {
constexpr char kProjectorCreationFlowErrorHistogramName[] =
"Ash.Projector.CreationFlowError.ClamshellMode";
constexpr char kProjectorMarkerColorHistogramName[] =
"Ash.Projector.MarkerColor.ClamshellMode";
constexpr char kProjectorToolbarHistogramName[] =
"Ash.Projector.Toolbar.ClamshellMode";
@ -79,11 +79,15 @@ class ProjectorUiControllerTest : public AshTestBase {
auto* projector_controller = Shell::Get()->projector_controller();
projector_controller->SetClient(&projector_client_);
controller_ = projector_controller->ui_controller();
auto* annotator_controller = Shell::Get()->annotator_controller();
annotator_controller->SetToolClient(&annotator_client_);
}
protected:
raw_ptr<ProjectorUiController, DanglingUntriaged> controller_;
MockProjectorClient projector_client_;
MockAnnotatorClient annotator_client_;
};
TEST_F(ProjectorUiControllerTest, ShowAndHideTray) {
@ -152,8 +156,7 @@ TEST_F(ProjectorUiControllerTest, EnablingDisablingMarker) {
controller_->EnableAnnotatorTool();
EXPECT_TRUE(controller_->is_annotator_enabled());
EXPECT_CALL(projector_client_, Clear());
controller_->ResetTools();
controller_->ResetCanvas();
EXPECT_FALSE(controller_->is_annotator_enabled());
histogram_tester.ExpectUniqueSample(kProjectorToolbarHistogramName,
@ -177,11 +180,6 @@ TEST_F(ProjectorUiControllerTest, SetAnnotatorTool) {
auto* projector_annotation_tray = Shell::GetPrimaryRootWindowController()
->GetStatusAreaWidget()
->projector_annotation_tray();
base::HistogramTester histogram_tester;
AnnotatorTool tool;
tool.color = kProjectorDefaultPenColor;
EXPECT_CALL(projector_client_, SetTool(tool));
// Assert that the initial pref is unset.
PrefService* pref_service =
Shell::Get()->session_controller()->GetActivePrefService();
@ -206,9 +204,6 @@ TEST_F(ProjectorUiControllerTest, SetAnnotatorTool) {
EXPECT_EQ(
pref_service->GetUint64(prefs::kProjectorAnnotatorLastUsedMarkerColor),
kProjectorDefaultPenColor);
histogram_tester.ExpectUniqueSample(kProjectorMarkerColorHistogramName,
ProjectorMarkerColor::kMagenta,
/*count=*/1);
}
// Tests that right clicking the ProjectorAnnotationTray shows a bubble.

@ -42,8 +42,6 @@ component("cpp") {
"android_intent_helper.h",
"annotator/annotator_tool.cc",
"annotator/annotator_tool.h",
"annotator/annotator_tool_controller.cc",
"annotator/annotator_tool_controller.h",
"app_list/app_list_client.h",
"app_list/app_list_config.cc",
"app_list/app_list_config.h",

@ -1,34 +0,0 @@
// 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.
#include "ash/public/cpp/annotator/annotator_tool_controller.h"
#include "base/check.h"
#include "base/check_op.h"
namespace ash {
namespace {
AnnotatorToolController* g_instance = nullptr;
} // namespace
AnnotatorToolController::AnnotatorToolController() {
DCHECK(!g_instance);
g_instance = this;
}
AnnotatorToolController::~AnnotatorToolController() {
DCHECK_EQ(g_instance, this);
g_instance = nullptr;
}
// static
AnnotatorToolController* AnnotatorToolController::Get() {
DCHECK(g_instance);
return g_instance;
}
} // namespace ash

@ -1,41 +0,0 @@
// 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 ASH_PUBLIC_CPP_ANNOTATOR_ANNOTATOR_TOOL_CONTROLLER_H_
#define ASH_PUBLIC_CPP_ANNOTATOR_ANNOTATOR_TOOL_CONTROLLER_H_
#include "ash/public/cpp/ash_public_export.h"
namespace ash {
struct AnnotatorTool;
// This controller provides an interface to control the annotator tools.
class ASH_PUBLIC_EXPORT AnnotatorToolController {
public:
AnnotatorToolController();
AnnotatorToolController(const AnnotatorToolController&) = delete;
AnnotatorToolController& operator=(const AnnotatorToolController&) =
delete;
virtual ~AnnotatorToolController();
static AnnotatorToolController* Get();
// ProjectorController will use the following functions to manipulate the
// annotator.
// Sets the tool inside the annotator WebUI.
virtual void SetTool(const AnnotatorTool& tool) = 0;
// Undoes the last stroke in the annotator content.
virtual void Undo() = 0;
// Redoes the undone stroke in the annotator content.
virtual void Redo() = 0;
// Clears the contents of the annotator canvas.
virtual void Clear() = 0;
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_ANNOTATOR_ANNOTATOR_TOOL_CONTROLLER_H_

@ -5,8 +5,6 @@
#ifndef ASH_PUBLIC_CPP_TEST_MOCK_PROJECTOR_CLIENT_H_
#define ASH_PUBLIC_CPP_TEST_MOCK_PROJECTOR_CLIENT_H_
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/public/cpp/annotator/annotator_tool_controller.h"
#include "ash/public/cpp/projector/projector_client.h"
#include "ash/public/cpp/projector/projector_new_screencast_precondition.h"
#include "ash/public/cpp/projector/speech_recognition_availability.h"
@ -20,8 +18,7 @@ class FilePath;
namespace ash {
// A mock implementation of ProjectorClient for use in tests.
class MockProjectorClient : public ProjectorClient,
public AnnotatorToolController {
class MockProjectorClient : public ProjectorClient {
public:
MockProjectorClient();
MockProjectorClient(const MockProjectorClient&) = delete;
@ -45,12 +42,6 @@ class MockProjectorClient : public ProjectorClient,
MOCK_METHOD2(ToggleFileSyncingNotificationForPaths,
void(const std::vector<base::FilePath>&, bool));
// ProjectorAnnotatorController:
MOCK_METHOD1(SetTool, void(const AnnotatorTool&));
MOCK_METHOD0(Undo, void());
MOCK_METHOD0(Redo, void());
MOCK_METHOD0(Clear, void());
private:
base::ScopedTempDir screencast_container_path_;
};

@ -34,6 +34,7 @@
#include "ash/accessibility/sticky_keys/sticky_keys_controller.h"
#include "ash/accessibility/ui/accessibility_focus_ring_controller_impl.h"
#include "ash/ambient/ambient_controller.h"
#include "ash/annotator/annotator_controller.h"
#include "ash/api/tasks/tasks_controller.h"
#include "ash/api/tasks/tasks_delegate.h"
#include "ash/app_list/app_list_controller_impl.h"
@ -907,6 +908,7 @@ Shell::~Shell() {
// `game_dashboard_controller_` need to be destroyed before
// `capture_mode_controller_`.
projector_controller_.reset();
annotator_controller_.reset();
game_dashboard_controller_.reset();
// This must be called before `capture_mode_controller_` is destroyed. Note
@ -1773,6 +1775,7 @@ void Shell::Init(
shell_delegate_->CreateTasksDelegate());
}
annotator_controller_ = std::make_unique<AnnotatorController>();
projector_controller_ = std::make_unique<ProjectorControllerImpl>();
float_controller_ = std::make_unique<FloatController>();

@ -106,6 +106,7 @@ class AccessibilityFocusRingControllerImpl;
class AdaptiveChargingController;
class AmbientController;
class AnchoredNudgeManagerImpl;
class AnnotatorController;
class AppListControllerImpl;
class AppListFeatureUsageMetrics;
class AshAcceleratorConfiguration;
@ -839,6 +840,10 @@ class ASH_EXPORT Shell : public SessionObserver,
return projector_controller_.get();
}
AnnotatorController* annotator_controller() {
return annotator_controller_.get();
}
PciePeripheralNotificationController*
pcie_peripheral_notification_controller() {
return pcie_peripheral_notification_controller_.get();
@ -1246,6 +1251,8 @@ class ASH_EXPORT Shell : public SessionObserver,
std::unique_ptr<ProjectorControllerImpl> projector_controller_;
std::unique_ptr<AnnotatorController> annotator_controller_;
std::unique_ptr<AccessibilityEventHandlerManager>
accessibility_event_handler_manager_;

@ -9,8 +9,6 @@ assert(is_chromeos_ash, "Projector App is ash-chrome only")
static_library("annotator") {
sources = [
"annotator_client.cc",
"annotator_client.h",
"untrusted_annotator_page_handler_impl.cc",
"untrusted_annotator_page_handler_impl.h",
"untrusted_annotator_ui.cc",
@ -32,7 +30,10 @@ static_library("annotator") {
"//ui/webui",
]
public_deps = [ "//ash/webui/projector_app/public/cpp" ]
public_deps = [
"//ash/webui/annotator/public/cpp",
"//ash/webui/projector_app/public/cpp",
]
}
source_set("test_support") {
@ -45,10 +46,10 @@ source_set("test_support") {
]
public_deps = [
":annotator",
"//ash/public/cpp:cpp",
"//ash/public/cpp:test_support",
"//ash/webui/annotator/mojom:annotator_mojo_bindings",
"//ash/webui/annotator/public/cpp",
"//ash/webui/annotator/public/mojom:annotator_mojo_bindings",
"//base/test:test_support",
"//testing/gmock",
@ -60,6 +61,7 @@ source_set("unit_tests") {
sources = [ "test/untrusted_annotator_page_handler_impl_unittest.cc" ]
deps = [
":annotator",
":test_support",
"//ash/webui/annotator/mojom:annotator_mojo_bindings",
"//ash/webui/annotator/public/mojom:annotator_mojo_bindings",

@ -0,0 +1,15 @@
# 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.
import("//build/buildflag_header.gni")
import("//build/config/chromeos/ui_mode.gni")
assert(is_chromeos_ash, "Annotator is Chrome OS only")
source_set("cpp") {
sources = [
"annotator_client.cc",
"annotator_client.h",
]
deps = [ "//base:base" ]
}

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/webui/annotator/annotator_client.h"
#include "ash/webui/annotator/public/cpp/annotator_client.h"
#include "base/check_op.h"

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WEBUI_ANNOTATOR_ANNOTATOR_CLIENT_H_
#define ASH_WEBUI_ANNOTATOR_ANNOTATOR_CLIENT_H_
#ifndef ASH_WEBUI_ANNOTATOR_PUBLIC_CPP_ANNOTATOR_CLIENT_H_
#define ASH_WEBUI_ANNOTATOR_PUBLIC_CPP_ANNOTATOR_CLIENT_H_
namespace ash {
@ -42,4 +42,4 @@ class AnnotatorClient {
} // namespace ash
#endif // ASH_WEBUI_ANNOTATOR_ANNOTATOR_CLIENT_H_
#endif // ASH_WEBUI_ANNOTATOR_PUBLIC_CPP_ANNOTATOR_CLIENT_H_

@ -5,7 +5,7 @@
#ifndef ASH_WEBUI_ANNOTATOR_TEST_MOCK_ANNOTATOR_CLIENT_H_
#define ASH_WEBUI_ANNOTATOR_TEST_MOCK_ANNOTATOR_CLIENT_H_
#include "ash/webui/annotator/annotator_client.h"
#include "ash/webui/annotator/public/cpp/annotator_client.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace ash {

@ -8,8 +8,8 @@
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/public/cpp/projector/projector_controller.h"
#include "ash/webui/annotator/annotator_client.h"
#include "ash/webui/annotator/mojom/untrusted_annotator.mojom.h"
#include "ash/webui/annotator/public/cpp/annotator_client.h"
#include "ash/webui/annotator/public/mojom/annotator_structs.mojom.h"
#include "base/check.h"
#include "base/json/values_util.h"

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/webui/annotator/annotator_client.h"
#include "ash/webui/annotator/public/cpp/annotator_client.h"
#include "ash/webui/media_app_ui/test/media_app_ui_browsertest.h"
#include "ash/webui/projector_app/public/cpp/projector_app_constants.h"
#include "base/files/safe_base_name.h"

@ -4,7 +4,7 @@
#include "ash/capture_mode/capture_mode_controller.h"
#include "ash/projector/projector_controller_impl.h"
#include "ash/webui/annotator/annotator_client.h"
#include "ash/webui/annotator/public/cpp/annotator_client.h"
#include "ash/webui/media_app_ui/buildflags.h"
#include "ash/webui/media_app_ui/test/media_app_ui_browsertest.h"
#include "ash/webui/projector_app/buildflags.h"

@ -4,11 +4,31 @@
#include "chrome/browser/ui/ash/annotator/annotator_client_impl.h"
#include "annotator_client_impl.h"
#include "ash/annotator/annotator_controller.h"
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/shell.h"
#include "ash/webui/annotator/untrusted_annotator_page_handler_impl.h"
#include "ash/webui/projector_app/public/cpp/projector_app_constants.h"
#include "ui/views/controls/webview/webview.h"
#include "url/gurl.h"
AnnotatorClientImpl::AnnotatorClientImpl() = default;
AnnotatorClientImpl::AnnotatorClientImpl(
ash::AnnotatorController* annotator_controller)
: annotator_controller_(annotator_controller) {
annotator_controller_->SetToolClient(this);
}
AnnotatorClientImpl::~AnnotatorClientImpl() = default;
AnnotatorClientImpl::AnnotatorClientImpl()
: AnnotatorClientImpl(ash::Shell::Get()->annotator_controller()) {}
AnnotatorClientImpl::~AnnotatorClientImpl() {
annotator_controller_->SetToolClient(nullptr);
}
void AnnotatorClientImpl::InitForProjectorAnnotator(views::WebView* web_view) {
web_view->LoadInitialURL(GURL(ash::kChromeUIUntrustedAnnotatorUrl));
}
void AnnotatorClientImpl::SetAnnotatorPageHandler(
ash::UntrustedAnnotatorPageHandlerImpl* handler) {

@ -5,19 +5,29 @@
#ifndef CHROME_BROWSER_UI_ASH_ANNOTATOR_ANNOTATOR_CLIENT_IMPL_H_
#define CHROME_BROWSER_UI_ASH_ANNOTATOR_ANNOTATOR_CLIENT_IMPL_H_
#include "ash/annotator/annotator_controller.h"
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/webui/annotator/annotator_client.h"
#include "ash/webui/annotator/public/cpp/annotator_client.h"
#include "ash/webui/annotator/untrusted_annotator_page_handler_impl.h"
#include "base/memory/raw_ptr.h"
namespace views {
class WebView;
} // namespace views
// Implements the interface for the Annotator tool.
class AnnotatorClientImpl : public ash::AnnotatorClient {
public:
explicit AnnotatorClientImpl(ash::AnnotatorController* annotator_controller);
AnnotatorClientImpl();
AnnotatorClientImpl(const AnnotatorClientImpl&) = delete;
AnnotatorClientImpl& operator=(const AnnotatorClientImpl&) = delete;
~AnnotatorClientImpl() override;
// RecordingOverlayViewImpl calls this function to initialize the annotator
// tool.
static void InitForProjectorAnnotator(views::WebView* web_view);
// ash::AnnotatorClient:
void SetAnnotatorPageHandler(
ash::UntrustedAnnotatorPageHandlerImpl* handler) override;
@ -31,6 +41,7 @@ class AnnotatorClientImpl : public ash::AnnotatorClient {
}
private:
raw_ptr<ash::AnnotatorController> annotator_controller_ = nullptr;
raw_ptr<ash::UntrustedAnnotatorPageHandlerImpl> annotator_handler_ = nullptr;
};

@ -4,6 +4,7 @@
#include "chrome/browser/ui/ash/annotator/annotator_client_impl.h"
#include "ash/annotator/annotator_controller.h"
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/webui/annotator/mojom/untrusted_annotator.mojom.h"
#include "ash/webui/annotator/public/mojom/annotator_structs.mojom.h"
@ -24,6 +25,8 @@ class AnnotatorClientImplTest : public testing::Test {
// testing::Test:
void SetUp() override {
annotator_client_ =
std::make_unique<AnnotatorClientImpl>(&annotator_controller_);
annotator_ = std::make_unique<MockUntrustedAnnotatorPage>();
handler_ = std::make_unique<UntrustedAnnotatorPageHandlerImpl>(
annotator().remote().BindNewPipeAndPassReceiver(),
@ -33,15 +36,16 @@ class AnnotatorClientImplTest : public testing::Test {
// Annotator client has the handler's reference at this point, as it is set
// in the handler's constructor.
EXPECT_EQ(handler_.get(),
annotator_client_.get_annotator_handler_for_test());
annotator_client_->get_annotator_handler_for_test());
}
void TearDown() override {
handler_.reset();
annotator_.reset();
annotator_client_.reset();
}
AnnotatorClientImpl& annotator_client() { return annotator_client_; }
AnnotatorClientImpl& annotator_client() { return *annotator_client_; }
MockUntrustedAnnotatorPage& annotator() { return *annotator_; }
UntrustedAnnotatorPageHandlerImpl* handler() { return handler_.get(); }
base::test::SingleThreadTaskEnvironment& task_environment() {
@ -53,7 +57,8 @@ class AnnotatorClientImplTest : public testing::Test {
std::unique_ptr<MockUntrustedAnnotatorPage> annotator_;
std::unique_ptr<UntrustedAnnotatorPageHandlerImpl> handler_;
AnnotatorClientImpl annotator_client_;
std::unique_ptr<AnnotatorClientImpl> annotator_client_;
AnnotatorController annotator_controller_;
};
TEST_F(AnnotatorClientImplTest, SetTool) {

@ -10,7 +10,7 @@
#include "base/location.h"
#include "base/task/single_thread_task_runner.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/projector/projector_client_impl.h"
#include "chrome/browser/ui/ash/annotator/annotator_client_impl.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/views/controls/webview/web_contents_set_background_color.h"
#include "ui/views/controls/webview/webview.h"
@ -37,7 +37,7 @@ RecordingOverlayViewImpl::RecordingOverlayViewImpl(Profile* profile)
RecordingOverlayViewImpl::~RecordingOverlayViewImpl() = default;
void RecordingOverlayViewImpl::InitializeAnnotator() {
ProjectorClientImpl::InitForProjectorAnnotator(web_view_);
AnnotatorClientImpl::InitForProjectorAnnotator(web_view_);
}
BEGIN_METADATA(RecordingOverlayViewImpl)

@ -9,7 +9,6 @@
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/projector/projector_metrics.h"
#include "ash/public/cpp/annotator/annotator_tool.h"
#include "ash/public/cpp/projector/projector_controller.h"
#include "ash/public/cpp/projector/projector_new_screencast_precondition.h"
#include "ash/webui/projector_app/projector_app_client.h"
@ -29,7 +28,6 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/speech/speech_recognition_recognizer_client_impl.h"
#include "chrome/browser/ui/ash/annotator/annotator_client_impl.h"
#include "chrome/browser/ui/ash/projector/projector_utils.h"
#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
#include "chrome/browser/ui/browser_window.h"
@ -47,7 +45,6 @@
#include "media/mojo/mojom/speech_recognition_service.mojom.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/controls/webview/webview.h"
#include "url/gurl.h"
namespace {
@ -106,11 +103,6 @@ ash::OnDeviceToServerSpeechRecognitionFallbackReason GetFallbackReason(
} // namespace
// static
void ProjectorClientImpl::InitForProjectorAnnotator(views::WebView* web_view) {
web_view->LoadInitialURL(GURL(ash::kChromeUIUntrustedAnnotatorUrl));
}
// Using base::Unretained for callback is safe since the ProjectorClientImpl
// owns `drive_helper_`.
ProjectorClientImpl::ProjectorClientImpl(ash::ProjectorController* controller)
@ -315,20 +307,6 @@ void ProjectorClientImpl::OnLanguageIdentificationEvent(
// For now, this is ignored by projector.
}
void ProjectorClientImpl::SetTool(const ash::AnnotatorTool& tool) {
ash::AnnotatorClient::Get()->SetTool(tool);
}
// TODO(b/220202359): Implement undo.
void ProjectorClientImpl::Undo() {}
// TODO(b/220202359): Implement redo.
void ProjectorClientImpl::Redo() {}
void ProjectorClientImpl::Clear() {
ash::AnnotatorClient::Get()->Clear();
}
void ProjectorClientImpl::OnFileSystemMounted() {
OnNewScreencastPreconditionChanged(
controller_->GetNewScreencastPrecondition());

@ -7,7 +7,6 @@
#include <memory>
#include "ash/public/cpp/annotator/annotator_tool_controller.h"
#include "ash/public/cpp/projector/projector_client.h"
#include "ash/public/cpp/projector/projector_controller.h"
#include "ash/public/cpp/projector/speech_recognition_availability.h"
@ -22,23 +21,15 @@
#include "components/session_manager/core/session_manager.h"
#include "components/session_manager/core/session_manager_observer.h"
namespace views {
class WebView;
} // namespace views
class SpeechRecognitionRecognizerClientImpl;
// The client implementation for the ProjectorController in ash/. This client is
// responsible for handling requests that have browser dependencies.
class ProjectorClientImpl : public ash::ProjectorClient,
public SpeechRecognizerDelegate,
public ash::AnnotatorToolController,
drive::DriveIntegrationService::Observer,
session_manager::SessionManagerObserver {
public:
// RecordingOverlayViewImpl calls this function to initialize the annotator
// tool.
static void InitForProjectorAnnotator(views::WebView* web_view);
explicit ProjectorClientImpl(ash::ProjectorController* controller);
@ -78,12 +69,6 @@ class ProjectorClientImpl : public ash::ProjectorClient,
void OnLanguageIdentificationEvent(
media::mojom::LanguageIdentificationEventPtr event) override;
// ash::AnnotatorToolController:
void SetTool(const ash::AnnotatorTool& tool) override;
void Undo() override;
void Redo() override;
void Clear() override;
// DriveIntegrationService::Observer implementation.
void OnFileSystemMounted() override;
void OnFileSystemBeingUnmounted() override;

@ -173,7 +173,6 @@ class ProjectorClientTest : public InProcessBrowserTest {
// URLs are valid.
IN_PROC_BROWSER_TEST_F(ProjectorClientTest, AppUrlsValid) {
VerifyUrlValid(kChromeUIUntrustedProjectorUrl);
VerifyUrlValid(kChromeUIUntrustedAnnotatorUrl);
}
IN_PROC_BROWSER_TEST_F(ProjectorClientTest, OpenProjectorApp) {