1// Copyright (c) 2010 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/chromeos/cros/screen_lock_library.h"
6
7#include "base/message_loop.h"
8#include "base/string_util.h"
9#include "chrome/browser/chromeos/cros/cros_library.h"
10#include "content/browser/browser_thread.h"
11
12namespace chromeos {
13
14// This class handles the interaction with the ChromeOS screen lock APIs.
15class ScreenLockLibraryImpl : public ScreenLockLibrary {
16 public:
17  ScreenLockLibraryImpl() {
18    if (CrosLibrary::Get()->EnsureLoaded()) {
19      Init();
20    }
21  }
22
23  ~ScreenLockLibraryImpl() {
24    if (screen_lock_connection_) {
25      chromeos::DisconnectScreenLock(screen_lock_connection_);
26    }
27  }
28
29  void AddObserver(Observer* observer) {
30    observers_.AddObserver(observer);
31  }
32
33  void RemoveObserver(Observer* observer) {
34    observers_.RemoveObserver(observer);
35  }
36
37  void NotifyScreenLockRequested() {
38    chromeos::NotifyScreenLockRequested();
39  }
40
41  void NotifyScreenLockCompleted() {
42    chromeos::NotifyScreenLockCompleted();
43  }
44
45  void NotifyScreenUnlockRequested() {
46    chromeos::NotifyScreenUnlockRequested();
47  }
48
49  void NotifyScreenUnlockCompleted() {
50    chromeos::NotifyScreenUnlockCompleted();
51  }
52
53 private:
54  void Init() {
55    screen_lock_connection_ = chromeos::MonitorScreenLock(
56        &ScreenLockedHandler, this);
57  }
58
59  void LockScreen() {
60    // Make sure we run on UI thread.
61    if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
62      BrowserThread::PostTask(
63          BrowserThread::UI, FROM_HERE,
64          NewRunnableMethod(this, &ScreenLockLibraryImpl::LockScreen));
65      return;
66    }
67    FOR_EACH_OBSERVER(Observer, observers_, LockScreen(this));
68  }
69
70  void UnlockScreen() {
71    // Make sure we run on UI thread.
72    if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
73      BrowserThread::PostTask(
74          BrowserThread::UI, FROM_HERE,
75          NewRunnableMethod(this, &ScreenLockLibraryImpl::UnlockScreen));
76      return;
77    }
78    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen(this));
79  }
80
81  void UnlockScreenFailed() {
82    // Make sure we run on UI thread.
83    if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
84      BrowserThread::PostTask(
85          BrowserThread::UI, FROM_HERE,
86          NewRunnableMethod(this, &ScreenLockLibraryImpl::UnlockScreenFailed));
87      return;
88    }
89    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreenFailed(this));
90  }
91
92  static void ScreenLockedHandler(void* object, ScreenLockEvent event) {
93    ScreenLockLibraryImpl* self = static_cast<ScreenLockLibraryImpl*>(object);
94    switch (event) {
95      case chromeos::LockScreen:
96        self->LockScreen();
97        break;
98      case chromeos::UnlockScreen:
99        self->UnlockScreen();
100        break;
101      case chromeos::UnlockScreenFailed:
102        self->UnlockScreenFailed();
103        break;
104      default:
105        NOTREACHED();
106    }
107  }
108
109  ObserverList<Observer> observers_;
110
111  // A reference to the screen lock api
112  chromeos::ScreenLockConnection screen_lock_connection_;
113
114  DISALLOW_COPY_AND_ASSIGN(ScreenLockLibraryImpl);
115};
116
117class ScreenLockLibraryStubImpl : public ScreenLockLibrary {
118 public:
119  ScreenLockLibraryStubImpl() {}
120  ~ScreenLockLibraryStubImpl() {}
121  void AddObserver(Observer* observer) {}
122  void RemoveObserver(Observer* observer) {}
123  void NotifyScreenLockRequested() {}
124  void NotifyScreenLockCompleted() {}
125  void NotifyScreenUnlockRequested() {}
126  void NotifyScreenUnlockCompleted() {}
127};
128
129// static
130ScreenLockLibrary* ScreenLockLibrary::GetImpl(bool stub) {
131  if (stub)
132    return new ScreenLockLibraryStubImpl();
133  else
134    return new ScreenLockLibraryImpl();
135}
136
137}  // namespace chromeos
138
139// Allows InvokeLater without adding refcounting. This class is a Singleton and
140// won't be deleted until it's last InvokeLater is run.
141DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::ScreenLockLibraryImpl);
142