OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 "components/keyboard_lock/keyboard_lock_host.h" |
| 6 |
| 7 #include <utility> |
| 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" |
| 11 #include "base/location.h" |
| 12 #include "base/logging.h" |
| 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/single_thread_task_runner.h" |
| 15 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/browser/ui/browser_finder.h" |
| 17 #include "components/keyboard_lock/active_key_event_filter.h" |
| 18 #include "components/keyboard_lock/active_key_event_filter_registrar.h" |
| 19 #include "components/keyboard_lock/key_event_filter_share_wrapper.h" |
| 20 #include "components/keyboard_lock/key_event_filter_thread_proxy.h" |
| 21 #include "components/keyboard_lock/key_hook_share_wrapper.h" |
| 22 #include "components/keyboard_lock/key_hook_state_keeper.h" |
| 23 #include "components/keyboard_lock/page_observer.h" |
| 24 #include "components/keyboard_lock/platform_key_hook.h" |
| 25 #include "components/keyboard_lock/widget_key_event_filter.h" |
| 26 #include "content/public/browser/web_contents.h" |
| 27 #include "ui/events/keycodes/dom/keycode_converter.h" |
| 28 |
| 29 namespace keyboard_lock { |
| 30 |
| 31 namespace { |
| 32 |
| 33 std::unique_ptr<KeyHookStateKeeper> CreateKeyHookStateKeeper( |
| 34 const scoped_refptr<base::SingleThreadTaskRunner>& runner, |
| 35 ActiveKeyEventFilterTracker* tracker, |
| 36 Browser* owner, |
| 37 KeyEventFilter* filter) { |
| 38 auto thread_proxy = base::MakeUnique<KeyEventFilterThreadProxy>( |
| 39 runner, base::MakeUnique<ActiveKeyEventFilter>(tracker)); |
| 40 return base::MakeUnique<KeyHookStateKeeper>( |
| 41 std::move(thread_proxy), |
| 42 base::MakeUnique<PlatformKeyHook>(owner, filter)); |
| 43 } |
| 44 |
| 45 } // namespace |
| 46 |
| 47 KeyboardLockHost::KeyboardLockHost( |
| 48 Browser* owner, |
| 49 scoped_refptr<base::SingleThreadTaskRunner> runner) |
| 50 : owner_(owner), |
| 51 runner_(std::move(runner)), |
| 52 key_hook_(CreateKeyHookStateKeeper( |
| 53 runner_, &active_key_event_filter_tracker_, owner_, filter())) { |
| 54 DCHECK(runner_); |
| 55 key_hook_.Activate(base::Callback<void(bool)>()); |
| 56 } |
| 57 |
| 58 KeyboardLockHost::~KeyboardLockHost() = default; |
| 59 |
| 60 // static |
| 61 KeyboardLockHost* KeyboardLockHost::Find(const content::WebContents* contents) { |
| 62 Browser* browser = chrome::FindBrowserWithWebContents(contents); |
| 63 if (!browser) { |
| 64 LOG(ERROR) << "No browser found from WebContents " << contents; |
| 65 return nullptr; |
| 66 } |
| 67 DCHECK(browser->GetKeyboardLockHost()); |
| 68 return browser->GetKeyboardLockHost(); |
| 69 } |
| 70 |
| 71 KeyEventFilter* KeyboardLockHost::filter() const { |
| 72 return const_cast<KeyHookThreadWrapper*>(&key_hook_); |
| 73 } |
| 74 |
| 75 void KeyboardLockHost::SetReservedKeys( |
| 76 content::WebContents* contents, |
| 77 const std::vector<ui::KeyboardCode>& codes, |
| 78 base::Callback<void(bool)> on_result) { |
| 79 if (!runner_->BelongsToCurrentThread()) { |
| 80 // TODO(zijiehe): The |contents| is not safe to be posted to other threads. |
| 81 if (!runner_->PostTask(FROM_HERE, base::BindOnce( |
| 82 &KeyboardLockHost::SetReservedKeys, |
| 83 base::Unretained(this), |
| 84 base::Unretained(contents), |
| 85 codes, |
| 86 on_result))) { |
| 87 if (on_result) { |
| 88 on_result.Run(false); |
| 89 } |
| 90 } |
| 91 return; |
| 92 } |
| 93 |
| 94 KeyHookActivator* key_hook = key_hooks_.Find(contents); |
| 95 if (key_hook) { |
| 96 key_hook->RegisterKey(codes, on_result); |
| 97 return; |
| 98 } |
| 99 |
| 100 auto state_keeper = base::MakeUnique<KeyHookStateKeeper>( |
| 101 base::MakeUnique<WidgetKeyEventFilter>(contents), |
| 102 base::MakeUnique<KeyHookShareWrapper>(&key_hook_)); |
| 103 state_keeper->RegisterKey(codes, on_result); |
| 104 auto* filter = state_keeper.get(); |
| 105 key_hooks_.Insert(contents, base::MakeUnique<ActiveKeyEventFilterRegistrar>( |
| 106 &active_key_event_filter_tracker_, |
| 107 std::move(state_keeper), |
| 108 filter)); |
| 109 PageObserver::Observe(contents, &key_hooks_); |
| 110 } |
| 111 |
| 112 void KeyboardLockHost::SetReservedKeyCodes( |
| 113 content::WebContents* contents, |
| 114 const std::vector<std::string>& codes, |
| 115 base::Callback<void(bool)> on_result) { |
| 116 std::vector<ui::KeyboardCode> ui_codes; |
| 117 for (auto code : codes) { |
| 118 ui_codes.push_back(NativeKeycodeToKeyboardCode( |
| 119 ui::KeycodeConverter::CodeStringToNativeKeycode(code))); |
| 120 } |
| 121 SetReservedKeys(contents, ui_codes, std::move(on_result)); |
| 122 } |
| 123 |
| 124 void KeyboardLockHost::ClearReservedKeys(content::WebContents* contents, |
| 125 base::Callback<void(bool)> on_result) { |
| 126 if (!runner_->BelongsToCurrentThread()) { |
| 127 // TODO(zijiehe): The |contents| is not safe to be posted to other threads. |
| 128 if (!runner_->PostTask(FROM_HERE, base::BindOnce( |
| 129 &KeyboardLockHost::ClearReservedKeys, |
| 130 base::Unretained(this), |
| 131 base::Unretained(contents), |
| 132 on_result))) { |
| 133 if (on_result) { |
| 134 on_result.Run(false); |
| 135 } |
| 136 } |
| 137 return; |
| 138 } |
| 139 |
| 140 key_hooks_.Erase(contents); |
| 141 } |
| 142 |
| 143 } // namespace keyboard_lock |
OLD | NEW |