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") { ...@@ -236,6 +236,8 @@ source_set("chromeos") {
"accessibility/accessibility_extension_loader.h", "accessibility/accessibility_extension_loader.h",
"accessibility/accessibility_manager.cc", "accessibility/accessibility_manager.cc",
"accessibility/accessibility_manager.h", "accessibility/accessibility_manager.h",
"accessibility/accessibility_panel.cc",
"accessibility/accessibility_panel.h",
"accessibility/ax_host_service.cc", "accessibility/ax_host_service.cc",
"accessibility/ax_host_service.h", "accessibility/ax_host_service.h",
"accessibility/chromevox_panel.cc", "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 @@ ...@@ -4,35 +4,20 @@
#include "chrome/browser/chromeos/accessibility/chromevox_panel.h" #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 "ash/public/interfaces/constants.mojom.h"
#include "base/macros.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.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 "content/public/common/service_manager_connection.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/constants.h" #include "extensions/common/constants.h"
#include "services/service_manager/public/cpp/connector.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/views/widget/widget.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_animations.h"
namespace { namespace {
const char kChromeVoxPanelRelativeUrl[] = "/cvox2/background/panel.html"; const char kChromeVoxPanelRelativeUrl[] = "/cvox2/background/panel.html";
const char kFullscreenURLFragment[] = "fullscreen";
const char kDisableSpokenFeedbackURLFragment[] = "close"; const char kDisableSpokenFeedbackURLFragment[] = "close";
const char kFocusURLFragment[] = "focus"; const char kFocusURLFragment[] = "focus";
const char kFullscreenURLFragment[] = "fullscreen";
const char kWidgetName[] = "ChromeVoxPanel";
} // namespace } // namespace
...@@ -44,11 +29,6 @@ class ChromeVoxPanel::ChromeVoxPanelWebContentsObserver ...@@ -44,11 +29,6 @@ class ChromeVoxPanel::ChromeVoxPanelWebContentsObserver
: content::WebContentsObserver(web_contents), panel_(panel) {} : content::WebContentsObserver(web_contents), panel_(panel) {}
~ChromeVoxPanelWebContentsObserver() override {} ~ChromeVoxPanelWebContentsObserver() override {}
// content::WebContentsObserver overrides.
void DidFirstVisuallyNonEmptyPaint() override {
panel_->DidFirstVisuallyNonEmptyPaint();
}
void DidFinishNavigation( void DidFinishNavigation(
content::NavigationHandle* navigation_handle) override { content::NavigationHandle* navigation_handle) override {
// The ChromeVox panel uses the URL fragment to communicate state // The ChromeVox panel uses the URL fragment to communicate state
...@@ -71,89 +51,12 @@ class ChromeVoxPanel::ChromeVoxPanelWebContentsObserver ...@@ -71,89 +51,12 @@ class ChromeVoxPanel::ChromeVoxPanelWebContentsObserver
}; };
ChromeVoxPanel::ChromeVoxPanel(content::BrowserContext* browser_context) ChromeVoxPanel::ChromeVoxPanel(content::BrowserContext* browser_context)
: widget_(nullptr), web_view_(nullptr) { : AccessibilityPanel(browser_context, GetUrlForContent(), kWidgetName) {
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();
web_contents_observer_.reset( web_contents_observer_.reset(
new ChromeVoxPanelWebContentsObserver(contents, this)); new ChromeVoxPanelWebContentsObserver(GetWebContents(), 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;
} }
void ChromeVoxPanel::DidFirstVisuallyNonEmptyPaint() { ChromeVoxPanel::~ChromeVoxPanel() {}
widget_->Show();
}
void ChromeVoxPanel::EnterFullscreen() { void ChromeVoxPanel::EnterFullscreen() {
Focus(); Focus();
...@@ -161,15 +64,15 @@ void ChromeVoxPanel::EnterFullscreen() { ...@@ -161,15 +64,15 @@ void ChromeVoxPanel::EnterFullscreen() {
} }
void ChromeVoxPanel::ExitFullscreen() { void ChromeVoxPanel::ExitFullscreen() {
widget_->Deactivate(); GetWidget()->Deactivate();
widget_->widget_delegate()->set_can_activate(false); GetWidget()->widget_delegate()->set_can_activate(false);
SetAccessibilityPanelFullscreen(false); SetAccessibilityPanelFullscreen(false);
} }
void ChromeVoxPanel::Focus() { void ChromeVoxPanel::Focus() {
widget_->widget_delegate()->set_can_activate(true); GetWidget()->widget_delegate()->set_can_activate(true);
widget_->Activate(); GetWidget()->Activate();
web_view_->RequestFocus(); GetContentsView()->RequestFocus();
} }
void ChromeVoxPanel::SetAccessibilityPanelFullscreen(bool fullscreen) { void ChromeVoxPanel::SetAccessibilityPanelFullscreen(bool fullscreen) {
...@@ -180,3 +83,11 @@ void ChromeVoxPanel::SetAccessibilityPanelFullscreen(bool fullscreen) { ...@@ -180,3 +83,11 @@ void ChromeVoxPanel::SetAccessibilityPanelFullscreen(bool fullscreen) {
->BindInterface(ash::mojom::kServiceName, &accessibility_controller); ->BindInterface(ash::mojom::kServiceName, &accessibility_controller);
accessibility_controller->SetAccessibilityPanelFullscreen(fullscreen); 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 @@ ...@@ -5,50 +5,19 @@
#ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_CHROMEVOX_PANEL_H_ #ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_CHROMEVOX_PANEL_H_
#define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_CHROMEVOX_PANEL_H_ #define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_CHROMEVOX_PANEL_H_
#include <stdint.h>
#include "base/macros.h" #include "base/macros.h"
#include "content/public/browser/web_contents_delegate.h" #include "chrome/browser/chromeos/accessibility/accessibility_panel.h"
#include "ui/views/widget/widget_delegate.h"
namespace content {
class BrowserContext;
}
namespace views {
class Widget;
}
// Displays spoken feedback UI controls for the ChromeVox component extension // 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 AccessibilityPanel {
class ChromeVoxPanel : public views::WidgetDelegate,
public content::WebContentsDelegate {
public: public:
explicit ChromeVoxPanel(content::BrowserContext* browser_context); explicit ChromeVoxPanel(content::BrowserContext* browser_context);
~ChromeVoxPanel() override; ~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; class ChromeVoxPanelWebContentsObserver;
// content::WebContentsDelegate: private:
bool HandleContextMenu(const content::ContextMenuParams& params) override;
// Methods indirectly invoked by the component extension. // Methods indirectly invoked by the component extension.
void DidFirstVisuallyNonEmptyPaint();
void EnterFullscreen(); void EnterFullscreen();
void ExitFullscreen(); void ExitFullscreen();
void Focus(); void Focus();
...@@ -56,9 +25,9 @@ class ChromeVoxPanel : public views::WidgetDelegate, ...@@ -56,9 +25,9 @@ class ChromeVoxPanel : public views::WidgetDelegate,
// Sends a request to the ash window manager. // Sends a request to the ash window manager.
void SetAccessibilityPanelFullscreen(bool fullscreen); void SetAccessibilityPanelFullscreen(bool fullscreen);
views::Widget* widget_; std::string GetUrlForContent();
std::unique_ptr<ChromeVoxPanelWebContentsObserver> web_contents_observer_; std::unique_ptr<ChromeVoxPanelWebContentsObserver> web_contents_observer_;
views::View* web_view_;
DISALLOW_COPY_AND_ASSIGN(ChromeVoxPanel); 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