Index: chrome/browser/chromeos/accessibility/chromevox_panel.cc |
diff --git a/chrome/browser/chromeos/accessibility/chromevox_panel.cc b/chrome/browser/chromeos/accessibility/chromevox_panel.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..dc10267e0ebe60ddc651d1cf0845ce70f868c234 |
--- /dev/null |
+++ b/chrome/browser/chromeos/accessibility/chromevox_panel.cc |
@@ -0,0 +1,146 @@ |
+// Copyright 2015 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 "ash/shell.h" |
+#include "ash/shell_window_ids.h" |
+#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" |
+#include "chrome/browser/chromeos/accessibility/chromevox_panel.h" |
+#include "chrome/common/extensions/extension_constants.h" |
+#include "content/public/browser/web_contents.h" |
+#include "ui/chromeos/accessibility_types.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 int kPanelHeight = 35; |
+const char kChromeVoxPanelRelativeUrl[] = "/cvox2/background/panel.html"; |
+const char kFullscreenURLFragment[] = "fullscreen"; |
+const char kDisableSpokenFeedbackURLFragment[] = "close"; |
+ |
+} // namespace |
+ |
+class ChromeVoxPanelWebContentsObserver : public content::WebContentsObserver { |
+ public: |
+ ChromeVoxPanelWebContentsObserver(content::WebContents* web_contents, |
+ ChromeVoxPanel* panel) |
+ : 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 |
+ // to this panel host. |
+ std::string fragment = web_contents()->GetLastCommittedURL().ref(); |
+ if (fragment == kDisableSpokenFeedbackURLFragment) |
+ panel_->DisableSpokenFeedback(); |
+ else if (fragment == kFullscreenURLFragment) |
+ panel_->EnterFullscreen(); |
+ else |
+ panel_->ExitFullscreen(); |
+ } |
+ |
+ private: |
+ ChromeVoxPanel* panel_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ChromeVoxPanelWebContentsObserver); |
+}; |
+ |
+ChromeVoxPanel::ChromeVoxPanel(content::BrowserContext* browser_context) { |
+ std::string url("chrome-extension://"); |
+ url += extension_misc::kChromeVoxExtensionId; |
+ url += kChromeVoxPanelRelativeUrl; |
+ |
+ web_view_ = new views::WebView(browser_context); |
+ web_contents_observer_.reset( |
+ new ChromeVoxPanelWebContentsObserver(web_view_->GetWebContents(), this)); |
+ web_view_->LoadInitialURL(GURL(url)); |
+ |
+ widget_ = new views::Widget(); |
+ views::Widget::InitParams params( |
+ views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
+ aura::Window* root_window = ash::Shell::GetPrimaryRootWindow(); |
+ params.parent = ash::Shell::GetContainer( |
+ root_window, ash::kShellWindowId_SettingBubbleContainer); |
+ params.delegate = this; |
+ params.bounds = gfx::Rect(0, 0, root_window->bounds().width(), |
+ root_window->bounds().height()); |
+ widget_->Init(params); |
+ SetShadowType(widget_->GetNativeWindow(), wm::SHADOW_TYPE_RECTANGULAR); |
+ |
+ ash::Shell::GetScreen()->AddObserver(this); |
+} |
+ |
+ChromeVoxPanel::~ChromeVoxPanel() { |
+ ash::Shell::GetScreen()->RemoveObserver(this); |
+} |
+ |
+int ChromeVoxPanel::GetHeight() { |
+ return kPanelHeight; |
+} |
+ |
+aura::Window* ChromeVoxPanel::GetRootWindow() { |
+ return GetWidget()->GetNativeWindow()->GetRootWindow(); |
+} |
+ |
+void ChromeVoxPanel::Close() { |
+ widget_->Close(); |
+} |
+ |
+void ChromeVoxPanel::DidFirstVisuallyNonEmptyPaint() { |
+ widget_->Show(); |
+ ash::Shell::GetInstance()->UpdateDisplayWorkAreaInsets(GetRootWindow()); |
+} |
+ |
+void ChromeVoxPanel::EnterFullscreen() { |
+ fullscreen_ = true; |
+ UpdateWidgetBounds(); |
+} |
+ |
+void ChromeVoxPanel::ExitFullscreen() { |
+ fullscreen_ = false; |
+ UpdateWidgetBounds(); |
+} |
+ |
+void ChromeVoxPanel::DisableSpokenFeedback() { |
+ chromeos::AccessibilityManager::Get()->EnableSpokenFeedback( |
+ false, ui::A11Y_NOTIFICATION_NONE); |
+} |
+ |
+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_; |
Jun Mukai
2015/11/06 18:21:04
You don't have to remember |web_view_| as an insta
dmazzoni
2015/11/09 23:02:06
Well, I need the BrowserContext to initialize the
|
+} |
+ |
+void ChromeVoxPanel::OnDisplayMetricsChanged(const gfx::Display& display, |
+ uint32_t changed_metrics) { |
+ UpdateWidgetBounds(); |
+ ash::Shell::GetInstance()->UpdateDisplayWorkAreaInsets(GetRootWindow()); |
+} |
+ |
+void ChromeVoxPanel::UpdateWidgetBounds() { |
+ gfx::Rect bounds(GetRootWindow()->bounds().size()); |
+ if (!fullscreen_) |
+ bounds.set_height(kPanelHeight); |
+ widget_->SetBounds(bounds); |
+} |