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/profiles/profile.h"
10#include "chrome/browser/profiles/profile_manager.h"
11
12#if defined(OS_CHROMEOS)
13#include "chrome/browser/chromeos/login/lock/screen_locker.h"
14#include "chrome/browser/chromeos/profiles/profile_helper.h"
15#endif
16
17namespace OnDisplayStateChanged =
18    extensions::api::braille_display_private::OnDisplayStateChanged;
19namespace OnKeyEvent = extensions::api::braille_display_private::OnKeyEvent;
20namespace WriteDots = extensions::api::braille_display_private::WriteDots;
21using extensions::api::braille_display_private::DisplayState;
22using extensions::api::braille_display_private::KeyEvent;
23using extensions::api::braille_display_private::BrailleController;
24
25namespace extensions {
26
27class BrailleDisplayPrivateAPI::DefaultEventDelegate
28    : public BrailleDisplayPrivateAPI::EventDelegate {
29 public:
30  DefaultEventDelegate(EventRouter::Observer* observer, Profile* profile);
31  virtual ~DefaultEventDelegate();
32
33  virtual void BroadcastEvent(scoped_ptr<Event> event) OVERRIDE;
34  virtual bool HasListener() OVERRIDE;
35
36 private:
37  EventRouter::Observer* observer_;
38  Profile* profile_;
39};
40
41BrailleDisplayPrivateAPI::BrailleDisplayPrivateAPI(
42    content::BrowserContext* context)
43    : profile_(Profile::FromBrowserContext(context)),
44      scoped_observer_(this),
45      event_delegate_(new DefaultEventDelegate(this, profile_)) {}
46
47BrailleDisplayPrivateAPI::~BrailleDisplayPrivateAPI() {
48}
49
50void BrailleDisplayPrivateAPI::Shutdown() {
51}
52
53static base::LazyInstance<
54    BrowserContextKeyedAPIFactory<BrailleDisplayPrivateAPI> > g_factory =
55    LAZY_INSTANCE_INITIALIZER;
56
57// static
58BrowserContextKeyedAPIFactory<BrailleDisplayPrivateAPI>*
59BrailleDisplayPrivateAPI::GetFactoryInstance() {
60  return g_factory.Pointer();
61}
62
63void BrailleDisplayPrivateAPI::OnBrailleDisplayStateChanged(
64    const DisplayState& display_state) {
65  scoped_ptr<Event> event(new Event(
66      OnDisplayStateChanged::kEventName,
67      OnDisplayStateChanged::Create(display_state)));
68  event_delegate_->BroadcastEvent(event.Pass());
69}
70
71void BrailleDisplayPrivateAPI::OnBrailleKeyEvent(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 = EventRouter::Get(profile_);
124  event_router->RegisterObserver(observer_, OnDisplayStateChanged::kEventName);
125  event_router->RegisterObserver(observer_, OnKeyEvent::kEventName);
126}
127
128BrailleDisplayPrivateAPI::DefaultEventDelegate::~DefaultEventDelegate() {
129  EventRouter::Get(profile_)->UnregisterObserver(observer_);
130}
131
132void BrailleDisplayPrivateAPI::DefaultEventDelegate::BroadcastEvent(
133    scoped_ptr<Event> event) {
134  EventRouter::Get(profile_)->BroadcastEvent(event.Pass());
135}
136
137bool BrailleDisplayPrivateAPI::DefaultEventDelegate::HasListener() {
138  EventRouter* event_router = EventRouter::Get(profile_);
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