0

Projector: Launch toolbar from Player app

This CL adds a message handler for the Player app WebUI to launch the
Projector toolbar when a button is clicked. The button can toggle the
toolbar visibility, similar to the Projector feature pod controller.

Bug: 1213937
Change-Id: I00e58fc8af31995d766c318a68c07ca2e50ee78c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3016366
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Yilkal Abe <yilkal@chromium.org>
Commit-Queue: Toby Huang <tobyhuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#900775}
This commit is contained in:
Toby Huang
2021-07-13 01:38:58 +00:00
committed by Chromium LUCI CQ
parent 01b2794029
commit 97ce1d5d77
9 changed files with 79 additions and 17 deletions

@ -67,6 +67,10 @@ void ProjectorControllerImpl::SetProjectorToolsVisible(bool is_visible) {
ui_controller_->CloseToolbar();
}
bool ProjectorControllerImpl::AreProjectorToolsVisible() const {
return ui_controller_->IsToolbarVisible();
}
bool ProjectorControllerImpl::IsEligible() const {
return is_speech_recognition_available_;
}
@ -85,12 +89,16 @@ void ProjectorControllerImpl::MarkKeyIdea() {
}
void ProjectorControllerImpl::OnRecordingStarted() {
projector_session_->Start();
StartSpeechRecognition();
ui_controller_->OnRecordingStateChanged(true /* started */);
metadata_controller_->OnRecordingStarted();
}
void ProjectorControllerImpl::OnRecordingEnded() {
if (!projector_session_->is_active())
return;
projector_session_->Stop();
StopSpeechRecognition();
ui_controller_->OnRecordingStateChanged(false /* started */);

@ -36,9 +36,9 @@ class ASH_EXPORT ProjectorControllerImpl : public ProjectorController {
void OnSpeechRecognitionAvailable(bool available) override;
void OnTranscription(const media::SpeechRecognitionResult& result) override;
void OnTranscriptionError() override;
void SetProjectorToolsVisible(bool is_visible);
bool IsEligible() const;
void SetProjectorToolsVisible(bool is_visible) override;
bool AreProjectorToolsVisible() const override;
bool IsEligible() const override;
// Sets Caption bubble state to become opened/closed.
void SetCaptionBubbleState(bool is_on);

@ -56,17 +56,10 @@ void ProjectorFeaturePodController::OnIconPressed() {
tray_controller_->CloseBubble();
auto* projector_controller = Shell::Get()->projector_controller();
auto* projector_session = projector_controller->projector_session();
DCHECK(projector_controller);
DCHECK(projector_session);
if (projector_session->is_active()) {
projector_session->Stop();
projector_controller->SetProjectorToolsVisible(false);
} else {
projector_session->Start();
projector_controller->SetProjectorToolsVisible(true);
}
bool is_visible = projector_controller->AreProjectorToolsVisible();
projector_controller->SetProjectorToolsVisible(!is_visible);
}
SystemTrayItemUmaType ProjectorFeaturePodController::GetUmaType() const {

@ -50,6 +50,14 @@ class ASH_PUBLIC_EXPORT ProjectorController {
// Called when there is an error in transcription.
virtual void OnTranscriptionError() = 0;
// Sets Projector toolbar visibility.
virtual void SetProjectorToolsVisible(bool is_visible) = 0;
virtual bool AreProjectorToolsVisible() const = 0;
// Returns true if Projector is eligible to start a new session.
// TODO(yilkal): Rename to something more descriptive, like CanStart().
virtual bool IsEligible() const = 0;
};
} // namespace ash

@ -46,6 +46,7 @@ js_type_check("closure_compile") {
}
js_library("player_app") {
deps = [ "//ui/webui/resources/js:cr.m" ]
}
js_library("selfie_cam") {

@ -2,10 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
// TODO(crbug/1213937): Launch Projector toolbar and integrate with screen
// capture.
function onLaunchClick() {
console.log('Launching Projector toolbar');
sendWithPromise('launchScreenCapture').then(function(isVisible) {
var button = document.body.querySelector('button');
// TODO(crbug/1213937): Use $i18n{}.
if (isVisible) {
button.textContent = 'Hide Projector Tools';
} else {
button.textContent = 'Show Projector Tools';
}
});
}
function initialize() {

@ -43,6 +43,9 @@ class ASH_PUBLIC_EXPORT MockProjectorController : public ProjectorController {
MOCK_METHOD1(OnTranscription,
void(const media::SpeechRecognitionResult& result));
MOCK_METHOD0(OnTranscriptionError, void());
MOCK_METHOD1(SetProjectorToolsVisible, void(bool is_visible));
MOCK_CONST_METHOD0(AreProjectorToolsVisible, bool());
MOCK_CONST_METHOD0(IsEligible, bool());
};
class ProjectorClientTest : public InProcessBrowserTest {

@ -4,12 +4,15 @@
#include "chrome/browser/ui/webui/chromeos/projector/projector_ui.h"
#include "ash/public/cpp/projector/projector_controller.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/common/webui_url_constants.h"
#include "chromeos/projector/grit/projector_resources.h"
#include "chromeos/projector/grit/projector_resources_map.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/browser/web_ui_message_handler.h"
namespace chromeos {
@ -25,12 +28,48 @@ content::WebUIDataSource* CreateProjectorHTMLSource() {
return source;
}
class ProjectorMessageHandler : public content::WebUIMessageHandler {
public:
ProjectorMessageHandler() = default;
~ProjectorMessageHandler() override = default;
ProjectorMessageHandler(const ProjectorMessageHandler&) = delete;
ProjectorMessageHandler& operator=(const ProjectorMessageHandler&) = delete;
// content::WebUIMessageHandler:
void RegisterMessages() override {
web_ui()->RegisterMessageCallback(
"launchScreenCapture",
base::BindRepeating(
&ProjectorMessageHandler::HandleShowHideProjectorToolbar,
base::Unretained(this)));
}
private:
void HandleShowHideProjectorToolbar(const base::ListValue* args) {
AllowJavascript();
CHECK_EQ(1u, args->GetSize());
bool is_visible = true;
// This code only shows and hides the Projector toolbar.
// TODO(crbug/1206720): Integrate with screen capture.
auto* projector_controller = ash::ProjectorController::Get();
if (projector_controller && projector_controller->IsEligible()) {
is_visible = projector_controller->AreProjectorToolsVisible();
projector_controller->SetProjectorToolsVisible(!is_visible);
}
ResolveJavascriptCallback(args->GetList()[0], base::Value(!is_visible));
}
};
} // namespace
ProjectorUI::ProjectorUI(content::WebUI* web_ui)
: MojoBubbleWebUIController(web_ui) {
: MojoBubbleWebUIController(web_ui, /*enable_chrome_send=*/true) {
Profile* profile = Profile::FromWebUI(web_ui);
content::WebUIDataSource::Add(profile, CreateProjectorHTMLSource());
web_ui->AddMessageHandler(std::make_unique<ProjectorMessageHandler>());
}
ProjectorUI::~ProjectorUI() = default;

@ -699,7 +699,7 @@ Some handling C++ might do this:
void OvenHandler::HandleBakeDonuts(const base::ListValue* args) {
AllowJavascript();
double num_donuts_baked = GetOven()->BakeDonuts();
ResolveJavascriptCallback(args->GetList()[0], num_donuts_baked);
ResolveJavascriptCallback(args->GetList()[0], base::Value(num_donuts_baked));
}
```
@ -794,7 +794,7 @@ should be communicated to the JavaScript running in a tab.
```c++
void OvenHandler::OnBakingDonutsFinished(size_t num_donuts) {
FireWebUIListener("donuts-baked", base::FundamentalValue(num_donuts));
FireWebUIListener("donuts-baked", base::Value(num_donuts));
}
```
@ -841,7 +841,7 @@ void DonutHandler::HandleGetNumberOfDonuts(const base::ListValue* args) {
const base::Value& callback_id = args->GetList()[0];
size_t num_donuts = GetOven()->GetNumberOfDonuts();
ResolveJavascriptCallback(callback_id, base::FundamentalValue(num_donuts));
ResolveJavascriptCallback(callback_id, base::Value(num_donuts));
}
```