1// Copyright (c) 2012 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/automation/automation_provider_observers.h"
6
7#include "base/values.h"
8#include "chrome/browser/automation/automation_provider.h"
9#include "chrome/browser/chrome_notification_types.h"
10#include "chrome/browser/chromeos/login/authentication_notification_details.h"
11#include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h"
12#include "chrome/browser/chromeos/login/existing_user_controller.h"
13#include "chrome/browser/chromeos/login/screen_locker.h"
14#include "chrome/browser/chromeos/login/screens/wizard_screen.h"
15#include "chrome/browser/chromeos/login/user_image.h"
16#include "chrome/browser/chromeos/login/user_image_manager.h"
17#include "chrome/browser/chromeos/login/user_manager.h"
18#include "chrome/browser/chromeos/login/wizard_controller.h"
19#include "content/public/browser/notification_service.h"
20
21using chromeos::WizardController;
22
23namespace {
24
25// Fake screen name for the user session (reported by WizardControllerObserver).
26const char kSessionScreenName[] = "session";
27
28}
29
30OOBEWebuiReadyObserver::OOBEWebuiReadyObserver(AutomationProvider* automation)
31    : automation_(automation->AsWeakPtr()) {
32  if (WizardController::default_controller() &&
33      WizardController::default_controller()->current_screen()) {
34    OOBEWebuiReady();
35  } else {
36    registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
37                   content::NotificationService::AllSources());
38  }
39}
40
41void OOBEWebuiReadyObserver::Observe(
42    int type,
43    const content::NotificationSource& source,
44    const content::NotificationDetails& details) {
45  DCHECK(type == chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE);
46  OOBEWebuiReady();
47}
48
49void OOBEWebuiReadyObserver::OOBEWebuiReady() {
50  if (automation_)
51    automation_->OnOOBEWebuiReady();
52  delete this;
53}
54
55LoginObserver::LoginObserver(chromeos::ExistingUserController* controller,
56                             AutomationProvider* automation,
57                             IPC::Message* reply_message)
58    : controller_(controller),
59      automation_(automation->AsWeakPtr()),
60      reply_message_(reply_message) {
61  controller_->set_login_status_consumer(this);
62}
63
64LoginObserver::~LoginObserver() {
65  controller_->set_login_status_consumer(NULL);
66}
67
68void LoginObserver::OnLoginFailure(const chromeos::LoginFailure& error) {
69  scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
70  return_value->SetString("error_string", error.GetErrorString());
71  AutomationJSONReply(automation_.get(), reply_message_.release())
72      .SendSuccess(return_value.get());
73  delete this;
74}
75
76void LoginObserver::OnLoginSuccess(const chromeos::UserContext& user_context) {
77  controller_->set_login_status_consumer(NULL);
78  AutomationJSONReply(automation_.get(), reply_message_.release())
79      .SendSuccess(NULL);
80  delete this;
81}
82
83WizardControllerObserver::WizardControllerObserver(
84    WizardController* wizard_controller,
85    AutomationProvider* automation,
86    IPC::Message* reply_message)
87    : wizard_controller_(wizard_controller),
88      automation_(automation->AsWeakPtr()),
89      reply_message_(reply_message) {
90  wizard_controller_->AddObserver(this);
91  registrar_.Add(this, chrome::NOTIFICATION_LOGIN_WEBUI_LOADED,
92                 content::NotificationService::AllSources());
93}
94
95WizardControllerObserver::~WizardControllerObserver() {
96  wizard_controller_->RemoveObserver(this);
97}
98
99void WizardControllerObserver::OnScreenChanged(
100    chromeos::WizardScreen* next_screen) {
101  std::string screen_name = next_screen->GetName();
102  if (screen_to_wait_for_.empty() || screen_to_wait_for_ == screen_name) {
103    SendReply(screen_name);
104  } else {
105    DVLOG(2) << "Still waiting for " << screen_to_wait_for_;
106  }
107}
108
109void WizardControllerObserver::OnSessionStart() {
110  SendReply(kSessionScreenName);
111}
112
113void WizardControllerObserver::Observe(
114    int type,
115    const content::NotificationSource& source,
116    const content::NotificationDetails& details) {
117  DCHECK(type == chrome::NOTIFICATION_LOGIN_WEBUI_LOADED);
118  SendReply(WizardController::kLoginScreenName);
119}
120
121void WizardControllerObserver::SendReply(const std::string& screen_name) {
122  scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
123  return_value->SetString("next_screen", screen_name);
124  AutomationJSONReply(automation_.get(), reply_message_.release())
125      .SendSuccess(return_value.get());
126  delete this;
127}
128
129ScreenLockUnlockObserver::ScreenLockUnlockObserver(
130    AutomationProvider* automation,
131    IPC::Message* reply_message,
132    bool lock_screen)
133    : automation_(automation->AsWeakPtr()),
134      reply_message_(reply_message),
135      lock_screen_(lock_screen) {
136  registrar_.Add(this, chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
137                 content::NotificationService::AllSources());
138}
139
140ScreenLockUnlockObserver::~ScreenLockUnlockObserver() {}
141
142void ScreenLockUnlockObserver::Observe(
143    int type,
144    const content::NotificationSource& source,
145    const content::NotificationDetails& details) {
146  DCHECK(type == chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED);
147  if (automation_) {
148    AutomationJSONReply reply(automation_.get(), reply_message_.release());
149    bool is_screen_locked = *content::Details<bool>(details).ptr();
150    if (lock_screen_ == is_screen_locked)
151      reply.SendSuccess(NULL);
152    else
153      reply.SendError("Screen lock failure.");
154  }
155  delete this;
156}
157
158ScreenUnlockObserver::ScreenUnlockObserver(AutomationProvider* automation,
159                                           IPC::Message* reply_message)
160    : ScreenLockUnlockObserver(automation, reply_message, false) {
161  chromeos::ScreenLocker::default_screen_locker()->SetLoginStatusConsumer(this);
162}
163
164ScreenUnlockObserver::~ScreenUnlockObserver() {
165  chromeos::ScreenLocker* screen_locker =
166      chromeos::ScreenLocker::default_screen_locker();
167  if (screen_locker)
168    screen_locker->SetLoginStatusConsumer(NULL);
169}
170
171void ScreenUnlockObserver::OnLoginFailure(const chromeos::LoginFailure& error) {
172  if (automation_) {
173    scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
174    return_value->SetString("error_string", error.GetErrorString());
175    AutomationJSONReply(automation_.get(), reply_message_.release())
176        .SendSuccess(return_value.get());
177  }
178  delete this;
179}
180