• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/testing_automation_provider.h"
6 
7 #include "base/values.h"
8 #include "chrome/browser/automation/automation_provider_json.h"
9 #include "chrome/browser/automation/automation_provider_observers.h"
10 #include "chrome/browser/chromeos/cros/cros_library.h"
11 #include "chrome/browser/chromeos/cros/network_library.h"
12 #include "chrome/browser/chromeos/cros/power_library.h"
13 #include "chrome/browser/chromeos/cros/screen_lock_library.h"
14 #include "chrome/browser/chromeos/cros/update_library.h"
15 #include "chrome/browser/chromeos/login/existing_user_controller.h"
16 #include "chrome/browser/chromeos/login/screen_locker.h"
17 #include "chrome/browser/chromeos/proxy_cros_settings_provider.h"
18 
19 using chromeos::CrosLibrary;
20 using chromeos::NetworkLibrary;
21 using chromeos::UserManager;
22 using chromeos::UpdateLibrary;
23 
24 namespace {
25 
EnsureCrosLibraryLoaded(AutomationProvider * provider,IPC::Message * reply_message)26 bool EnsureCrosLibraryLoaded(AutomationProvider* provider,
27                              IPC::Message* reply_message) {
28   if (!CrosLibrary::Get()->EnsureLoaded()) {
29     AutomationJSONReply(provider, reply_message).SendError(
30         "Could not load cros library.");
31     return false;
32   }
33   return true;
34 }
35 
GetNetworkInfoDict(const chromeos::Network * network)36 DictionaryValue* GetNetworkInfoDict(const chromeos::Network* network) {
37   DictionaryValue* item = new DictionaryValue;
38   item->SetString("name", network->name());
39   item->SetString("device_path", network->device_path());
40   item->SetString("ip_address", network->ip_address());
41   item->SetString("status", network->GetStateString());
42   return item;
43 }
44 
GetProxySetting(const std::string & setting_name)45 Value* GetProxySetting(const std::string& setting_name) {
46   chromeos::ProxyCrosSettingsProvider settings_provider;
47   std::string setting_path = "cros.session.proxy.";
48   setting_path.append(setting_name);
49 
50   if (setting_name == "ignorelist") {
51     Value* value;
52     if (settings_provider.Get(setting_path, &value))
53       return value;
54   } else {
55     Value* setting;
56     if (settings_provider.Get(setting_path, &setting)) {
57       DictionaryValue* setting_dict = static_cast<DictionaryValue*>(setting);
58       Value* value;
59       bool found = setting_dict->Remove("value", &value);
60       delete setting;
61       if (found)
62         return value;
63     }
64   }
65   return NULL;
66 }
67 
UpdateStatusToString(chromeos::UpdateStatusOperation status)68 const char* UpdateStatusToString(chromeos::UpdateStatusOperation status) {
69   switch (status) {
70     case chromeos::UPDATE_STATUS_IDLE:
71       return "idle";
72     case chromeos::UPDATE_STATUS_CHECKING_FOR_UPDATE:
73       return "checking for update";
74     case chromeos::UPDATE_STATUS_UPDATE_AVAILABLE:
75       return "update available";
76     case chromeos::UPDATE_STATUS_DOWNLOADING:
77       return "downloading";
78     case chromeos::UPDATE_STATUS_VERIFYING:
79       return "verifying";
80     case chromeos::UPDATE_STATUS_FINALIZING:
81       return "finalizing";
82     case chromeos::UPDATE_STATUS_UPDATED_NEED_REBOOT:
83       return "updated need reboot";
84     case chromeos::UPDATE_STATUS_REPORTING_ERROR_EVENT:
85       return "reporting error event";
86     default:
87       return "unknown";
88   }
89 }
90 
GetReleaseTrackCallback(void * user_data,const char * track)91 void GetReleaseTrackCallback(void* user_data, const char* track) {
92   AutomationJSONReply* reply = static_cast<AutomationJSONReply*>(user_data);
93 
94   if (track == NULL) {
95     reply->SendError("Unable to get release track.");
96     delete reply;
97     return;
98   }
99 
100   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
101   return_value->SetString("release_track", track);
102 
103   UpdateLibrary* update_library = CrosLibrary::Get()->GetUpdateLibrary();
104   const UpdateLibrary::Status& status = update_library->status();
105   chromeos::UpdateStatusOperation update_status = status.status;
106   return_value->SetString("status", UpdateStatusToString(update_status));
107   if (update_status == chromeos::UPDATE_STATUS_DOWNLOADING)
108     return_value->SetDouble("download_progress", status.download_progress);
109   if (status.last_checked_time > 0)
110     return_value->SetInteger("last_checked_time", status.last_checked_time);
111   if (status.new_size > 0)
112     return_value->SetInteger("new_size", status.new_size);
113 
114   reply->SendSuccess(return_value.get());
115   delete reply;
116 }
117 
UpdateCheckCallback(void * user_data,chromeos::UpdateResult result,const char * error_msg)118 void UpdateCheckCallback(void* user_data, chromeos::UpdateResult result,
119                          const char* error_msg) {
120   AutomationJSONReply* reply = static_cast<AutomationJSONReply*>(user_data);
121   if (result == chromeos::UPDATE_RESULT_SUCCESS)
122     reply->SendSuccess(NULL);
123   else
124     reply->SendError(error_msg);
125   delete reply;
126 }
127 
128 }  // namespace
129 
GetLoginInfo(DictionaryValue * args,IPC::Message * reply_message)130 void TestingAutomationProvider::GetLoginInfo(DictionaryValue* args,
131                                              IPC::Message* reply_message) {
132   AutomationJSONReply reply(this, reply_message);
133   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
134 
135   const UserManager* user_manager = UserManager::Get();
136   if (!user_manager)
137     reply.SendError("No user manager!");
138   const chromeos::ScreenLocker* screen_locker =
139       chromeos::ScreenLocker::default_screen_locker();
140 
141   return_value->SetBoolean("is_owner", user_manager->current_user_is_owner());
142   return_value->SetBoolean("is_logged_in", user_manager->user_is_logged_in());
143   return_value->SetBoolean("is_screen_locked", screen_locker);
144   if (user_manager->user_is_logged_in()) {
145     return_value->SetBoolean("is_guest", user_manager->IsLoggedInAsGuest());
146     return_value->SetString("email", user_manager->logged_in_user().email());
147   }
148 
149   reply.SendSuccess(return_value.get());
150 }
151 
152 // Logging in as guest will cause session_manager to restart Chrome with new
153 // flags. If you used EnableChromeTesting, you will have to call it again.
LoginAsGuest(DictionaryValue * args,IPC::Message * reply_message)154 void TestingAutomationProvider::LoginAsGuest(DictionaryValue* args,
155                                              IPC::Message* reply_message) {
156   chromeos::ExistingUserController* controller =
157       chromeos::ExistingUserController::current_controller();
158   // Set up an observer (it will delete itself).
159   new LoginManagerObserver(this, reply_message);
160   controller->LoginAsGuest();
161 }
162 
Login(DictionaryValue * args,IPC::Message * reply_message)163 void TestingAutomationProvider::Login(DictionaryValue* args,
164                                       IPC::Message* reply_message) {
165   std::string username, password;
166   if (!args->GetString("username", &username) ||
167       !args->GetString("password", &password)) {
168     AutomationJSONReply(this, reply_message).SendError(
169         "Invalid or missing args.");
170     return;
171   }
172 
173   chromeos::ExistingUserController* controller =
174       chromeos::ExistingUserController::current_controller();
175   // Set up an observer (it will delete itself).
176   new LoginManagerObserver(this, reply_message);
177   controller->Login(username, password);
178 }
179 
LockScreen(DictionaryValue * args,IPC::Message * reply_message)180 void TestingAutomationProvider::LockScreen(DictionaryValue* args,
181                                            IPC::Message* reply_message) {
182   if (!EnsureCrosLibraryLoaded(this, reply_message))
183     return;
184 
185   new ScreenLockUnlockObserver(this, reply_message, true);
186   CrosLibrary::Get()->GetScreenLockLibrary()->
187       NotifyScreenLockRequested();
188 }
189 
UnlockScreen(DictionaryValue * args,IPC::Message * reply_message)190 void TestingAutomationProvider::UnlockScreen(DictionaryValue* args,
191                                              IPC::Message* reply_message) {
192   if (!EnsureCrosLibraryLoaded(this, reply_message))
193     return;
194 
195   new ScreenLockUnlockObserver(this, reply_message, false);
196   CrosLibrary::Get()->GetScreenLockLibrary()->
197       NotifyScreenUnlockRequested();
198 }
199 
200 // Signing out could have undesirable side effects: session_manager is
201 // killed, so its children, including chrome and the window manager, will
202 // also be killed. Anything owned by chronos will probably be killed.
SignoutInScreenLocker(DictionaryValue * args,IPC::Message * reply_message)203 void TestingAutomationProvider::SignoutInScreenLocker(
204     DictionaryValue* args, IPC::Message* reply_message) {
205   AutomationJSONReply reply(this, reply_message);
206   chromeos::ScreenLocker* screen_locker =
207       chromeos::ScreenLocker::default_screen_locker();
208   if (!screen_locker) {
209     reply.SendError(
210         "No default screen locker. Are you sure the screen is locked?");
211     return;
212   }
213 
214   // Send success before stopping session because if we're a child of
215   // session manager then we'll die when the session is stopped.
216   reply.SendSuccess(NULL);
217   screen_locker->Signout();
218 }
219 
GetBatteryInfo(DictionaryValue * args,IPC::Message * reply_message)220 void TestingAutomationProvider::GetBatteryInfo(DictionaryValue* args,
221                                                IPC::Message* reply_message) {
222   if (!EnsureCrosLibraryLoaded(this, reply_message))
223     return;
224 
225   chromeos::PowerLibrary* power_library = CrosLibrary::Get()->GetPowerLibrary();
226   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
227 
228   return_value->SetBoolean("battery_is_present",
229                            power_library->battery_is_present());
230   return_value->SetBoolean("line_power_on", power_library->line_power_on());
231   if (power_library->battery_is_present()) {
232     return_value->SetBoolean("battery_fully_charged",
233                              power_library->battery_fully_charged());
234     return_value->SetDouble("battery_percentage",
235                             power_library->battery_percentage());
236     if (power_library->line_power_on()) {
237       int time = power_library->battery_time_to_full().InSeconds();
238       if (time > 0 || power_library->battery_fully_charged())
239         return_value->SetInteger("battery_time_to_full", time);
240     } else {
241       int time = power_library->battery_time_to_empty().InSeconds();
242       if (time > 0)
243         return_value->SetInteger("battery_time_to_empty", time);
244     }
245   }
246 
247   AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
248 }
249 
GetNetworkInfo(DictionaryValue * args,IPC::Message * reply_message)250 void TestingAutomationProvider::GetNetworkInfo(DictionaryValue* args,
251                                                IPC::Message* reply_message) {
252   if (!EnsureCrosLibraryLoaded(this, reply_message))
253     return;
254 
255   NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
256   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
257 
258   // IP address.
259   return_value->SetString("ip_address", network_library->IPAddress());
260 
261   // Currently connected networks.
262   if (network_library->ethernet_network())
263     return_value->SetString(
264         "connected_ethernet",
265         network_library->ethernet_network()->service_path());
266   if (network_library->wifi_network())
267     return_value->SetString("connected_wifi",
268                             network_library->wifi_network()->service_path());
269   if (network_library->cellular_network())
270     return_value->SetString(
271         "connected_cellular",
272         network_library->cellular_network()->service_path());
273 
274   // Ethernet network.
275   bool ethernet_available = network_library->ethernet_available();
276   bool ethernet_enabled = network_library->ethernet_enabled();
277   if (ethernet_available && ethernet_enabled) {
278     const chromeos::EthernetNetwork* ethernet_network =
279         network_library->ethernet_network();
280     if (ethernet_network) {
281       DictionaryValue* items = new DictionaryValue;
282       DictionaryValue* item = GetNetworkInfoDict(ethernet_network);
283       items->Set(ethernet_network->service_path(), item);
284       return_value->Set("ethernet_networks", items);
285     }
286   }
287 
288   // Wi-fi networks.
289   bool wifi_available = network_library->wifi_available();
290   bool wifi_enabled = network_library->wifi_enabled();
291   if (wifi_available && wifi_enabled) {
292     const chromeos::WifiNetworkVector& wifi_networks =
293         network_library->wifi_networks();
294     DictionaryValue* items = new DictionaryValue;
295     for (chromeos::WifiNetworkVector::const_iterator iter =
296          wifi_networks.begin(); iter != wifi_networks.end(); ++iter) {
297       const chromeos::WifiNetwork* wifi = *iter;
298       DictionaryValue* item = GetNetworkInfoDict(wifi);
299       item->SetInteger("strength", wifi->strength());
300       item->SetBoolean("encrypted", wifi->encrypted());
301       item->SetString("encryption", wifi->GetEncryptionString());
302       items->Set(wifi->service_path(), item);
303     }
304     return_value->Set("wifi_networks", items);
305   }
306 
307   // Cellular networks.
308   bool cellular_available = network_library->cellular_available();
309   bool cellular_enabled = network_library->cellular_enabled();
310   if (cellular_available && cellular_enabled) {
311     const chromeos::CellularNetworkVector& cellular_networks =
312         network_library->cellular_networks();
313     DictionaryValue* items = new DictionaryValue;
314     for (size_t i = 0; i < cellular_networks.size(); ++i) {
315       DictionaryValue* item = GetNetworkInfoDict(cellular_networks[i]);
316       item->SetInteger("strength", cellular_networks[i]->strength());
317       item->SetString("operator_name", cellular_networks[i]->operator_name());
318       item->SetString("operator_code", cellular_networks[i]->operator_code());
319       item->SetString("payment_url", cellular_networks[i]->payment_url());
320       item->SetString("usage_url", cellular_networks[i]->usage_url());
321       item->SetString("network_technology",
322                       cellular_networks[i]->GetNetworkTechnologyString());
323       item->SetString("connectivity_state",
324                       cellular_networks[i]->GetConnectivityStateString());
325       item->SetString("activation_state",
326                       cellular_networks[i]->GetActivationStateString());
327       item->SetString("roaming_state",
328                       cellular_networks[i]->GetRoamingStateString());
329       items->Set(cellular_networks[i]->service_path(), item);
330     }
331     return_value->Set("cellular_networks", items);
332   }
333 
334   AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
335 }
336 
NetworkScan(DictionaryValue * args,IPC::Message * reply_message)337 void TestingAutomationProvider::NetworkScan(DictionaryValue* args,
338                                             IPC::Message* reply_message) {
339   if (!EnsureCrosLibraryLoaded(this, reply_message))
340     return;
341 
342   NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
343   network_library->RequestNetworkScan();
344 
345   // Set up an observer (it will delete itself).
346   new NetworkScanObserver(this, reply_message);
347 }
348 
GetProxySettings(DictionaryValue * args,IPC::Message * reply_message)349 void TestingAutomationProvider::GetProxySettings(DictionaryValue* args,
350                                                  IPC::Message* reply_message) {
351   const char* settings[] = { "pacurl", "singlehttp", "singlehttpport",
352                              "httpurl", "httpport", "httpsurl", "httpsport",
353                              "type", "single", "ftpurl", "ftpport",
354                              "socks", "socksport", "ignorelist" };
355 
356   scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
357   chromeos::ProxyCrosSettingsProvider settings_provider;
358 
359   for (size_t i = 0; i < arraysize(settings); ++i) {
360     Value* setting = GetProxySetting(settings[i]);
361     if (setting)
362       return_value->Set(settings[i], setting);
363   }
364 
365   AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
366 }
367 
SetProxySettings(DictionaryValue * args,IPC::Message * reply_message)368 void TestingAutomationProvider::SetProxySettings(DictionaryValue* args,
369                                                 IPC::Message* reply_message) {
370   AutomationJSONReply reply(this, reply_message);
371   std::string key;
372   Value* value;
373   if (!args->GetString("key", &key) || !args->Get("value", &value)) {
374     reply.SendError("Invalid or missing args.");
375     return;
376   }
377 
378   std::string setting_path = "cros.session.proxy.";
379   setting_path.append(key);
380 
381   // ProxyCrosSettingsProvider will own the Value* passed to Set().
382   chromeos::ProxyCrosSettingsProvider().Set(setting_path, value->DeepCopy());
383   reply.SendSuccess(NULL);
384 }
385 
ConnectToWifiNetwork(DictionaryValue * args,IPC::Message * reply_message)386 void TestingAutomationProvider::ConnectToWifiNetwork(
387     DictionaryValue* args, IPC::Message* reply_message) {
388   if (!EnsureCrosLibraryLoaded(this, reply_message))
389     return;
390 
391   AutomationJSONReply reply(this, reply_message);
392   std::string service_path, password, identity, certpath;
393   if (!args->GetString("service_path", &service_path) ||
394       !args->GetString("password", &password) ||
395       !args->GetString("identity", &identity) ||
396       !args->GetString("certpath", &certpath)) {
397     reply.SendError("Invalid or missing args.");
398     return;
399   }
400 
401   NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
402   chromeos::WifiNetwork* wifi =
403       network_library->FindWifiNetworkByPath(service_path);
404   if (!wifi) {
405     reply.SendError("No network found with specified service path.");
406     return;
407   }
408   if (!password.empty())
409     wifi->SetPassphrase(password);
410   if (!identity.empty())
411     wifi->SetIdentity(identity);
412   if (!certpath.empty())
413     wifi->SetCertPath(certpath);
414 
415   // Set up an observer (it will delete itself).
416   new ServicePathConnectObserver(this, reply_message, service_path);
417 
418   network_library->ConnectToWifiNetwork(wifi);
419   network_library->RequestNetworkScan();
420 }
421 
ConnectToHiddenWifiNetwork(DictionaryValue * args,IPC::Message * reply_message)422 void TestingAutomationProvider::ConnectToHiddenWifiNetwork(
423     DictionaryValue* args, IPC::Message* reply_message) {
424   if (!CrosLibrary::Get()->EnsureLoaded()) {
425     AutomationJSONReply(this, reply_message)
426         .SendError("Could not load cros library.");
427     return;
428   }
429 
430   std::string ssid, security, password, identity, certpath;
431   if (!args->GetString("ssid", &ssid) ||
432       !args->GetString("security", &security) ||
433       !args->GetString("password", &password) ||
434       !args->GetString("identity", &identity) ||
435       !args->GetString("certpath", &certpath)) {
436     AutomationJSONReply(this, reply_message)
437         .SendError("Invalid or missing args.");
438     return;
439   }
440 
441   std::map<std::string, chromeos::ConnectionSecurity> connection_security_map;
442   connection_security_map["SECURITY_NONE"] = chromeos::SECURITY_NONE;
443   connection_security_map["SECURITY_WEP"] = chromeos::SECURITY_WEP;
444   connection_security_map["SECURITY_WPA"] = chromeos::SECURITY_WPA;
445   connection_security_map["SECURITY_RSN"] = chromeos::SECURITY_RSN;
446   connection_security_map["SECURITY_8021X"] = chromeos::SECURITY_8021X;
447 
448   if (connection_security_map.find(security) == connection_security_map.end()) {
449     AutomationJSONReply(this, reply_message)
450         .SendError("Unknown security type.");
451     return;
452   }
453   chromeos::ConnectionSecurity connection_security =
454       connection_security_map[security];
455 
456   NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
457 
458   // Set up an observer (it will delete itself).
459   new SSIDConnectObserver(this, reply_message, ssid);
460 
461   network_library->ConnectToWifiNetwork(connection_security, ssid, password,
462                                         identity, certpath);
463 }
464 
DisconnectFromWifiNetwork(DictionaryValue * args,IPC::Message * reply_message)465 void TestingAutomationProvider::DisconnectFromWifiNetwork(
466     DictionaryValue* args, IPC::Message* reply_message) {
467   if (!EnsureCrosLibraryLoaded(this, reply_message))
468     return;
469 
470   AutomationJSONReply reply(this, reply_message);
471   NetworkLibrary* network_library = CrosLibrary::Get()->GetNetworkLibrary();
472   const chromeos::WifiNetwork* wifi = network_library->wifi_network();
473   if (!wifi) {
474     reply.SendError("Not connected to any wifi network.");
475     return;
476   }
477 
478   network_library->DisconnectFromNetwork(wifi);
479   reply.SendSuccess(NULL);
480 }
481 
GetUpdateInfo(DictionaryValue * args,IPC::Message * reply_message)482 void TestingAutomationProvider::GetUpdateInfo(DictionaryValue* args,
483                                               IPC::Message* reply_message) {
484   if (!EnsureCrosLibraryLoaded(this, reply_message))
485     return;
486 
487   UpdateLibrary* update_library = CrosLibrary::Get()->GetUpdateLibrary();
488   AutomationJSONReply* reply = new AutomationJSONReply(this, reply_message);
489   update_library->GetReleaseTrack(GetReleaseTrackCallback, reply);
490 }
491 
UpdateCheck(DictionaryValue * args,IPC::Message * reply_message)492 void TestingAutomationProvider::UpdateCheck(
493     DictionaryValue* args,
494     IPC::Message* reply_message) {
495   if (!EnsureCrosLibraryLoaded(this, reply_message))
496     return;
497 
498   UpdateLibrary* update_library = CrosLibrary::Get()->GetUpdateLibrary();
499   AutomationJSONReply* reply = new AutomationJSONReply(this, reply_message);
500   update_library->RequestUpdateCheck(UpdateCheckCallback, reply);
501 }
502 
SetReleaseTrack(DictionaryValue * args,IPC::Message * reply_message)503 void TestingAutomationProvider::SetReleaseTrack(DictionaryValue* args,
504                                                 IPC::Message* reply_message) {
505   if (!EnsureCrosLibraryLoaded(this, reply_message))
506     return;
507 
508   AutomationJSONReply reply(this, reply_message);
509   std::string track;
510   if (!args->GetString("track", &track)) {
511     reply.SendError("Invalid or missing args.");
512     return;
513   }
514 
515   UpdateLibrary* update_library = CrosLibrary::Get()->GetUpdateLibrary();
516   update_library->SetReleaseTrack(track);
517   reply.SendSuccess(NULL);
518 }
519