1// Copyright 2013 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 "chrome/browser/extensions/api/braille_display_private/braille_display_private_api.h"
6
7#include "base/lazy_instance.h"
8#include "chrome/browser/extensions/api/braille_display_private/braille_controller.h"
9#include "chrome/browser/extensions/extension_system.h"
10#include "chrome/browser/profiles/profile.h"
11#include "chrome/browser/profiles/profile_manager.h"
12
13#if defined(OS_CHROMEOS)
14#include "chrome/browser/chromeos/login/screen_locker.h"
15#include "chrome/browser/chromeos/profiles/profile_helper.h"
16#endif
17
18namespace OnDisplayStateChanged =
19    extensions::api::braille_display_private::OnDisplayStateChanged;
20namespace OnKeyEvent = extensions::api::braille_display_private::OnKeyEvent;
21namespace WriteDots = extensions::api::braille_display_private::WriteDots;
22using extensions::api::braille_display_private::DisplayState;
23using extensions::api::braille_display_private::KeyEvent;
24using extensions::api::braille_display_private::BrailleController;
25
26namespace extensions {
27
28class BrailleDisplayPrivateAPI::DefaultEventDelegate
29    : public BrailleDisplayPrivateAPI::EventDelegate {
30 public:
31  DefaultEventDelegate(EventRouter::Observer* observer, Profile* profile);
32  virtual ~DefaultEventDelegate();
33
34  virtual void BroadcastEvent(scoped_ptr<Event> event) OVERRIDE;
35  virtual bool HasListener() OVERRIDE;
36
37 private:
38  EventRouter::Observer* observer_;
39  Profile* profile_;
40};
41
42BrailleDisplayPrivateAPI::BrailleDisplayPrivateAPI(Profile* profile)
43    : profile_(profile), scoped_observer_(this),
44      event_delegate_(new DefaultEventDelegate(this, profile_)) {
45}
46
47BrailleDisplayPrivateAPI::~BrailleDisplayPrivateAPI() {
48}
49
50void BrailleDisplayPrivateAPI::Shutdown() {
51}
52
53static base::LazyInstance<ProfileKeyedAPIFactory<BrailleDisplayPrivateAPI> >
54g_factory = LAZY_INSTANCE_INITIALIZER;
55
56// static
57ProfileKeyedAPIFactory<BrailleDisplayPrivateAPI>*
58BrailleDisplayPrivateAPI::GetFactoryInstance() {
59  return &g_factory.Get();
60}
61
62void BrailleDisplayPrivateAPI::OnDisplayStateChanged(
63    const DisplayState& display_state) {
64  scoped_ptr<Event> event(new Event(
65      OnDisplayStateChanged::kEventName,
66      OnDisplayStateChanged::Create(display_state)));
67  event_delegate_->BroadcastEvent(event.Pass());
68}
69
70void BrailleDisplayPrivateAPI::OnKeyEvent(
71    const KeyEvent& key_event) {
72  // Key events only go to extensions of the active profile.
73  if (!IsProfileActive())
74    return;
75  scoped_ptr<Event> event(new Event(
76      OnKeyEvent::kEventName, OnKeyEvent::Create(key_event)));
77  event_delegate_->BroadcastEvent(event.Pass());
78}
79
80bool BrailleDisplayPrivateAPI::IsProfileActive() {
81#if defined(OS_CHROMEOS)
82  Profile* active_profile;
83  chromeos::ScreenLocker* screen_locker =
84      chromeos::ScreenLocker::default_screen_locker();
85  if (screen_locker && screen_locker->locked()) {
86    active_profile = chromeos::ProfileHelper::GetSigninProfile();
87  } else {
88    // Since we are creating one instance per profile / user, we should be fine
89    // comparing against the active user. That said - if we ever change that,
90    // this code will need to be changed.
91    active_profile = ProfileManager::GetActiveUserProfile();
92  }
93  return profile_->IsSameProfile(active_profile);
94#else  // !defined(OS_CHROMEOS)
95  return true;
96#endif
97}
98
99void BrailleDisplayPrivateAPI::SetEventDelegateForTest(
100    scoped_ptr<EventDelegate> delegate) {
101  event_delegate_ = delegate.Pass();
102}
103
104void BrailleDisplayPrivateAPI::OnListenerAdded(
105    const EventListenerInfo& details) {
106  BrailleController* braille_controller = BrailleController::GetInstance();
107  if (!scoped_observer_.IsObserving(braille_controller))
108    scoped_observer_.Add(braille_controller);
109}
110
111void BrailleDisplayPrivateAPI::OnListenerRemoved(
112    const EventListenerInfo& details) {
113  BrailleController* braille_controller = BrailleController::GetInstance();
114  if (!event_delegate_->HasListener() &&
115      scoped_observer_.IsObserving(braille_controller)) {
116    scoped_observer_.Remove(braille_controller);
117  }
118}
119
120BrailleDisplayPrivateAPI::DefaultEventDelegate::DefaultEventDelegate(
121    EventRouter::Observer* observer, Profile* profile)
122    : observer_(observer), profile_(profile) {
123  EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
124  event_router->RegisterObserver(observer_, OnDisplayStateChanged::kEventName);
125  event_router->RegisterObserver(observer_, OnKeyEvent::kEventName);
126}
127
128BrailleDisplayPrivateAPI::DefaultEventDelegate::~DefaultEventDelegate() {
129  ExtensionSystem::Get(profile_)->event_router()->UnregisterObserver(observer_);
130}
131
132void BrailleDisplayPrivateAPI::DefaultEventDelegate::BroadcastEvent(
133    scoped_ptr<Event> event) {
134  ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent(event.Pass());
135}
136
137bool BrailleDisplayPrivateAPI::DefaultEventDelegate::HasListener() {
138  EventRouter* event_router = ExtensionSystem::Get(profile_)->event_router();
139  return (event_router->HasEventListener(OnDisplayStateChanged::kEventName) ||
140          event_router->HasEventListener(OnKeyEvent::kEventName));
141}
142
143namespace api {
144bool BrailleDisplayPrivateGetDisplayStateFunction::Prepare() {
145  return true;
146}
147
148void BrailleDisplayPrivateGetDisplayStateFunction::Work() {
149  SetResult(
150      BrailleController::GetInstance()->GetDisplayState()->ToValue().release());
151}
152
153bool BrailleDisplayPrivateGetDisplayStateFunction::Respond() {
154  return true;
155}
156
157BrailleDisplayPrivateWriteDotsFunction::
158BrailleDisplayPrivateWriteDotsFunction() {
159}
160
161BrailleDisplayPrivateWriteDotsFunction::
162~BrailleDisplayPrivateWriteDotsFunction() {
163}
164
165bool BrailleDisplayPrivateWriteDotsFunction::Prepare() {
166  params_ = WriteDots::Params::Create(*args_);
167  EXTENSION_FUNCTION_VALIDATE(params_);
168  return true;
169}
170
171void BrailleDisplayPrivateWriteDotsFunction::Work() {
172  BrailleController::GetInstance()->WriteDots(params_->cells);
173}
174
175bool BrailleDisplayPrivateWriteDotsFunction::Respond() {
176  return true;
177}
178}  // namespace api
179}  // namespace extensions
180