• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "athena/content/web_activity.h"
6 
7 #include "athena/activity/public/activity_manager.h"
8 #include "athena/input/public/accelerator_manager.h"
9 #include "content/public/browser/native_web_keyboard_event.h"
10 #include "content/public/browser/web_contents.h"
11 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
12 #include "ui/views/controls/webview/webview.h"
13 #include "ui/views/focus/focus_manager.h"
14 
15 namespace athena {
16 namespace {
17 
18 class WebActivityController : public AcceleratorHandler {
19  public:
20   enum Command {
21     CMD_BACK,
22     CMD_FORWARD,
23     CMD_RELOAD,
24     CMD_RELOAD_IGNORE_CACHE,
25   };
26 
WebActivityController(views::WebView * web_view)27   explicit WebActivityController(views::WebView* web_view)
28       : web_view_(web_view), reserved_accelerator_enabled_(true) {}
~WebActivityController()29   virtual ~WebActivityController() {}
30 
31   // Installs accelerators for web activity.
InstallAccelerators()32   void InstallAccelerators() {
33     accelerator_manager_ = AcceleratorManager::CreateForFocusManager(
34                                web_view_->GetFocusManager()).Pass();
35     const AcceleratorData accelerator_data[] = {
36         {TRIGGER_ON_PRESS, ui::VKEY_R, ui::EF_CONTROL_DOWN, CMD_RELOAD,
37          AF_NONE},
38         {TRIGGER_ON_PRESS, ui::VKEY_BROWSER_REFRESH, ui::EF_NONE, CMD_RELOAD,
39          AF_NONE},
40         {TRIGGER_ON_PRESS, ui::VKEY_BROWSER_REFRESH, ui::EF_CONTROL_DOWN,
41          CMD_RELOAD_IGNORE_CACHE, AF_NONE},
42         {TRIGGER_ON_PRESS, ui::VKEY_BROWSER_FORWARD, ui::EF_NONE, CMD_FORWARD,
43          AF_NONE},
44         {TRIGGER_ON_PRESS, ui::VKEY_BROWSER_BACK, ui::EF_NONE, CMD_BACK,
45          AF_NONE},
46     };
47     accelerator_manager_->RegisterAccelerators(
48         accelerator_data, arraysize(accelerator_data), this);
49   }
50 
51   // Methods that are called before and after key events are consumed by the web
52   // contents.
53   // See the documentation in WebContentsDelegate: for more details.
PreHandleKeyboardEvent(content::WebContents * source,const content::NativeWebKeyboardEvent & event,bool * is_keyboard_shortcut)54   bool PreHandleKeyboardEvent(content::WebContents* source,
55                               const content::NativeWebKeyboardEvent& event,
56                               bool* is_keyboard_shortcut) {
57     ui::Accelerator accelerator(
58         static_cast<ui::KeyboardCode>(event.windowsKeyCode),
59         content::GetModifiersFromNativeWebKeyboardEvent(event));
60     if (event.type == blink::WebInputEvent::KeyUp)
61       accelerator.set_type(ui::ET_KEY_RELEASED);
62 
63     if (reserved_accelerator_enabled_ &&
64         accelerator_manager_->IsRegistered(accelerator, AF_RESERVED)) {
65       return web_view_->GetFocusManager()->ProcessAccelerator(accelerator);
66     }
67     *is_keyboard_shortcut =
68         accelerator_manager_->IsRegistered(accelerator, AF_NONE);
69     return false;
70   }
71 
HandleKeyboardEvent(content::WebContents * source,const content::NativeWebKeyboardEvent & event)72   void HandleKeyboardEvent(content::WebContents* source,
73                            const content::NativeWebKeyboardEvent& event) {
74     unhandled_keyboard_event_handler_.HandleKeyboardEvent(
75         event, web_view_->GetFocusManager());
76   }
77 
78  private:
79   // AcceleratorHandler:
IsCommandEnabled(int command_id) const80   virtual bool IsCommandEnabled(int command_id) const OVERRIDE {
81     switch (command_id) {
82       case CMD_RELOAD:
83         return true;
84       case CMD_BACK:
85         return web_view_->GetWebContents()->GetController().CanGoBack();
86       case CMD_FORWARD:
87         return web_view_->GetWebContents()->GetController().CanGoForward();
88     }
89     return false;
90   }
91 
OnAcceleratorFired(int command_id,const ui::Accelerator & accelerator)92   virtual bool OnAcceleratorFired(int command_id,
93                                   const ui::Accelerator& accelerator) OVERRIDE {
94     switch (command_id) {
95       case CMD_RELOAD:
96         web_view_->GetWebContents()->GetController().Reload(false);
97         return true;
98       case CMD_RELOAD_IGNORE_CACHE:
99         web_view_->GetWebContents()->GetController().ReloadIgnoringCache(false);
100         return true;
101       case CMD_BACK:
102         web_view_->GetWebContents()->GetController().GoBack();
103         return true;
104       case CMD_FORWARD:
105         web_view_->GetWebContents()->GetController().GoForward();
106         return true;
107     }
108     return false;
109   }
110 
111   views::WebView* web_view_;
112   bool reserved_accelerator_enabled_;
113   scoped_ptr<AcceleratorManager> accelerator_manager_;
114   views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
115 
116   DISALLOW_COPY_AND_ASSIGN(WebActivityController);
117 };
118 
119 // A web view for athena's web activity.
120 class AthenaWebView : public views::WebView {
121  public:
AthenaWebView(content::BrowserContext * context)122   AthenaWebView(content::BrowserContext* context)
123       : views::WebView(context), controller_(new WebActivityController(this)) {}
~AthenaWebView()124   virtual ~AthenaWebView() {}
125 
InstallAccelerators()126   void InstallAccelerators() { controller_->InstallAccelerators(); }
127 
128  private:
129   // WebContentsDelegate:
PreHandleKeyboardEvent(content::WebContents * source,const content::NativeWebKeyboardEvent & event,bool * is_keyboard_shortcut)130   virtual bool PreHandleKeyboardEvent(
131       content::WebContents* source,
132       const content::NativeWebKeyboardEvent& event,
133       bool* is_keyboard_shortcut) OVERRIDE {
134     return controller_->PreHandleKeyboardEvent(
135         source, event, is_keyboard_shortcut);
136   }
137 
HandleKeyboardEvent(content::WebContents * source,const content::NativeWebKeyboardEvent & event)138   virtual void HandleKeyboardEvent(
139       content::WebContents* source,
140       const content::NativeWebKeyboardEvent& event) OVERRIDE {
141     controller_->HandleKeyboardEvent(source, event);
142   }
143 
144   scoped_ptr<WebActivityController> controller_;
145 
146   DISALLOW_COPY_AND_ASSIGN(AthenaWebView);
147 };
148 
149 }  // namespace
150 
WebActivity(content::BrowserContext * browser_context,const GURL & url)151 WebActivity::WebActivity(content::BrowserContext* browser_context,
152                          const GURL& url)
153     : browser_context_(browser_context), url_(url), web_view_(NULL) {
154 }
155 
~WebActivity()156 WebActivity::~WebActivity() {
157 }
158 
GetActivityViewModel()159 ActivityViewModel* WebActivity::GetActivityViewModel() {
160   return this;
161 }
162 
Init()163 void WebActivity::Init() {
164   DCHECK(web_view_);
165   static_cast<AthenaWebView*>(web_view_)->InstallAccelerators();
166 }
167 
GetRepresentativeColor()168 SkColor WebActivity::GetRepresentativeColor() {
169   // TODO(sad): Compute the color from the favicon.
170   return SK_ColorGRAY;
171 }
172 
GetTitle()173 base::string16 WebActivity::GetTitle() {
174   return web_view_->GetWebContents()->GetTitle();
175 }
176 
GetContentsView()177 views::View* WebActivity::GetContentsView() {
178   if (!web_view_) {
179     web_view_ = new AthenaWebView(browser_context_);
180     web_view_->LoadInitialURL(url_);
181     Observe(web_view_->GetWebContents());
182   }
183   return web_view_;
184 }
185 
TitleWasSet(content::NavigationEntry * entry,bool explicit_set)186 void WebActivity::TitleWasSet(content::NavigationEntry* entry,
187                               bool explicit_set) {
188   ActivityManager::Get()->UpdateActivity(this);
189 }
190 
DidUpdateFaviconURL(const std::vector<content::FaviconURL> & candidates)191 void WebActivity::DidUpdateFaviconURL(
192     const std::vector<content::FaviconURL>& candidates) {
193   ActivityManager::Get()->UpdateActivity(this);
194 }
195 
196 }  // namespace athena
197