Commit 3754df62 authored by Zach Helfinstein's avatar Zach Helfinstein Committed by Commit Bot

Abstract widget logic out of ChromeVoxPanel

This change is in preparation for creating the Switch Access context
menu, which we want to behave similarly to the ChromeVox Panel.

Bug: 864796
Change-Id: I7d3c4828d1de7165ce4e3cab99fa779b3f5dcd1d
Reviewed-on: https://chromium-review.googlesource.com/1141341
Commit-Queue: Zach Helfinstein <zhelfins@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576181}
parent f973fcee
......@@ -236,6 +236,8 @@ source_set("chromeos") {
"accessibility/accessibility_extension_loader.h",
"accessibility/accessibility_manager.cc",
"accessibility/accessibility_manager.h",
"accessibility/accessibility_panel.cc",
"accessibility/accessibility_panel.h",
"accessibility/ax_host_service.cc",
"accessibility/ax_host_service.h",
"accessibility/chromevox_panel.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/accessibility/accessibility_panel.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/interfaces/accessibility_controller.mojom.h"
#include "base/macros.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/data_use_measurement/data_use_web_contents_observer.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/ui/ash/ash_util.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/view_type_utils.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_animations.h"
// Monitors the contents of the accessibility panel for relevant changes
class AccessibilityPanel::AccessibilityPanelWebContentsObserver
: public content::WebContentsObserver {
public:
AccessibilityPanelWebContentsObserver(content::WebContents* web_contents,
AccessibilityPanel* panel)
: content::WebContentsObserver(web_contents), panel_(panel) {}
~AccessibilityPanelWebContentsObserver() override = default;
// content::WebContentsObserver overrides.
void DidFirstVisuallyNonEmptyPaint() override {
panel_->DidFirstVisuallyNonEmptyPaint();
}
private:
AccessibilityPanel* panel_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityPanelWebContentsObserver);
};
AccessibilityPanel::AccessibilityPanel(content::BrowserContext* browser_context,
std::string content_url,
std::string widget_name) {
views::WebView* web_view = new views::WebView(browser_context);
web_contents_ = web_view->GetWebContents();
web_contents_observer_.reset(
new AccessibilityPanelWebContentsObserver(web_contents_, this));
data_use_measurement::DataUseWebContentsObserver::CreateForWebContents(
web_contents_);
web_contents_->SetDelegate(this);
extensions::SetViewType(web_contents_, extensions::VIEW_TYPE_COMPONENT);
extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
web_contents_);
web_view->LoadInitialURL(GURL(content_url));
web_view_ = web_view;
widget_ = new views::Widget();
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
// Placing the panel in the accessibility panel container allows ash to manage
// both the window bounds and display work area.
ash_util::SetupWidgetInitParamsForContainer(
&params, ash::kShellWindowId_AccessibilityPanelContainer);
params.bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
params.delegate = this;
params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
params.name = widget_name;
widget_->Init(params);
wm::SetShadowElevation(widget_->GetNativeWindow(),
wm::kShadowElevationInactiveWindow);
// WebContentsObserver::DidFirstVisuallyNonEmptyPaint is not called under
// mash. Work around this by showing the window immediately.
// TODO(jamescook|fsamuel): Fix this. It causes a white flash when opening the
// window. The underlying problem is FrameToken plumbing, see
// ui::ws::ServerWindow::OnFrameTokenChanged. https://crbug.com/771331
if (!features::IsAshInBrowserProcess())
widget_->Show();
}
AccessibilityPanel::~AccessibilityPanel() = default;
void AccessibilityPanel::CloseNow() {
widget_->CloseNow();
}
void AccessibilityPanel::Close() {
// NOTE: Close the widget asynchronously because it's not legal to delete
// a WebView/WebContents during a DidFinishNavigation callback.
widget_->Close();
}
const views::Widget* AccessibilityPanel::GetWidget() const {
return widget_;
}
views::Widget* AccessibilityPanel::GetWidget() {
return widget_;
}
content::WebContents* AccessibilityPanel::GetWebContents() {
return web_contents_;
}
void AccessibilityPanel::DeleteDelegate() {
delete this;
}
views::View* AccessibilityPanel::GetContentsView() {
return web_view_;
}
bool AccessibilityPanel::HandleContextMenu(
const content::ContextMenuParams& params) {
// Eat all requests as context menus are disallowed.
return true;
}
void AccessibilityPanel::DidFirstVisuallyNonEmptyPaint() {
widget_->Show();
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_ACCESSIBILITY_PANEL_H_
#define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_ACCESSIBILITY_PANEL_H_
#include <stdint.h>
#include "base/macros.h"
#include "content/public/browser/web_contents_delegate.h"
#include "ui/views/widget/widget_delegate.h"
namespace content {
class BrowserContext;
}
namespace views {
class Widget;
}
// Creates a panel onscreen on which an accessibility extension can draw a
// custom UI.
class AccessibilityPanel : public views::WidgetDelegate,
public content::WebContentsDelegate {
public:
explicit AccessibilityPanel(content::BrowserContext* browser_context,
std::string content_url,
std::string widget_name);
~AccessibilityPanel() override;
// Closes the panel immediately, deleting the WebView/WebContents.
void CloseNow();
// Closes the panel asynchronously.
void Close();
// WidgetDelegate overrides.
const views::Widget* GetWidget() const override;
views::Widget* GetWidget() override;
void DeleteDelegate() override;
views::View* GetContentsView() override;
protected:
// Returns the web contents, so subclasses can monitor for changes.
content::WebContents* GetWebContents();
private:
class AccessibilityPanelWebContentsObserver;
// content::WebContentsDelegate:
bool HandleContextMenu(const content::ContextMenuParams& params) override;
// Indirectly invoked by the component extension.
void DidFirstVisuallyNonEmptyPaint();
content::WebContents* web_contents_;
std::unique_ptr<AccessibilityPanelWebContentsObserver> web_contents_observer_;
views::Widget* widget_ = nullptr;
views::View* web_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(AccessibilityPanel);
};
#endif // CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_ACCESSIBILITY_PANEL_H_
......@@ -4,35 +4,20 @@
#include "chrome/browser/chromeos/accessibility/chromevox_panel.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/interfaces/accessibility_controller.mojom.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "base/macros.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/data_use_measurement/data_use_web_contents_observer.h"
#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
#include "chrome/browser/ui/ash/ash_util.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/service_manager_connection.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_animations.h"
namespace {
const char kChromeVoxPanelRelativeUrl[] = "/cvox2/background/panel.html";
const char kFullscreenURLFragment[] = "fullscreen";
const char kDisableSpokenFeedbackURLFragment[] = "close";
const char kFocusURLFragment[] = "focus";
const char kFullscreenURLFragment[] = "fullscreen";
const char kWidgetName[] = "ChromeVoxPanel";
} // namespace
......@@ -44,11 +29,6 @@ class ChromeVoxPanel::ChromeVoxPanelWebContentsObserver
: content::WebContentsObserver(web_contents), panel_(panel) {}
~ChromeVoxPanelWebContentsObserver() override {}
// content::WebContentsObserver overrides.
void DidFirstVisuallyNonEmptyPaint() override {
panel_->DidFirstVisuallyNonEmptyPaint();
}
void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override {
// The ChromeVox panel uses the URL fragment to communicate state
......@@ -71,89 +51,12 @@ class ChromeVoxPanel::ChromeVoxPanelWebContentsObserver
};
ChromeVoxPanel::ChromeVoxPanel(content::BrowserContext* browser_context)
: widget_(nullptr), web_view_(nullptr) {
std::string url("chrome-extension://");
url += extension_misc::kChromeVoxExtensionId;
url += kChromeVoxPanelRelativeUrl;
views::WebView* web_view = new views::WebView(browser_context);
content::WebContents* contents = web_view->GetWebContents();
: AccessibilityPanel(browser_context, GetUrlForContent(), kWidgetName) {
web_contents_observer_.reset(
new ChromeVoxPanelWebContentsObserver(contents, this));
data_use_measurement::DataUseWebContentsObserver::CreateForWebContents(
contents);
contents->SetDelegate(this);
extensions::SetViewType(contents, extensions::VIEW_TYPE_COMPONENT);
extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
contents);
web_view->LoadInitialURL(GURL(url));
web_view_ = web_view;
widget_ = new views::Widget();
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
// Placing the panel in the accessibility panel container allows ash to manage
// both the window bounds and display work area.
ash_util::SetupWidgetInitParamsForContainer(
&params, ash::kShellWindowId_AccessibilityPanelContainer);
params.bounds = display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
params.delegate = this;
params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
params.name = "ChromeVoxPanel";
widget_->Init(params);
wm::SetShadowElevation(widget_->GetNativeWindow(),
wm::kShadowElevationInactiveWindow);
// WebContentsObserver::DidFirstVisuallyNonEmptyPaint is not called under
// mash. Work around this by showing the window immediately.
// TODO(jamescook|fsamuel): Fix this. It causes a white flash when opening the
// window. The underlying problem is FrameToken plumbing, see
// ui::ws::ServerWindow::OnFrameTokenChanged. https://crbug.com/771331
if (!features::IsAshInBrowserProcess())
widget_->Show();
}
ChromeVoxPanel::~ChromeVoxPanel() = default;
aura::Window* ChromeVoxPanel::GetRootWindow() {
return GetWidget()->GetNativeWindow()->GetRootWindow();
}
void ChromeVoxPanel::CloseNow() {
widget_->CloseNow();
}
void ChromeVoxPanel::Close() {
// NOTE: Close the widget asynchronously because it's not legal to delete
// a WebView/WebContents during a DidFinishNavigation callback.
widget_->Close();
}
const views::Widget* ChromeVoxPanel::GetWidget() const {
return widget_;
}
views::Widget* ChromeVoxPanel::GetWidget() {
return widget_;
}
void ChromeVoxPanel::DeleteDelegate() {
delete this;
}
views::View* ChromeVoxPanel::GetContentsView() {
return web_view_;
}
bool ChromeVoxPanel::HandleContextMenu(
const content::ContextMenuParams& params) {
// Eat all requests as context menus are disallowed.
return true;
new ChromeVoxPanelWebContentsObserver(GetWebContents(), this));
}
void ChromeVoxPanel::DidFirstVisuallyNonEmptyPaint() {
widget_->Show();
}
ChromeVoxPanel::~ChromeVoxPanel() {}
void ChromeVoxPanel::EnterFullscreen() {
Focus();
......@@ -161,15 +64,15 @@ void ChromeVoxPanel::EnterFullscreen() {
}
void ChromeVoxPanel::ExitFullscreen() {
widget_->Deactivate();
widget_->widget_delegate()->set_can_activate(false);
GetWidget()->Deactivate();
GetWidget()->widget_delegate()->set_can_activate(false);
SetAccessibilityPanelFullscreen(false);
}
void ChromeVoxPanel::Focus() {
widget_->widget_delegate()->set_can_activate(true);
widget_->Activate();
web_view_->RequestFocus();
GetWidget()->widget_delegate()->set_can_activate(true);
GetWidget()->Activate();
GetContentsView()->RequestFocus();
}
void ChromeVoxPanel::SetAccessibilityPanelFullscreen(bool fullscreen) {
......@@ -180,3 +83,11 @@ void ChromeVoxPanel::SetAccessibilityPanelFullscreen(bool fullscreen) {
->BindInterface(ash::mojom::kServiceName, &accessibility_controller);
accessibility_controller->SetAccessibilityPanelFullscreen(fullscreen);
}
std::string ChromeVoxPanel::GetUrlForContent() {
std::string url("chrome-extension://");
url += extension_misc::kChromeVoxExtensionId;
url += kChromeVoxPanelRelativeUrl;
return url;
}
......@@ -5,50 +5,19 @@
#ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_CHROMEVOX_PANEL_H_
#define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_CHROMEVOX_PANEL_H_
#include <stdint.h>
#include "base/macros.h"
#include "content/public/browser/web_contents_delegate.h"
#include "ui/views/widget/widget_delegate.h"
namespace content {
class BrowserContext;
}
namespace views {
class Widget;
}
#include "chrome/browser/chromeos/accessibility/accessibility_panel.h"
// Displays spoken feedback UI controls for the ChromeVox component extension
// in a small panel at the top of the display. Widget bounds are managed by ash.
class ChromeVoxPanel : public views::WidgetDelegate,
public content::WebContentsDelegate {
class ChromeVoxPanel : public AccessibilityPanel {
public:
explicit ChromeVoxPanel(content::BrowserContext* browser_context);
~ChromeVoxPanel() override;
aura::Window* GetRootWindow();
// Closes the panel immediately, deleting the WebView/WebContents.
void CloseNow();
// Closes the panel asynchronously.
void Close();
// WidgetDelegate overrides.
const views::Widget* GetWidget() const override;
views::Widget* GetWidget() override;
void DeleteDelegate() override;
views::View* GetContentsView() override;
private:
class ChromeVoxPanelWebContentsObserver;
// content::WebContentsDelegate:
bool HandleContextMenu(const content::ContextMenuParams& params) override;
private:
// Methods indirectly invoked by the component extension.
void DidFirstVisuallyNonEmptyPaint();
void EnterFullscreen();
void ExitFullscreen();
void Focus();
......@@ -56,9 +25,9 @@ class ChromeVoxPanel : public views::WidgetDelegate,
// Sends a request to the ash window manager.
void SetAccessibilityPanelFullscreen(bool fullscreen);
views::Widget* widget_;
std::string GetUrlForContent();
std::unique_ptr<ChromeVoxPanelWebContentsObserver> web_contents_observer_;
views::View* web_view_;
DISALLOW_COPY_AND_ASSIGN(ChromeVoxPanel);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment