1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <stdio.h>
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/at_exit.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/cancelable_callback.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/command_line.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "base/run_loop.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_split.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_util.h"
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/stringprintf.h"
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/wifi/wifi_service.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_MACOSX)
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/mac/scoped_nsautorelease_pool.h"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace wifi {
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class WiFiTest {
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WiFiTest() {}
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ~WiFiTest() {}
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  enum Result {
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RESULT_ERROR = -2,
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RESULT_WRONG_USAGE = -1,
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RESULT_OK = 0,
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RESULT_PENDING = 1,
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Result Main(int argc, const char* argv[]);
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool ParseCommandLine(int argc, const char* argv[]);
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Start() {}
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Finish(Result result) {
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_NE(RESULT_PENDING, result);
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    result_ = result;
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (base::MessageLoop::current())
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::MessageLoop::current()->Quit();
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void OnNetworksChanged(
575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const WiFiService::NetworkGuidList& network_guid_list) {
585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    VLOG(0) << "Networks Changed: " << network_guid_list[0];
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::DictionaryValue properties;
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    std::string error;
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    wifi_service_->GetProperties(network_guid_list[0], &properties, &error);
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    VLOG(0) << error << ":\n" << properties;
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void OnNetworkListChanged(
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      const WiFiService::NetworkGuidList& network_guid_list) {
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    VLOG(0) << "Network List Changed: " << network_guid_list.size();
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_MACOSX)
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Without this there will be a mem leak on osx.
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::mac::ScopedNSAutoreleasePool scoped_pool_;
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<WiFiService> wifi_service_;
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Need AtExitManager to support AsWeakPtr (in NetLog).
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::AtExitManager exit_manager_;
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Result result_;
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WiFiTest::Result WiFiTest::Main(int argc, const char* argv[]) {
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!ParseCommandLine(argc, argv)) {
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    VLOG(0) <<  "Usage: " << argv[0] <<
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                " [--list]"
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                " [--get_key]"
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                " [--get_properties]"
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                " [--create]"
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                " [--connect]"
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                " [--disconnect]"
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                " [--scan]"
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                " [--network_guid=<network_guid>]"
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                " [--frequency=0|2400|5000]"
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                " [--security=none|WEP-PSK|WPA-PSK|WPA2-PSK]"
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                " [--password=<wifi_password>]"
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                " [<network_guid>]\n";
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return RESULT_WRONG_USAGE;
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoopForIO loop;
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  result_ = RESULT_PENDING;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return result_;
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool WiFiTest::ParseCommandLine(int argc, const char* argv[]) {
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CommandLine::Init(argc, argv);
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string network_guid =
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      parsed_command_line.GetSwitchValueASCII("network_guid");
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string frequency =
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      parsed_command_line.GetSwitchValueASCII("frequency");
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string password =
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      parsed_command_line.GetSwitchValueASCII("password");
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string security =
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      parsed_command_line.GetSwitchValueASCII("security");
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (parsed_command_line.GetArgs().size() == 1) {
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    network_guid = base::UTF16ToASCII(parsed_command_line.GetArgs()[0]);
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    network_guid = parsed_command_line.GetArgs()[0];
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_WIN)
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (parsed_command_line.HasSwitch("debug"))
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MessageBoxA(NULL, __FUNCTION__, "Debug Me!", MB_OK);
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::MessageLoopForIO loop;
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  wifi_service_.reset(WiFiService::Create());
1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  wifi_service_->Initialize(loop.message_loop_proxy());
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (parsed_command_line.HasSwitch("list")) {
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue network_list;
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    wifi_service_->GetVisibleNetworks(std::string(), &network_list, true);
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    VLOG(0) << network_list;
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (parsed_command_line.HasSwitch("get_properties")) {
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (network_guid.length() > 0) {
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::DictionaryValue properties;
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      std::string error;
1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      wifi_service_->GetProperties(network_guid, &properties, &error);
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      VLOG(0) << error << ":\n" << properties;
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Optional properties (frequency, password) to use for connect or create.
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> properties(new base::DictionaryValue());
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!frequency.empty()) {
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int value = 0;
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (base::StringToInt(frequency, &value)) {
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      properties->SetInteger("WiFi.Frequency", value);
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // fall through to connect.
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!password.empty())
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    properties->SetString("WiFi.Passphrase", password);
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!security.empty())
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    properties->SetString("WiFi.Security", security);
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (parsed_command_line.HasSwitch("create")) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!network_guid.empty()) {
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string error;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string new_network_guid;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      properties->SetString("WiFi.SSID", network_guid);
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VLOG(0) << "Creating Network: " << *properties;
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      wifi_service_->CreateNetwork(
1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          false, properties.Pass(), &new_network_guid, &error);
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VLOG(0) << error << ":\n" << new_network_guid;
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (parsed_command_line.HasSwitch("connect")) {
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!network_guid.empty()) {
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      std::string error;
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!properties->empty()) {
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        VLOG(0) << "Using connect properties: " << *properties;
1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        wifi_service_->SetProperties(network_guid, properties.Pass(), &error);
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      wifi_service_->SetEventObservers(
1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          loop.message_loop_proxy(),
1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          base::Bind(&WiFiTest::OnNetworksChanged, base::Unretained(this)),
1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          base::Bind(&WiFiTest::OnNetworkListChanged, base::Unretained(this)));
1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      wifi_service_->StartConnect(network_guid, &error);
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      VLOG(0) << error;
199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (error.empty())
200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        base::MessageLoop::current()->Run();
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (parsed_command_line.HasSwitch("disconnect")) {
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (network_guid.length() > 0) {
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      std::string error;
2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      wifi_service_->StartDisconnect(network_guid, &error);
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      VLOG(0) << error;
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return true;
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (parsed_command_line.HasSwitch("get_key")) {
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (network_guid.length() > 0) {
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string error;
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string key_data;
2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      wifi_service_->GetKeyFromSystem(network_guid, &key_data, &error);
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      VLOG(0) << key_data << error;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (parsed_command_line.HasSwitch("scan")) {
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    wifi_service_->SetEventObservers(
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        loop.message_loop_proxy(),
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&WiFiTest::OnNetworksChanged, base::Unretained(this)),
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&WiFiTest::OnNetworkListChanged, base::Unretained(this)));
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    wifi_service_->RequestNetworkScan();
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::MessageLoop::current()->Run();
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return true;
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace wifi
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int main(int argc, const char* argv[]) {
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CommandLine::Init(argc, argv);
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  logging::LoggingSettings settings;
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  logging::InitLogging(settings);
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  wifi::WiFiTest wifi_test;
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return wifi_test.Main(argc, argv);
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
248