screen_lock_library.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
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/chrome_thread.h"
10#include "chrome/browser/chromeos/cros/cros_library.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    // Make sure we run on IO thread.
39    if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
40      ChromeThread::PostTask(
41          ChromeThread::IO, FROM_HERE,
42          NewRunnableMethod(
43              this,
44              &ScreenLockLibraryImpl::NotifyScreenLockRequested));
45      return;
46    }
47    chromeos::NotifyScreenLockRequested();
48  }
49
50  void NotifyScreenLockCompleted() {
51    // Make sure we run on IO thread.
52    if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
53      ChromeThread::PostTask(
54          ChromeThread::IO, FROM_HERE,
55          NewRunnableMethod(
56              this,
57              &ScreenLockLibraryImpl::NotifyScreenLockCompleted));
58      return;
59    }
60    chromeos::NotifyScreenLockCompleted();
61  }
62
63  void NotifyScreenUnlockRequested() {
64    // Make sure we run on IO thread.
65    if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
66      ChromeThread::PostTask(
67          ChromeThread::IO, FROM_HERE,
68          NewRunnableMethod(
69              this,
70              &ScreenLockLibraryImpl::NotifyScreenUnlockRequested));
71      return;
72    }
73    chromeos::NotifyScreenUnlockRequested();
74  }
75
76  void NotifyScreenUnlockCompleted() {
77    // Make sure we run on IO thread.
78    if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
79      ChromeThread::PostTask(
80          ChromeThread::IO, FROM_HERE,
81          NewRunnableMethod(
82              this,
83              &ScreenLockLibraryImpl::NotifyScreenUnlockCompleted));
84      return;
85    }
86    chromeos::NotifyScreenUnlockCompleted();
87  }
88
89 private:
90  void Init() {
91    screen_lock_connection_ = chromeos::MonitorScreenLock(
92        &ScreenLockedHandler, this);
93  }
94
95  void LockScreen() {
96    // Make sure we run on UI thread.
97    if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
98      ChromeThread::PostTask(
99          ChromeThread::UI, FROM_HERE,
100          NewRunnableMethod(this, &ScreenLockLibraryImpl::LockScreen));
101      return;
102    }
103    FOR_EACH_OBSERVER(Observer, observers_, LockScreen(this));
104  }
105
106  void UnlockScreen() {
107    // Make sure we run on UI thread.
108    if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
109      ChromeThread::PostTask(
110          ChromeThread::UI, FROM_HERE,
111          NewRunnableMethod(this, &ScreenLockLibraryImpl::UnlockScreen));
112      return;
113    }
114    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen(this));
115  }
116
117  void UnlockScreenFailed() {
118    // Make sure we run on UI thread.
119    if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
120      ChromeThread::PostTask(
121          ChromeThread::UI, FROM_HERE,
122          NewRunnableMethod(this, &ScreenLockLibraryImpl::UnlockScreenFailed));
123      return;
124    }
125    FOR_EACH_OBSERVER(Observer, observers_, UnlockScreenFailed(this));
126  }
127
128  static void ScreenLockedHandler(void* object, ScreenLockEvent event) {
129    ScreenLockLibraryImpl* self = static_cast<ScreenLockLibraryImpl*>(object);
130    switch (event) {
131      case chromeos::LockScreen:
132        self->LockScreen();
133        break;
134      case chromeos::UnlockScreen:
135        self->UnlockScreen();
136        break;
137      case chromeos::UnlockScreenFailed:
138        self->UnlockScreenFailed();
139        break;
140      default:
141        NOTREACHED();
142    }
143  }
144
145  ObserverList<Observer> observers_;
146
147  // A reference to the screen lock api
148  chromeos::ScreenLockConnection screen_lock_connection_;
149
150  DISALLOW_COPY_AND_ASSIGN(ScreenLockLibraryImpl);
151};
152
153class ScreenLockLibraryStubImpl : public ScreenLockLibrary {
154 public:
155  ScreenLockLibraryStubImpl() {}
156  ~ScreenLockLibraryStubImpl() {}
157  void AddObserver(Observer* observer) {}
158  void RemoveObserver(Observer* observer) {}
159  void NotifyScreenLockRequested() {}
160  void NotifyScreenLockCompleted() {}
161  void NotifyScreenUnlockRequested() {}
162  void NotifyScreenUnlockCompleted() {}
163};
164
165// static
166ScreenLockLibrary* ScreenLockLibrary::GetImpl(bool stub) {
167  if (stub)
168    return new ScreenLockLibraryStubImpl();
169  else
170    return new ScreenLockLibraryImpl();
171}
172
173}  // namespace chromeos
174
175// Allows InvokeLater without adding refcounting. This class is a Singleton and
176// won't be deleted until it's last InvokeLater is run.
177DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::ScreenLockLibraryImpl);
178
179