Home | History | Annotate | Download | only in automation
      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 
     21 using chromeos::NetworkLibrary;
     22 using chromeos::WizardController;
     23 
     24 namespace {
     25 
     26 // Fake screen name for the user session (reported by WizardControllerObserver).
     27 const char kSessionScreenName[] = "session";
     28 
     29 }
     30 
     31 NetworkManagerInitObserver::NetworkManagerInitObserver(
     32     AutomationProvider* automation)
     33     : automation_(automation->AsWeakPtr()) {
     34 }
     35 
     36 NetworkManagerInitObserver::~NetworkManagerInitObserver() {
     37   NetworkLibrary::Get()->RemoveNetworkManagerObserver(this);
     38 }
     39 
     40 bool NetworkManagerInitObserver::Init() {
     41   if (!NetworkLibrary::Get()->IsCros()) {
     42     // If the network library is not the production version, don't wait for
     43     // the network library to finish initializing, because it'll wait
     44     // forever.
     45     automation_->OnNetworkLibraryInit();
     46     return false;
     47   }
     48 
     49   NetworkLibrary::Get()->AddNetworkManagerObserver(this);
     50   return true;
     51 }
     52 
     53 void NetworkManagerInitObserver::OnNetworkManagerChanged(NetworkLibrary* obj) {
     54   if (!obj->wifi_scanning()) {
     55     if (automation_)
     56       automation_->OnNetworkLibraryInit();
     57     delete this;
     58   }
     59 }
     60 
     61 OOBEWebuiReadyObserver::OOBEWebuiReadyObserver(AutomationProvider* automation)
     62     : automation_(automation->AsWeakPtr()) {
     63   if (WizardController::default_controller() &&
     64       WizardController::default_controller()->current_screen()) {
     65     OOBEWebuiReady();
     66   } else {
     67     registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
     68                    content::NotificationService::AllSources());
     69   }
     70 }
     71 
     72 void OOBEWebuiReadyObserver::Observe(
     73     int type,
     74     const content::NotificationSource& source,
     75     const content::NotificationDetails& details) {
     76   DCHECK(type == chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE);
     77   OOBEWebuiReady();
     78 }
     79 
     80 void OOBEWebuiReadyObserver::OOBEWebuiReady() {
     81   if (automation_)
     82     automation_->OnOOBEWebuiReady();
     83   delete this;
     84 }
     85 
     86 LoginObserver::LoginObserver(chromeos::ExistingUserController* controller,
     87                              AutomationProvider* automation,
     88                              IPC::Message* reply_message)
     89     : controller_(controller),
     90       automation_(automation->AsWeakPtr()),
     91       reply_message_(reply_message) {
     92   controller_->set_login_status_consumer(this);
     93 }
     94 
     95 LoginObserver::~LoginObserver() {
     96   controller_->set_login_status_consumer(NULL);
     97 }
     98 
     99 void LoginObserver::OnLoginFailure(const chromeos::LoginFailure& error) {
    100   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
    101   return_value->SetString("error_string", error.GetErrorString());
    102   AutomationJSONReply(automation_.get(), reply_message_.release())
    103       .SendSuccess(return_value.get());
    104   delete this;
    105 }
    106 
    107 void LoginObserver::OnLoginSuccess(
    108     const chromeos::UserContext& user_context,
    109     bool pending_requests,
    110     bool using_oauth) {
    111   controller_->set_login_status_consumer(NULL);
    112   AutomationJSONReply(automation_.get(), reply_message_.release())
    113       .SendSuccess(NULL);
    114   delete this;
    115 }
    116 
    117 WizardControllerObserver::WizardControllerObserver(
    118     WizardController* wizard_controller,
    119     AutomationProvider* automation,
    120     IPC::Message* reply_message)
    121     : wizard_controller_(wizard_controller),
    122       automation_(automation->AsWeakPtr()),
    123       reply_message_(reply_message) {
    124   wizard_controller_->AddObserver(this);
    125   registrar_.Add(this, chrome::NOTIFICATION_LOGIN_WEBUI_LOADED,
    126                  content::NotificationService::AllSources());
    127 }
    128 
    129 WizardControllerObserver::~WizardControllerObserver() {
    130   wizard_controller_->RemoveObserver(this);
    131 }
    132 
    133 void WizardControllerObserver::OnScreenChanged(
    134     chromeos::WizardScreen* next_screen) {
    135   std::string screen_name = next_screen->GetName();
    136   if (screen_to_wait_for_.empty() || screen_to_wait_for_ == screen_name) {
    137     SendReply(screen_name);
    138   } else {
    139     DVLOG(2) << "Still waiting for " << screen_to_wait_for_;
    140   }
    141 }
    142 
    143 void WizardControllerObserver::OnSessionStart() {
    144   SendReply(kSessionScreenName);
    145 }
    146 
    147 void WizardControllerObserver::Observe(
    148     int type,
    149     const content::NotificationSource& source,
    150     const content::NotificationDetails& details) {
    151   DCHECK(type == chrome::NOTIFICATION_LOGIN_WEBUI_LOADED);
    152   SendReply(WizardController::kLoginScreenName);
    153 }
    154 
    155 void WizardControllerObserver::SendReply(const std::string& screen_name) {
    156   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
    157   return_value->SetString("next_screen", screen_name);
    158   AutomationJSONReply(automation_.get(), reply_message_.release())
    159       .SendSuccess(return_value.get());
    160   delete this;
    161 }
    162 
    163 ScreenLockUnlockObserver::ScreenLockUnlockObserver(
    164     AutomationProvider* automation,
    165     IPC::Message* reply_message,
    166     bool lock_screen)
    167     : automation_(automation->AsWeakPtr()),
    168       reply_message_(reply_message),
    169       lock_screen_(lock_screen) {
    170   registrar_.Add(this, chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
    171                  content::NotificationService::AllSources());
    172 }
    173 
    174 ScreenLockUnlockObserver::~ScreenLockUnlockObserver() {}
    175 
    176 void ScreenLockUnlockObserver::Observe(
    177     int type,
    178     const content::NotificationSource& source,
    179     const content::NotificationDetails& details) {
    180   DCHECK(type == chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED);
    181   if (automation_) {
    182     AutomationJSONReply reply(automation_.get(), reply_message_.release());
    183     bool is_screen_locked = *content::Details<bool>(details).ptr();
    184     if (lock_screen_ == is_screen_locked)
    185       reply.SendSuccess(NULL);
    186     else
    187       reply.SendError("Screen lock failure.");
    188   }
    189   delete this;
    190 }
    191 
    192 ScreenUnlockObserver::ScreenUnlockObserver(AutomationProvider* automation,
    193                                            IPC::Message* reply_message)
    194     : ScreenLockUnlockObserver(automation, reply_message, false) {
    195   chromeos::ScreenLocker::default_screen_locker()->SetLoginStatusConsumer(this);
    196 }
    197 
    198 ScreenUnlockObserver::~ScreenUnlockObserver() {
    199   chromeos::ScreenLocker* screen_locker =
    200       chromeos::ScreenLocker::default_screen_locker();
    201   if (screen_locker)
    202     screen_locker->SetLoginStatusConsumer(NULL);
    203 }
    204 
    205 void ScreenUnlockObserver::OnLoginFailure(const chromeos::LoginFailure& error) {
    206   if (automation_) {
    207     scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
    208     return_value->SetString("error_string", error.GetErrorString());
    209     AutomationJSONReply(automation_.get(), reply_message_.release())
    210         .SendSuccess(return_value.get());
    211   }
    212   delete this;
    213 }
    214 
    215 NetworkScanObserver::NetworkScanObserver(AutomationProvider* automation,
    216                                          IPC::Message* reply_message)
    217     : automation_(automation->AsWeakPtr()), reply_message_(reply_message) {
    218   NetworkLibrary* network_library = NetworkLibrary::Get();
    219   network_library->AddNetworkManagerObserver(this);
    220 }
    221 
    222 NetworkScanObserver::~NetworkScanObserver() {
    223   NetworkLibrary* network_library = NetworkLibrary::Get();
    224   network_library->RemoveNetworkManagerObserver(this);
    225 }
    226 
    227 void NetworkScanObserver::OnNetworkManagerChanged(NetworkLibrary* obj) {
    228   if (obj->wifi_scanning())
    229     return;
    230 
    231   if (automation_) {
    232     AutomationJSONReply(automation_.get(), reply_message_.release())
    233         .SendSuccess(NULL);
    234   }
    235   delete this;
    236 }
    237 
    238 ToggleNetworkDeviceObserver::ToggleNetworkDeviceObserver(
    239     AutomationProvider* automation, IPC::Message* reply_message,
    240     const std::string& device, bool enable)
    241     : automation_(automation->AsWeakPtr()), reply_message_(reply_message),
    242       device_(device), enable_(enable) {
    243   NetworkLibrary* network_library = NetworkLibrary::Get();
    244   network_library->AddNetworkManagerObserver(this);
    245 }
    246 
    247 ToggleNetworkDeviceObserver::~ToggleNetworkDeviceObserver() {
    248   NetworkLibrary* network_library = NetworkLibrary::Get();
    249   network_library->RemoveNetworkManagerObserver(this);
    250 }
    251 
    252 void ToggleNetworkDeviceObserver::OnNetworkManagerChanged(NetworkLibrary* obj) {
    253   if ((device_ == "ethernet" && enable_ == obj->ethernet_enabled()) ||
    254       (device_ == "wifi" && enable_ == obj->wifi_enabled()) ||
    255       (device_ == "cellular" && enable_ == obj->cellular_enabled())) {
    256     if (automation_) {
    257       AutomationJSONReply(automation_.get(), reply_message_.release())
    258           .SendSuccess(NULL);
    259     }
    260     delete this;
    261   }
    262 }
    263 
    264 NetworkStatusObserver::NetworkStatusObserver(AutomationProvider* automation,
    265                                                IPC::Message* reply_message)
    266     : automation_(automation->AsWeakPtr()), reply_message_(reply_message) {
    267   NetworkLibrary* network_library = NetworkLibrary::Get();
    268   network_library->AddNetworkManagerObserver(this);
    269 }
    270 
    271 NetworkStatusObserver::~NetworkStatusObserver() {
    272   NetworkLibrary* network_library = NetworkLibrary::Get();
    273   network_library->RemoveNetworkManagerObserver(this);
    274 }
    275 
    276 void NetworkStatusObserver::OnNetworkManagerChanged(NetworkLibrary* obj) {
    277   const chromeos::Network* network = GetNetwork(obj);
    278   if (!network) {
    279     // The network was not found, and we assume it no longer exists.
    280     // This could be because the ssid is invalid, or the network went away.
    281     if (automation_) {
    282       scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
    283       return_value->SetString("error_string", "Network not found.");
    284       AutomationJSONReply(automation_.get(), reply_message_.release())
    285           .SendSuccess(return_value.get());
    286     }
    287     delete this;
    288     return;
    289   }
    290 
    291   NetworkStatusCheck(network);
    292 }
    293 
    294 NetworkConnectObserver::NetworkConnectObserver(
    295     AutomationProvider* automation, IPC::Message* reply_message)
    296     : NetworkStatusObserver(automation, reply_message) {}
    297 
    298 void NetworkConnectObserver::NetworkStatusCheck(const chromeos::Network*
    299                                                 network) {
    300   if (network->failed()) {
    301     if (automation_) {
    302       scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
    303       return_value->SetString("error_string", network->GetErrorString());
    304       AutomationJSONReply(automation_.get(), reply_message_.release())
    305           .SendSuccess(return_value.get());
    306     }
    307     delete this;
    308   } else if (network->connected()) {
    309     if (automation_) {
    310       AutomationJSONReply(automation_.get(), reply_message_.release())
    311           .SendSuccess(NULL);
    312     }
    313     delete this;
    314   }
    315 
    316   // The network is in the NetworkLibrary's list, but there's no failure or
    317   // success condition, so just continue waiting for more network events.
    318 }
    319 
    320 NetworkDisconnectObserver::NetworkDisconnectObserver(
    321     AutomationProvider* automation, IPC::Message* reply_message,
    322     const std::string& service_path)
    323     : NetworkStatusObserver(automation, reply_message),
    324       service_path_(service_path) {}
    325 
    326 void NetworkDisconnectObserver::NetworkStatusCheck(const chromeos::Network*
    327                                                    network) {
    328   if (!network->connected()) {
    329       AutomationJSONReply(automation_.get(), reply_message_.release())
    330           .SendSuccess(NULL);
    331       delete this;
    332   }
    333 }
    334 
    335 const chromeos::Network* NetworkDisconnectObserver::GetNetwork(
    336     NetworkLibrary* network_library) {
    337   return network_library->FindNetworkByPath(service_path_);
    338 }
    339 
    340 ServicePathConnectObserver::ServicePathConnectObserver(
    341     AutomationProvider* automation, IPC::Message* reply_message,
    342     const std::string& service_path)
    343     : NetworkConnectObserver(automation, reply_message),
    344       service_path_(service_path) {}
    345 
    346 const chromeos::Network* ServicePathConnectObserver::GetNetwork(
    347     NetworkLibrary* network_library) {
    348   return network_library->FindNetworkByPath(service_path_);
    349 }
    350 
    351 SSIDConnectObserver::SSIDConnectObserver(
    352     AutomationProvider* automation, IPC::Message* reply_message,
    353     const std::string& ssid)
    354     : NetworkConnectObserver(automation, reply_message), ssid_(ssid) {}
    355 
    356 const chromeos::Network* SSIDConnectObserver::GetNetwork(
    357     NetworkLibrary* network_library) {
    358   const chromeos::WifiNetworkVector& wifi_networks =
    359       network_library->wifi_networks();
    360   for (chromeos::WifiNetworkVector::const_iterator iter = wifi_networks.begin();
    361        iter != wifi_networks.end(); ++iter) {
    362     const chromeos::WifiNetwork* wifi = *iter;
    363     if (wifi->name() == ssid_)
    364       return wifi;
    365   }
    366   return NULL;
    367 }
    368 
    369 VirtualConnectObserver::VirtualConnectObserver(AutomationProvider* automation,
    370                                                IPC::Message* reply_message,
    371                                                const std::string& service_name)
    372     : automation_(automation->AsWeakPtr()),
    373       reply_message_(reply_message),
    374       service_name_(service_name) {
    375   NetworkLibrary* network_library = NetworkLibrary::Get();
    376   network_library->AddNetworkManagerObserver(this);
    377 }
    378 
    379 VirtualConnectObserver::~VirtualConnectObserver() {
    380   NetworkLibrary* network_library = NetworkLibrary::Get();
    381   network_library->RemoveNetworkManagerObserver(this);
    382 }
    383 
    384 void VirtualConnectObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
    385   const chromeos::VirtualNetwork* virt = GetVirtualNetwork(cros);
    386   if (!virt) {
    387     // The network hasn't been added to the NetworkLibrary's list yet,
    388     // just continue waiting for more network events.
    389     return;
    390   }
    391 
    392   if (virt->failed()) {
    393     if (automation_) {
    394       scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
    395       return_value->SetString("error_string", virt->GetErrorString());
    396       AutomationJSONReply(automation_.get(), reply_message_.release())
    397           .SendSuccess(return_value.get());
    398     }
    399     delete this;
    400   } else if (virt->connected()) {
    401     if (automation_) {
    402       AutomationJSONReply(automation_.get(), reply_message_.release())
    403           .SendSuccess(NULL);
    404     }
    405     delete this;
    406   }
    407   // The network is in the NetworkLibrary's list, but there's no failure or
    408   // success condition, so just continue waiting for more network events.
    409 }
    410 
    411 chromeos::VirtualNetwork* VirtualConnectObserver::GetVirtualNetwork(
    412     const chromeos::NetworkLibrary* cros) {
    413   chromeos::VirtualNetwork* virt = NULL;
    414   const chromeos::VirtualNetworkVector& virtual_networks =
    415       cros->virtual_networks();
    416 
    417   for (chromeos::VirtualNetworkVector::const_iterator iter =
    418        virtual_networks.begin(); iter != virtual_networks.end(); ++iter) {
    419     chromeos::VirtualNetwork* v = *iter;
    420     if (v->name() == service_name_) {
    421       virt = v;
    422       break;
    423     }
    424   }
    425   return virt;
    426 }
    427