Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / apps / shell / browser / shell_network_controller_chromeos.cc
1 // Copyright 2014 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 "apps/shell/browser/shell_network_controller_chromeos.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/time/time.h"
12 #include "chromeos/network/network_connection_handler.h"
13 #include "chromeos/network/network_handler.h"
14 #include "chromeos/network/network_handler_callbacks.h"
15 #include "chromeos/network/network_state.h"
16 #include "chromeos/network/network_state_handler.h"
17 #include "chromeos/network/shill_property_util.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19
20 namespace apps {
21
22 namespace {
23
24 // Frequency at which networks should be scanned when not connected.
25 const int kScanIntervalSec = 10;
26
27 void HandleEnableWifiError(
28     const std::string& error_name,
29     scoped_ptr<base::DictionaryValue> error_data) {
30   LOG(WARNING) << "Unable to enable wifi: " << error_name;
31 }
32
33 // Returns a human-readable name for the network described by |state|.
34 std::string GetNetworkName(const chromeos::NetworkState& state) {
35   return !state.name().empty() ? state.name() :
36       base::StringPrintf("[%s]", state.type().c_str());
37 }
38
39 // Returns true if shill is either connected or connecting to a network.
40 bool IsConnectedOrConnecting() {
41   chromeos::NetworkStateHandler* state_handler =
42       chromeos::NetworkHandler::Get()->network_state_handler();
43   return state_handler->ConnectedNetworkByType(
44              chromeos::NetworkTypePattern::Default()) ||
45          state_handler->ConnectingNetworkByType(
46              chromeos::NetworkTypePattern::Default());
47 }
48
49 }  // namespace
50
51 ShellNetworkController::ShellNetworkController()
52     : waiting_for_connection_result_(false),
53       weak_ptr_factory_(this) {
54   chromeos::NetworkHandler::Initialize();
55   chromeos::NetworkStateHandler* state_handler =
56       chromeos::NetworkHandler::Get()->network_state_handler();
57   DCHECK(state_handler);
58   state_handler->AddObserver(this, FROM_HERE);
59   state_handler->SetTechnologyEnabled(
60       chromeos::NetworkTypePattern::Primitive(shill::kTypeWifi),
61       true, base::Bind(&HandleEnableWifiError));
62
63   if (!IsConnectedOrConnecting()) {
64     RequestScan();
65     SetScanningEnabled(true);
66     ConnectIfUnconnected();
67   }
68 }
69
70 ShellNetworkController::~ShellNetworkController() {
71   chromeos::NetworkHandler::Get()->network_state_handler()->RemoveObserver(
72       this, FROM_HERE);
73   chromeos::NetworkHandler::Shutdown();
74 }
75
76 void ShellNetworkController::NetworkListChanged() {
77   VLOG(1) << "Network list changed";
78   ConnectIfUnconnected();
79 }
80
81 void ShellNetworkController::DefaultNetworkChanged(
82     const chromeos::NetworkState* state) {
83   if (state) {
84     VLOG(1) << "Default network state changed:"
85             << " name=" << GetNetworkName(*state)
86             << " path=" << state->path()
87             << " state=" << state->connection_state();
88   } else {
89     VLOG(1) << "Default network state changed: [no network]";
90   }
91
92   if (IsConnectedOrConnecting()) {
93     SetScanningEnabled(false);
94   } else {
95     SetScanningEnabled(true);
96     ConnectIfUnconnected();
97   }
98 }
99
100 void ShellNetworkController::SetScanningEnabled(bool enabled) {
101   const bool currently_enabled = scan_timer_.IsRunning();
102   if (enabled == currently_enabled)
103     return;
104
105   VLOG(1) << (enabled ? "Starting" : "Stopping") << " scanning";
106   if (enabled) {
107     scan_timer_.Start(FROM_HERE,
108                       base::TimeDelta::FromSeconds(kScanIntervalSec),
109                       this, &ShellNetworkController::RequestScan);
110   } else {
111     scan_timer_.Stop();
112   }
113 }
114
115 void ShellNetworkController::RequestScan() {
116   VLOG(1) << "Requesting scan";
117   chromeos::NetworkHandler::Get()->network_state_handler()->RequestScan();
118 }
119
120 // Attempts to connect to an available network if not already connecting or
121 // connected.
122 void ShellNetworkController::ConnectIfUnconnected() {
123   chromeos::NetworkHandler* handler = chromeos::NetworkHandler::Get();
124   DCHECK(handler);
125   if (waiting_for_connection_result_ || IsConnectedOrConnecting())
126     return;
127
128   chromeos::NetworkStateHandler::NetworkStateList state_list;
129   handler->network_state_handler()->GetNetworkListByType(
130       chromeos::NetworkTypePattern::WiFi(), &state_list);
131   for (chromeos::NetworkStateHandler::NetworkStateList::const_iterator it =
132        state_list.begin(); it != state_list.end(); ++it) {
133     const chromeos::NetworkState* state = *it;
134     DCHECK(state);
135     if (!state->connectable())
136       continue;
137
138     VLOG(1) << "Connecting to network " << GetNetworkName(*state)
139             << " with path " << state->path() << " and strength "
140             << state->signal_strength();
141     waiting_for_connection_result_ = true;
142     handler->network_connection_handler()->ConnectToNetwork(
143         state->path(),
144         base::Bind(&ShellNetworkController::HandleConnectionSuccess,
145                    weak_ptr_factory_.GetWeakPtr()),
146         base::Bind(&ShellNetworkController::HandleConnectionError,
147                    weak_ptr_factory_.GetWeakPtr()),
148         false /* check_error_state */);
149
150     return;
151   }
152
153   VLOG(1) << "Didn't find any connectable networks";
154 }
155
156 void ShellNetworkController::HandleConnectionSuccess() {
157   VLOG(1) << "Successfully connected to network";
158   waiting_for_connection_result_ = false;
159 }
160
161 void ShellNetworkController::HandleConnectionError(
162     const std::string& error_name,
163     scoped_ptr<base::DictionaryValue> error_data) {
164   LOG(WARNING) << "Unable to connect to network: " << error_name;
165   waiting_for_connection_result_ = false;
166 }
167
168 }  // namespace apps