summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstevenjb@google.com <stevenjb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-15 06:40:33 +0000
committerstevenjb@google.com <stevenjb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-15 06:40:33 +0000
commitc364790639ff2ac3ea6ec187cd71ce2908b76548 (patch)
tree0ea4f83a66bb3526da0b849a3e7cdd2c0257568b
parent0c6f3b0c5f6409496fcecab0819b062f36d9b113 (diff)
downloadchromium_src-c364790639ff2ac3ea6ec187cd71ce2908b76548.zip
chromium_src-c364790639ff2ac3ea6ec187cd71ce2908b76548.tar.gz
chromium_src-c364790639ff2ac3ea6ec187cd71ce2908b76548.tar.bz2
Add VPN UI
* Add 'Private networks' submenu to the network menu, which lists active virtual networks and has 'Add private network...' item * Settings UI is incomplete and currently consists only of an overlay badge on the active wireless network when there is an active VPN. Note: Code is ready for review, but requires changes to flimflam to be testable. BUG=chromium-os:11815 TEST=Test conencting to PSK and OpenVPN networks Review URL: http://codereview.chromium.org/6733013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81710 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd54
-rw-r--r--chrome/browser/about_flags.cc12
-rw-r--r--chrome/browser/automation/testing_automation_provider_chromeos.cc4
-rw-r--r--chrome/browser/browser_about_handler.cc173
-rw-r--r--chrome/browser/chromeos/cros/mock_network_library.h17
-rw-r--r--chrome/browser/chromeos/cros/network_library.cc779
-rw-r--r--chrome/browser/chromeos/cros/network_library.h149
-rw-r--r--chrome/browser/chromeos/network_login_observer.cc55
-rw-r--r--chrome/browser/chromeos/network_login_observer.h9
-rw-r--r--chrome/browser/chromeos/network_message_observer.cc112
-rw-r--r--chrome/browser/chromeos/network_message_observer.h13
-rw-r--r--chrome/browser/chromeos/options/network_config_view.cc49
-rw-r--r--chrome/browser/chromeos/options/network_config_view.h53
-rw-r--r--chrome/browser/chromeos/options/vpn_config_view.cc443
-rw-r--r--chrome/browser/chromeos/options/vpn_config_view.h125
-rw-r--r--chrome/browser/chromeos/options/wifi_config_view.cc54
-rw-r--r--chrome/browser/chromeos/options/wifi_config_view.h19
-rw-r--r--chrome/browser/chromeos/status/network_menu.cc882
-rw-r--r--chrome/browser/chromeos/status/network_menu.h220
-rw-r--r--chrome/browser/chromeos/status/network_menu_button.cc55
-rw-r--r--chrome/browser/chromeos/status/network_menu_button.h21
-rw-r--r--chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc16
-rw-r--r--chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc94
-rw-r--r--chrome/browser/ui/webui/options/chromeos/internet_options_handler.h4
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
27 files changed, 2516 insertions, 902 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 6bd79c4..2ff3b9c 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4213,6 +4213,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_EAP_DESCRIPTION" desc="Description of the 'Experimental Wi-Fi EAP methods' lab.">
Experimental support for additional Wi-Fi Extensible Authentication Protocol methods, such as EAP-TLS and LEAP.
</message>
+ <message name="IDS_FLAGS_ENABLE_VPN_NAME" desc="Title for the flag to enable VPN support">
+ VPN support
+ </message>
+ <message name="IDS_FLAGS_ENABLE_VPN_DESCRIPTION" desc="Description for the flag to enable VPN support">
+ Show Private networks in the Network menu to enable conencting to a VPN.
+ </message>
<!-- Crashes -->
<message name="IDS_CRASHES_TITLE" desc="Title for the chrome://crashes page.">
@@ -9848,6 +9854,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS" desc="The title for the dialog to join a wifi network.">
Join Wi-Fi network
</message>
+ <message name="IDS_OPTIONS_SETTINGS_ADD_VPN" desc="In the settings tab, the text on the button to add a private network.">
+ Add private network
+ </message>
<message name="IDS_OPTIONS_SETTINGS_ENABLE_DATA_ROAMING" desc="In the settings tab, the text next to the checkbox for data roaming.">
Allow mobile data roaming
</message>
@@ -10007,8 +10016,8 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PURCHASE_MORE" desc="In settings Internet options, the title for buy cellular data plan button.">
Buy data plan...
</message>
- <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_CREDENTIALS" desc="In settings Internet options, the label for invalid passphrase or identity input.">
- Password is too short or invalid.
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_UNKNOWN_ERROR" desc="In settings Internet options, the label for an unknown connection error.">
+ Failed to connect to network.
</message>
<message name="IDS_OPTIONS_SETTINGS_INTERNET_CELL_PLAN_NAME" desc="In settings Internet options, the label displayed next to cellular plan name.">
Plan name:
@@ -10094,6 +10103,36 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CONNECT_TITLE" desc="In settings Internet options, Title of the overlay when the user is not connected and can.">
Connect to network
</message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK" desc="In settings Internet options, a string specifying L2TP/IPSec + PSK.">
+ L2TP/IPSec + Pre-shared key
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT" desc="In settings Internet options, a string specifying L2TP/IPSec + User Certificate.">
+ L2TP/IPSec + User certificate
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN" desc="In settings Internet options, a string specifying OpenVPN.">
+ OpenVPN
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVICE_NAME" desc="In settings Internet options, a string specifying VPN service name.">
+ Service name:
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVER_HOSTNAME" desc="In settings Internet options, a string specifying VPN server hostname.">
+ Server hostname:
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PROVIDER_TYPE" desc="In settings Internet options, a string specifying VPN provider type.">
+ Provider type:
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PSK_PASSPHRASE" desc="In settings Internet options, a string specifying VPN PSK passphrase.">
+ Pre-shared key:
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USER_CERT" desc="In settings Internet options, a string specifying VPN user certificate.">
+ User certificate:
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USERNAME" desc="In settings Internet options, a string specifying VPN username.">
+ Username:
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USER_PASSPHRASE" desc="In settings Internet options, a string specifying VPN user passphrase.">
+ Password:
+ </message>
<message name="IDS_NETWORK_RECONNECT_TITLE" desc="In network menu, title of the reconnect button that allows user to retry connection on error.">
Reconnect
</message>
@@ -10980,6 +11019,15 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_STATUSBAR_NETWORK_OPEN_PROXY_SETTINGS_DIALOG" desc="The menu item in the network menu button at login screen for opening the options dialog">
Proxy settings...
</message>
+ <message name="IDS_STATUSBAR_NETWORK_PRIVATE_NETWORKS" desc="In the network status menu, the text for submenu of private networks.">
+ Private networks
+ </message>
+ <message name="IDS_STATUSBAR_NETWORK_ADD_VPN" desc="In the network status menu, the text in Private networks submenu to add a private network.">
+ Add private network...
+ </message>
+ <message name="IDS_STATUSBAR_NETWORK_DISCONNECT_VPN" desc="In the network status menu, the text in Private networks submenu to disconnect from a private network.">
+ Disconnect private network
+ </message>
<message name="IDS_STATUSBAR_NO_NETWORKS_MESSAGE" desc="No networks are available">
No networks are available
</message>
@@ -11218,7 +11266,7 @@ Keep your key file in a safe place. You will need it to create new versions of y
<!-- Network error strings for ChromeOS -->
<message name="IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN" desc="Network error in about:network: UNKNOWN">
- Unknown
+ Unknown network error
</message>
<message name="IDS_CHROMEOS_NETWORK_ERROR_OUT_OF_RANGE" desc="Network error in about:network: OUT_OF_RANGE">
Out of range
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 924b486..d5bb64e 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -309,6 +309,18 @@ const Experiment kExperiments[] = {
SINGLE_VALUE_TYPE("")
#endif
},
+ {
+ "enable-vpn",
+ IDS_FLAGS_ENABLE_VPN_NAME,
+ IDS_FLAGS_ENABLE_VPN_DESCRIPTION,
+ kOsCrOS,
+#if defined(OS_CHROMEOS)
+ // The switch exists only on Chrome OS.
+ SINGLE_VALUE_TYPE(switches::kEnableVPN)
+#else
+ SINGLE_VALUE_TYPE("")
+#endif
+ },
};
const Experiment* experiments = kExperiments;
diff --git a/chrome/browser/automation/testing_automation_provider_chromeos.cc b/chrome/browser/automation/testing_automation_provider_chromeos.cc
index 24faad4..875066a 100644
--- a/chrome/browser/automation/testing_automation_provider_chromeos.cc
+++ b/chrome/browser/automation/testing_automation_provider_chromeos.cc
@@ -459,7 +459,7 @@ void TestingAutomationProvider::ConnectToHiddenWifiNetwork(
new SSIDConnectObserver(this, reply_message, ssid);
network_library->ConnectToWifiNetwork(connection_security, ssid, password,
- identity, certpath, false);
+ identity, certpath);
}
void TestingAutomationProvider::DisconnectFromWifiNetwork(
@@ -475,7 +475,7 @@ void TestingAutomationProvider::DisconnectFromWifiNetwork(
return;
}
- network_library->DisconnectFromWirelessNetwork(wifi);
+ network_library->DisconnectFromNetwork(wifi);
reply.SendSuccess(NULL);
}
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc
index 958fe56..d03c149 100644
--- a/chrome/browser/browser_about_handler.cc
+++ b/chrome/browser/browser_about_handler.cc
@@ -363,11 +363,180 @@ std::string AboutAbout() {
}
#if defined(OS_CHROMEOS)
+
+// Html output helper functions
+// TODO(stevenjb): L10N this.
+
+// Helper function to wrap Html with <th> tag.
+static std::string WrapWithTH(std::string text) {
+ return "<th>" + text + "</th>";
+}
+
+// Helper function to wrap Html with <td> tag.
+static std::string WrapWithTD(std::string text) {
+ return "<td>" + text + "</td>";
+}
+
+// Helper function to create an Html table header for a Network.
+static std::string ToHtmlTableHeader(const chromeos::Network* network) {
+ std::string str =
+ WrapWithTH("Name") +
+ WrapWithTH("Active") +
+ WrapWithTH("State");
+ if (network->type() == chromeos::TYPE_WIFI ||
+ network->type() == chromeos::TYPE_CELLULAR) {
+ str += WrapWithTH("Auto-Connect");
+ str += WrapWithTH("Strength");
+ }
+ if (network->type() == chromeos::TYPE_WIFI) {
+ str += WrapWithTH("Encryption");
+ str += WrapWithTH("Passphrase");
+ str += WrapWithTH("Identity");
+ str += WrapWithTH("Certificate");
+ }
+ if (network->type() == chromeos::TYPE_CELLULAR) {
+ str += WrapWithTH("Technology");
+ str += WrapWithTH("Connectivity");
+ str += WrapWithTH("Activation");
+ str += WrapWithTH("Roaming");
+ }
+ if (network->type() == chromeos::TYPE_VPN) {
+ str += WrapWithTH("Host");
+ str += WrapWithTH("Provider Type");
+ str += WrapWithTH("PSK Passphrase");
+ str += WrapWithTH("Username");
+ str += WrapWithTH("User Passphrase");
+ }
+ str += WrapWithTH("Error");
+ str += WrapWithTH("IP Address");
+ return str;
+}
+
+// Helper function to create an Html table row for a Network.
+static std::string ToHtmlTableRow(const chromeos::Network* network) {
+ std::string str =
+ WrapWithTD(network->name()) +
+ WrapWithTD(base::IntToString(network->is_active())) +
+ WrapWithTD(network->GetStateString());
+ if (network->type() == chromeos::TYPE_WIFI ||
+ network->type() == chromeos::TYPE_CELLULAR) {
+ const chromeos::WirelessNetwork* wireless =
+ static_cast<const chromeos::WirelessNetwork*>(network);
+ str += WrapWithTD(base::IntToString(wireless->auto_connect()));
+ str += WrapWithTD(base::IntToString(wireless->strength()));
+ }
+ if (network->type() == chromeos::TYPE_WIFI) {
+ const chromeos::WifiNetwork* wifi =
+ static_cast<const chromeos::WifiNetwork*>(network);
+ str += WrapWithTD(wifi->GetEncryptionString());
+ str += WrapWithTD(std::string(wifi->passphrase().length(), '*'));
+ str += WrapWithTD(wifi->identity());
+ str += WrapWithTD(wifi->cert_path());
+ }
+ if (network->type() == chromeos::TYPE_CELLULAR) {
+ const chromeos::CellularNetwork* cell =
+ static_cast<const chromeos::CellularNetwork*>(network);
+ str += WrapWithTH(cell->GetNetworkTechnologyString());
+ str += WrapWithTH(cell->GetConnectivityStateString());
+ str += WrapWithTH(cell->GetActivationStateString());
+ str += WrapWithTH(cell->GetRoamingStateString());
+ }
+ if (network->type() == chromeos::TYPE_VPN) {
+ const chromeos::VirtualNetwork* vpn =
+ static_cast<const chromeos::VirtualNetwork*>(network);
+ str += WrapWithTH(vpn->server_hostname());
+ str += WrapWithTH(vpn->GetProviderTypeString());
+ str += WrapWithTD(std::string(vpn->psk_passphrase().length(), '*'));
+ str += WrapWithTH(vpn->username());
+ str += WrapWithTD(std::string(vpn->user_passphrase().length(), '*'));
+ }
+ str += WrapWithTD(network->failed() ? network->GetErrorString() : "");
+ str += WrapWithTD(network->ip_address());
+ return str;
+}
+
+std::string GetNetworkHtmlInfo(int refresh) {
+ chromeos::NetworkLibrary* cros =
+ chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+ std::string output;
+ output.append("<html><head><title>About Network</title>");
+ if (refresh > 0)
+ output.append("<meta http-equiv=\"refresh\" content=\"" +
+ base::IntToString(refresh) + "\"/>");
+ output.append("</head><body>");
+ if (refresh > 0) {
+ output.append("(Auto-refreshing page every " +
+ base::IntToString(refresh) + "s)");
+ } else {
+ output.append("(To auto-refresh this page: about:network/&lt;secs&gt;)");
+ }
+
+ if (cros->ethernet_enabled()) {
+ output.append("<h3>Ethernet:</h3><table border=1>");
+ const chromeos::EthernetNetwork* ethernet = cros->ethernet_network();
+ if (ethernet) {
+ output.append("<tr>" + ToHtmlTableHeader(ethernet) + "</tr>");
+ output.append("<tr>" + ToHtmlTableRow(ethernet) + "</tr>");
+ }
+ }
+
+ if (cros->wifi_enabled()) {
+ output.append("</table><h3>Wifi Networks:</h3><table border=1>");
+ const chromeos::WifiNetworkVector& wifi_networks = cros->wifi_networks();
+ for (size_t i = 0; i < wifi_networks.size(); ++i) {
+ if (i == 0)
+ output.append("<tr>" + ToHtmlTableHeader(wifi_networks[i]) +
+ "</tr>");
+ output.append("<tr>" + ToHtmlTableRow(wifi_networks[i]) + "</tr>");
+ }
+ }
+
+ if (cros->cellular_enabled()) {
+ output.append("</table><h3>Cellular Networks:</h3><table border=1>");
+ const chromeos::CellularNetworkVector& cellular_networks =
+ cros->cellular_networks();
+ for (size_t i = 0; i < cellular_networks.size(); ++i) {
+ if (i == 0)
+ output.append("<tr>" + ToHtmlTableHeader(cellular_networks[i]) +
+ "</tr>");
+ output.append("<tr>" + ToHtmlTableRow(cellular_networks[i]) + "</tr>");
+ }
+ }
+
+ {
+ output.append("</table><h3>Virtual Networks:</h3><table border=1>");
+ const chromeos::VirtualNetworkVector& virtual_networks =
+ cros->virtual_networks();
+ for (size_t i = 0; i < virtual_networks.size(); ++i) {
+ if (i == 0)
+ output.append("<tr>" + ToHtmlTableHeader(virtual_networks[i]) +
+ "</tr>");
+ output.append("<tr>" + ToHtmlTableRow(virtual_networks[i]) + "</tr>");
+ }
+ }
+
+ {
+ output.append(
+ "</table><h3>Remembered Wi-Fi Networks:</h3><table border=1>");
+ const chromeos::WifiNetworkVector& remembered_wifi_networks =
+ cros->remembered_wifi_networks();
+ for (size_t i = 0; i < remembered_wifi_networks.size(); ++i) {
+ if (i == 0)
+ output.append("<tr>" +
+ ToHtmlTableHeader(remembered_wifi_networks[i]) + "</tr>");
+ output.append("<tr>" + ToHtmlTableRow(remembered_wifi_networks[i]) +
+ "</tr>");
+ }
+ }
+
+ output.append("</table></body></html>");
+ return output;
+}
+
std::string AboutNetwork(const std::string& query) {
int refresh;
base::StringToInt(query, &refresh);
- return chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- GetHtmlInfo(refresh);
+ return GetNetworkHtmlInfo(refresh);
}
#endif
diff --git a/chrome/browser/chromeos/cros/mock_network_library.h b/chrome/browser/chromeos/cros/mock_network_library.h
index efc5b17..014ee9a 100644
--- a/chrome/browser/chromeos/cros/mock_network_library.h
+++ b/chrome/browser/chromeos/cros/mock_network_library.h
@@ -70,6 +70,8 @@ class MockNetworkLibrary : public NetworkLibrary {
WifiNetwork*(const std::string&));
MOCK_CONST_METHOD1(FindCellularNetworkByPath,
CellularNetwork*(const std::string&));
+ MOCK_CONST_METHOD1(FindVirtualNetworkByPath,
+ VirtualNetwork*(const std::string&));
MOCK_CONST_METHOD1(GetDataPlans,
CellularDataPlanVector*(const std::string&));
MOCK_CONST_METHOD1(GetSignificantDataPlan,
@@ -84,17 +86,22 @@ class MockNetworkLibrary : public NetworkLibrary {
MOCK_METHOD1(GetWifiAccessPoints, bool(WifiAccessPointVector*));
MOCK_METHOD1(ConnectToWifiNetwork, void(WifiNetwork*));
MOCK_METHOD1(ConnectToWifiNetwork, void(const std::string&));
- MOCK_METHOD6(ConnectToWifiNetwork, void(ConnectionSecurity security,
+ MOCK_METHOD5(ConnectToWifiNetwork, void(ConnectionSecurity security,
const std::string&,
const std::string&,
const std::string&,
- const std::string&,
- bool));
+ const std::string&));
MOCK_METHOD1(ConnectToCellularNetwork, void(CellularNetwork*));
+ MOCK_METHOD1(ConnectToVirtualNetwork, void(VirtualNetwork*));
+ MOCK_METHOD5(ConnectToVirtualNetworkPSK, void(const std::string&,
+ const std::string&,
+ const std::string&,
+ const std::string&,
+ const std::string&));
MOCK_METHOD0(SignalCellularPlanPayment, void(void));
MOCK_METHOD0(HasRecentCellularPlanPayment, bool(void));
- MOCK_METHOD1(DisconnectFromWirelessNetwork, void(const WirelessNetwork*));
+ MOCK_METHOD1(DisconnectFromNetwork, void(const Network*));
MOCK_METHOD1(ForgetWifiNetwork, void(const std::string&));
MOCK_CONST_METHOD0(ethernet_available, bool(void));
@@ -108,6 +115,8 @@ class MockNetworkLibrary : public NetworkLibrary {
MOCK_CONST_METHOD0(wifi_scanning, bool(void));
MOCK_CONST_METHOD0(active_network, const Network*(void));
+ MOCK_CONST_METHOD0(connected_network, const Network*(void));
+
MOCK_CONST_METHOD0(offline_mode, bool(void));
MOCK_METHOD1(EnableEthernetNetworkDevice, void(bool));
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc
index 54dd258..270c177 100644
--- a/chrome/browser/chromeos/cros/network_library.cc
+++ b/chrome/browser/chromeos/cros/network_library.cc
@@ -133,6 +133,8 @@ const char* kErrorProperty = "Error";
const char* kActiveProfileProperty = "ActiveProfile";
const char* kEntriesProperty = "Entries";
const char* kDevicesProperty = "Devices";
+const char* kProviderProperty = "Provider";
+const char* kHostProperty = "Host";
// Flimflam property names for SIMLock status.
const char* kSIMLockStatusProperty = "Cellular.SIMLockStatus";
@@ -185,6 +187,14 @@ const char* kSecurityRsn = "rsn";
const char* kSecurity8021x = "802_1x";
const char* kSecurityNone = "none";
+// Flimflam L2TPIPsec property names.
+const char* kL2TPIPSecCACertProperty = "L2TPIPsec.CACert";
+const char* kL2TPIPSecCertProperty = "L2TPIPsec.Cert";
+const char* kL2TPIPSecKeyProperty = "L2TPIPsec.Key";
+const char* kL2TPIPSecPSKProperty = "L2TPIPsec.PSK";
+const char* kL2TPIPSecUserProperty = "L2TPIPsec.User";
+const char* kL2TPIPSecPasswordProperty = "L2TPIPsec.Password";
+
// Flimflam EAP property names.
// See src/third_party/flimflam/doc/service-api.txt.
const char* kEapIdentityProperty = "EAP.Identity";
@@ -220,6 +230,11 @@ const std::string& kEapPhase2AuthTTLSMSCHAP = "autheap=MSCHAP";
const std::string& kEapPhase2AuthTTLSPAP = "autheap=PAP";
const std::string& kEapPhase2AuthTTLSCHAP = "autheap=CHAP";
+// Flimflam VPN provider types.
+const char* kProviderL2tpIpsec = "l2tpipsec";
+const char* kProviderOpenVpn = "openvpn";
+
+
// Flimflam state options.
const char* kStateIdle = "idle";
const char* kStateCarrier = "carrier";
@@ -320,6 +335,20 @@ static const char* SecurityToString(ConnectionSecurity security) {
return kUnknownString;
}
+static const char* ProviderTypeToString(VirtualNetwork::ProviderType type) {
+ switch (type) {
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK:
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
+ return kProviderL2tpIpsec;
+ case VirtualNetwork::PROVIDER_TYPE_OPEN_VPN:
+ return kProviderOpenVpn;
+ case VirtualNetwork::PROVIDER_TYPE_MAX:
+ break;
+ }
+ LOG(ERROR) << "ProviderTypeToString called with unknown type: " << type;
+ return kUnknownString;
+}
+
////////////////////////////////////////////////////////////////////////////
// Helper class to cache maps of strings to enums.
@@ -393,11 +422,18 @@ enum PropertyIndex {
PROPERTY_INDEX_FIRMWARE_REVISION,
PROPERTY_INDEX_HARDWARE_REVISION,
PROPERTY_INDEX_HOME_PROVIDER,
+ PROPERTY_INDEX_HOST,
PROPERTY_INDEX_IDENTITY,
PROPERTY_INDEX_IMEI,
PROPERTY_INDEX_IMSI,
PROPERTY_INDEX_IS_ACTIVE,
PROPERTY_INDEX_LAST_DEVICE_UPDATE,
+ PROPERTY_INDEX_L2TPIPSEC_CA_CERT,
+ PROPERTY_INDEX_L2TPIPSEC_CERT,
+ PROPERTY_INDEX_L2TPIPSEC_KEY,
+ PROPERTY_INDEX_L2TPIPSEC_PASSWORD,
+ PROPERTY_INDEX_L2TPIPSEC_PSK,
+ PROPERTY_INDEX_L2TPIPSEC_USER,
PROPERTY_INDEX_MANUFACTURER,
PROPERTY_INDEX_MDN,
PROPERTY_INDEX_MEID,
@@ -414,6 +450,7 @@ enum PropertyIndex {
PROPERTY_INDEX_PAYMENT_URL,
PROPERTY_INDEX_PRL_VERSION,
PROPERTY_INDEX_PROFILES,
+ PROPERTY_INDEX_PROVIDER,
PROPERTY_INDEX_ROAMING_STATE,
PROPERTY_INDEX_SAVE_CREDENTIALS,
PROPERTY_INDEX_SCANNING,
@@ -467,10 +504,17 @@ StringToEnum<PropertyIndex>::Pair property_index_table[] = {
{ kFirmwareRevisionProperty, PROPERTY_INDEX_FIRMWARE_REVISION },
{ kHardwareRevisionProperty, PROPERTY_INDEX_HARDWARE_REVISION },
{ kHomeProviderProperty, PROPERTY_INDEX_HOME_PROVIDER },
+ { kHostProperty, PROPERTY_INDEX_HOST },
{ kIdentityProperty, PROPERTY_INDEX_IDENTITY },
{ kImeiProperty, PROPERTY_INDEX_IMEI },
{ kImsiProperty, PROPERTY_INDEX_IMSI },
{ kIsActiveProperty, PROPERTY_INDEX_IS_ACTIVE },
+ { kL2TPIPSecCACertProperty, PROPERTY_INDEX_L2TPIPSEC_CA_CERT },
+ { kL2TPIPSecCertProperty, PROPERTY_INDEX_L2TPIPSEC_CERT },
+ { kL2TPIPSecKeyProperty, PROPERTY_INDEX_L2TPIPSEC_KEY },
+ { kL2TPIPSecPasswordProperty, PROPERTY_INDEX_L2TPIPSEC_PASSWORD },
+ { kL2TPIPSecPSKProperty, PROPERTY_INDEX_L2TPIPSEC_PSK },
+ { kL2TPIPSecUserProperty, PROPERTY_INDEX_L2TPIPSEC_USER },
{ kLastDeviceUpdateProperty, PROPERTY_INDEX_LAST_DEVICE_UPDATE },
{ kManufacturerProperty, PROPERTY_INDEX_MANUFACTURER },
{ kMdnProperty, PROPERTY_INDEX_MDN },
@@ -488,6 +532,7 @@ StringToEnum<PropertyIndex>::Pair property_index_table[] = {
{ kPassphraseRequiredProperty, PROPERTY_INDEX_PASSPHRASE_REQUIRED },
{ kPaymentURLProperty, PROPERTY_INDEX_PAYMENT_URL },
{ kProfilesProperty, PROPERTY_INDEX_PROFILES },
+ { kProviderProperty, PROPERTY_INDEX_PROVIDER },
{ kRoamingStateProperty, PROPERTY_INDEX_ROAMING_STATE },
{ kSaveCredentialsProperty, PROPERTY_INDEX_SAVE_CREDENTIALS },
{ kScanningProperty, PROPERTY_INDEX_SCANNING },
@@ -577,6 +622,17 @@ static ConnectionError ParseError(const std::string& error) {
return parser.Get(error);
}
+// VirtualNetwork
+static VirtualNetwork::ProviderType ParseProviderType(const std::string& mode) {
+ static StringToEnum<VirtualNetwork::ProviderType>::Pair table[] = {
+ { kProviderL2tpIpsec, VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK },
+ { kProviderOpenVpn, VirtualNetwork::PROVIDER_TYPE_OPEN_VPN },
+ };
+ static StringToEnum<VirtualNetwork::ProviderType> parser(
+ table, arraysize(table), VirtualNetwork::PROVIDER_TYPE_MAX);
+ return parser.Get(mode);
+}
+
// CellularNetwork.
static ActivationState ParseActivationState(const std::string& state) {
static StringToEnum<ActivationState>::Pair table[] = {
@@ -697,59 +753,6 @@ static EAPPhase2Auth ParseEAPPhase2Auth(const std::string& auth) {
return parser.Get(auth);
}
-////////////////////////////////////////////////////////////////////////////
-// Html output helper functions
-
-// Helper function to wrap Html with <th> tag.
-static std::string WrapWithTH(std::string text) {
- return "<th>" + text + "</th>";
-}
-
-// Helper function to wrap Html with <td> tag.
-static std::string WrapWithTD(std::string text) {
- return "<td>" + text + "</td>";
-}
-
-// Helper function to create an Html table header for a Network.
-static std::string ToHtmlTableHeader(Network* network) {
- std::string str;
- if (network->type() == TYPE_ETHERNET) {
- str += WrapWithTH("Active");
- } else if (network->type() == TYPE_WIFI || network->type() == TYPE_CELLULAR) {
- str += WrapWithTH("Name") + WrapWithTH("Active") +
- WrapWithTH("Auto-Connect") + WrapWithTH("Strength");
- if (network->type() == TYPE_WIFI)
- str += WrapWithTH("Encryption") + WrapWithTH("Passphrase") +
- WrapWithTH("Identity") + WrapWithTH("Certificate");
- }
- str += WrapWithTH("State") + WrapWithTH("Error") + WrapWithTH("IP Address");
- return str;
-}
-
-// Helper function to create an Html table row for a Network.
-static std::string ToHtmlTableRow(Network* network) {
- std::string str;
- if (network->type() == TYPE_ETHERNET) {
- str += WrapWithTD(base::IntToString(network->is_active()));
- } else if (network->type() == TYPE_WIFI || network->type() == TYPE_CELLULAR) {
- WirelessNetwork* wireless = static_cast<WirelessNetwork*>(network);
- str += WrapWithTD(wireless->name()) +
- WrapWithTD(base::IntToString(network->is_active())) +
- WrapWithTD(base::IntToString(wireless->auto_connect())) +
- WrapWithTD(base::IntToString(wireless->strength()));
- if (network->type() == TYPE_WIFI) {
- WifiNetwork* wifi = static_cast<WifiNetwork*>(network);
- str += WrapWithTD(wifi->GetEncryptionString()) +
- WrapWithTD(std::string(wifi->passphrase().length(), '*')) +
- WrapWithTD(wifi->identity()) + WrapWithTD(wifi->cert_path());
- }
- }
- str += WrapWithTD(network->GetStateString()) +
- WrapWithTD(network->failed() ? network->GetErrorString() : "") +
- WrapWithTD(network->ip_address());
- return str;
-}
-
////////////////////////////////////////////////////////////////////////////////
// Misc.
@@ -852,10 +855,12 @@ void NetworkDevice::ParseInfo(const DictionaryValue* info) {
const std::string& key = *iter;
Value* value;
bool res = info->GetWithoutPathExpansion(key, &value);
- CHECK(res);
- int index = property_index_parser().Get(key);
- if (!ParseValue(index, value))
- VLOG(1) << "NetworkDevice: Unhandled key: " << key;
+ DCHECK(res);
+ if (res) {
+ int index = property_index_parser().Get(key);
+ if (!ParseValue(index, value))
+ VLOG(1) << "NetworkDevice: Unhandled key: " << key;
+ }
}
}
@@ -937,57 +942,70 @@ void Network::ParseInfo(const DictionaryValue* info) {
const std::string& key = *iter;
Value* value;
bool res = info->GetWithoutPathExpansion(key, &value);
- CHECK(res);
- int index = property_index_parser().Get(key);
- if (!ParseValue(index, value)) // virtual.
- VLOG(1) << "Network: Type: " << type_ << " Unhandled key: " << key;
+ DCHECK(res);
+ if (res) {
+ int index = property_index_parser().Get(key);
+ if (!ParseValue(index, value)) // virtual.
+ VLOG(1) << "Network: " << name()
+ << " Type: " << ConnectionTypeToString(type())
+ << " Unhandled key: " << key;
+ }
}
}
-void Network::SetAutoConnect(bool auto_connect) {
- auto_connect_ = auto_connect;
- SetBooleanProperty(kAutoConnectProperty, auto_connect);
+void Network::SetValueProperty(const char* prop, Value* val) {
+ DCHECK(prop);
+ DCHECK(val);
+ if (!EnsureCrosLoaded())
+ return;
+ SetNetworkServiceProperty(service_path_.c_str(), prop, val);
}
-void Network::SetStringProperty(const char* prop, const std::string& str) {
+void Network::ClearProperty(const char* prop) {
+ DCHECK(prop);
+ if (!EnsureCrosLoaded())
+ return;
+ ClearNetworkServiceProperty(service_path_.c_str(), prop);
+}
+
+void Network::SetStringProperty(
+ const char* prop, const std::string& str, std::string* dest) {
+ if (dest)
+ *dest = str;
scoped_ptr<Value> value(Value::CreateStringValue(str));
SetValueProperty(prop, value.get());
}
-void Network::SetBooleanProperty(const char* prop, bool b) {
+void Network::SetOrClearStringProperty(const char* prop,
+ const std::string& str,
+ std::string* dest) {
+ if (str.empty()) {
+ ClearProperty(prop);
+ if (dest)
+ dest->clear();
+ } else {
+ SetStringProperty(prop, str, dest);
+ }
+}
+
+void Network::SetBooleanProperty(const char* prop, bool b, bool* dest) {
+ if (dest)
+ *dest = b;
scoped_ptr<Value> value(Value::CreateBooleanValue(b));
SetValueProperty(prop, value.get());
}
-void Network::SetIntegerProperty(const char* prop, int i) {
+void Network::SetIntegerProperty(const char* prop, int i, int* dest) {
+ if (dest)
+ *dest = i;
scoped_ptr<Value> value(Value::CreateIntegerValue(i));
SetValueProperty(prop, value.get());
}
-void Network::ClearProperty(const char* prop) {
- DCHECK(prop);
- if (!EnsureCrosLoaded())
- return;
- ClearNetworkServiceProperty(service_path_.c_str(), prop);
-}
-
-void Network::SetOrClearStringProperty(const char* prop,
- const std::string& str) {
- if (str.empty())
- ClearProperty(prop);
- else
- SetStringProperty(prop, str);
-}
-
-void Network::SetValueProperty(const char* prop, Value* val) {
- DCHECK(prop);
- DCHECK(val);
- if (!EnsureCrosLoaded())
- return;
- SetNetworkServiceProperty(service_path_.c_str(), prop, val);
+void Network::SetAutoConnect(bool auto_connect) {
+ SetBooleanProperty(kAutoConnectProperty, auto_connect, &auto_connect_);
}
-// Used by GetHtmlInfo() which is called from the about:network handler.
std::string Network::GetStateString() const {
switch (state_) {
case STATE_UNKNOWN:
@@ -1009,9 +1027,6 @@ std::string Network::GetStateString() const {
case STATE_ACTIVATION_FAILURE:
return l10n_util::GetStringUTF8(
IDS_CHROMEOS_NETWORK_STATE_ACTIVATION_FAILURE);
- default:
- // Usually no default, but changes to libcros may add states.
- break;
}
return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED);
}
@@ -1046,9 +1061,6 @@ std::string Network::GetErrorString() const {
return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_OTASP_FAILED);
case ERROR_AAA_FAILED:
return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_AAA_FAILED);
- default:
- // Usually no default, but changes to libcros may add errors.
- break;
}
return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED);
}
@@ -1072,6 +1084,145 @@ void Network::InitIPAddress() {
}
////////////////////////////////////////////////////////////////////////////////
+// VirtualNetwork
+
+bool VirtualNetwork::ParseProviderValue(int index, const Value* value) {
+ switch (index) {
+ case PROPERTY_INDEX_HOST:
+ return value->GetAsString(&server_hostname_);
+ case PROPERTY_INDEX_NAME:
+ // Note: shadows Network::name_ property.
+ return value->GetAsString(&name_);
+ case PROPERTY_INDEX_TYPE: {
+ std::string provider_type_string;
+ if (value->GetAsString(&provider_type_string)) {
+ provider_type_ = ParseProviderType(provider_type_string);
+ return true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+bool VirtualNetwork::ParseValue(int index, const Value* value) {
+ switch (index) {
+ case PROPERTY_INDEX_PROVIDER: {
+ DCHECK_EQ(value->GetType(), Value::TYPE_DICTIONARY);
+ const DictionaryValue* dict = static_cast<const DictionaryValue*>(value);
+ for (DictionaryValue::key_iterator iter = dict->begin_keys();
+ iter != dict->end_keys(); ++iter) {
+ const std::string& key = *iter;
+ Value* v;
+ bool res = dict->GetWithoutPathExpansion(key, &v);
+ DCHECK(res);
+ if (res) {
+ int index = property_index_parser().Get(key);
+ if (!ParseProviderValue(index, v))
+ VLOG(1) << name() << ": Provider unhandled key: " << key
+ << " Type: " << v->GetType();
+ }
+ }
+ return true;
+ }
+ case PROPERTY_INDEX_L2TPIPSEC_CA_CERT:
+ return value->GetAsString(&ca_cert_);
+ case PROPERTY_INDEX_L2TPIPSEC_PSK:
+ return value->GetAsString(&psk_passphrase_);
+ case PROPERTY_INDEX_L2TPIPSEC_CERT:
+ return value->GetAsString(&user_cert_);
+ case PROPERTY_INDEX_L2TPIPSEC_KEY:
+ return value->GetAsString(&user_cert_key_);
+ case PROPERTY_INDEX_L2TPIPSEC_USER:
+ return value->GetAsString(&username_);
+ case PROPERTY_INDEX_L2TPIPSEC_PASSWORD:
+ return value->GetAsString(&user_passphrase_);
+ default:
+ return Network::ParseValue(index, value);
+ break;
+ }
+ return false;
+}
+
+void VirtualNetwork::ParseInfo(const DictionaryValue* info) {
+ Network::ParseInfo(info);
+ VLOG(1) << "VPN: " << name()
+ << " Type: " << ProviderTypeToString(provider_type());
+ if (provider_type_ == PROVIDER_TYPE_L2TP_IPSEC_PSK) {
+ if (!user_cert_.empty())
+ provider_type_ = PROVIDER_TYPE_L2TP_IPSEC_USER_CERT;
+ }
+}
+
+bool VirtualNetwork::NeedMoreInfoToConnect() const {
+ if (server_hostname_.empty() || username_.empty() || user_passphrase_.empty())
+ return true;
+ switch (provider_type_) {
+ case PROVIDER_TYPE_L2TP_IPSEC_PSK:
+ if (psk_passphrase_.empty())
+ return true;
+ break;
+ case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
+ case PROVIDER_TYPE_OPEN_VPN:
+ if (user_cert_.empty())
+ return true;
+ break;
+ case PROVIDER_TYPE_MAX:
+ break;
+ }
+ return false;
+}
+
+void VirtualNetwork::SetCACert(const std::string& ca_cert) {
+ SetStringProperty(kL2TPIPSecCACertProperty, ca_cert, &ca_cert_);
+}
+
+void VirtualNetwork::SetPSKPassphrase(const std::string& psk_passphrase) {
+ SetStringProperty(kL2TPIPSecPSKProperty, psk_passphrase,
+ &psk_passphrase_);
+}
+
+void VirtualNetwork::SetUserCert(const std::string& user_cert) {
+ SetStringProperty(kL2TPIPSecCertProperty, user_cert, &user_cert_);
+}
+
+void VirtualNetwork::SetUserCertKey(const std::string& key) {
+ SetStringProperty(kL2TPIPSecKeyProperty, key, &user_cert_key_);
+}
+
+void VirtualNetwork::SetUsername(const std::string& username) {
+ SetStringProperty(kL2TPIPSecUserProperty, username, &username_);
+}
+
+void VirtualNetwork::SetUserPassphrase(const std::string& user_passphrase) {
+ SetStringProperty(kL2TPIPSecPasswordProperty, user_passphrase,
+ &user_passphrase_);
+}
+
+std::string VirtualNetwork::GetProviderTypeString() const {
+ switch (this->provider_type_) {
+ case PROVIDER_TYPE_L2TP_IPSEC_PSK:
+ return l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK);
+ break;
+ case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
+ return l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT);
+ break;
+ case PROVIDER_TYPE_OPEN_VPN:
+ return l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN);
+ break;
+ default:
+ return l10n_util::GetStringUTF8(
+ IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN);
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
// WirelessNetwork
bool WirelessNetwork::ParseValue(int index, const Value* value) {
@@ -1534,12 +1685,12 @@ void WifiNetwork::SetPassphrase(const std::string& passphrase) {
user_passphrase_ = passphrase_;
// Send the change to flimflam. If the format is valid, it will propagate to
// passphrase_ with a service update.
- SetStringProperty(kPassphraseProperty, passphrase);
+ SetStringProperty(kPassphraseProperty, passphrase, NULL);
}
void WifiNetwork::SetSaveCredentials(bool save_credentials) {
- save_credentials_ = save_credentials;
- SetBooleanProperty(kSaveCredentialsProperty, save_credentials);
+ SetBooleanProperty(kSaveCredentialsProperty, save_credentials,
+ &save_credentials_);
}
// See src/third_party/flimflam/doc/service-api.txt for properties that
@@ -1554,29 +1705,27 @@ void WifiNetwork::EraseCredentials() {
}
void WifiNetwork::SetIdentity(const std::string& identity) {
- identity_ = identity;
- SetStringProperty(kIdentityProperty, identity);
+ SetStringProperty(kIdentityProperty, identity, &identity_);
}
void WifiNetwork::SetCertPath(const std::string& cert_path) {
- cert_path_ = cert_path;
- SetStringProperty(kCertPathProperty, cert_path);
+ SetStringProperty(kCertPathProperty, cert_path, &cert_path_);
}
void WifiNetwork::SetEAPMethod(EAPMethod method) {
eap_method_ = method;
switch (method) {
case EAP_METHOD_PEAP:
- SetStringProperty(kEapMethodProperty, kEapMethodPEAP);
+ SetStringProperty(kEapMethodProperty, kEapMethodPEAP, NULL);
break;
case EAP_METHOD_TLS:
- SetStringProperty(kEapMethodProperty, kEapMethodTLS);
+ SetStringProperty(kEapMethodProperty, kEapMethodTLS, NULL);
break;
case EAP_METHOD_TTLS:
- SetStringProperty(kEapMethodProperty, kEapMethodTTLS);
+ SetStringProperty(kEapMethodProperty, kEapMethodTTLS, NULL);
break;
case EAP_METHOD_LEAP:
- SetStringProperty(kEapMethodProperty, kEapMethodLEAP);
+ SetStringProperty(kEapMethodProperty, kEapMethodLEAP, NULL);
break;
default:
ClearProperty(kEapMethodProperty);
@@ -1594,21 +1743,23 @@ void WifiNetwork::SetEAPPhase2Auth(EAPPhase2Auth auth) {
case EAP_PHASE_2_AUTH_MD5:
SetStringProperty(kEapPhase2AuthProperty,
is_peap ? kEapPhase2AuthPEAPMD5
- : kEapPhase2AuthTTLSMD5);
+ : kEapPhase2AuthTTLSMD5,
+ NULL);
break;
case EAP_PHASE_2_AUTH_MSCHAPV2:
SetStringProperty(kEapPhase2AuthProperty,
is_peap ? kEapPhase2AuthPEAPMSCHAPV2
- : kEapPhase2AuthTTLSMSCHAPV2);
+ : kEapPhase2AuthTTLSMSCHAPV2,
+ NULL);
break;
case EAP_PHASE_2_AUTH_MSCHAP:
- SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSMSCHAP);
+ SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSMSCHAP, NULL);
break;
case EAP_PHASE_2_AUTH_PAP:
- SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSPAP);
+ SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSPAP, NULL);
break;
case EAP_PHASE_2_AUTH_CHAP:
- SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSCHAP);
+ SetStringProperty(kEapPhase2AuthProperty, kEapPhase2AuthTTLSCHAP, NULL);
break;
}
}
@@ -1616,34 +1767,32 @@ void WifiNetwork::SetEAPPhase2Auth(EAPPhase2Auth auth) {
void WifiNetwork::SetEAPServerCaCertNssNickname(
const std::string& nss_nickname) {
VLOG(1) << "SetEAPServerCaCertNssNickname " << nss_nickname;
- eap_server_ca_cert_nss_nickname_ = nss_nickname;
- SetOrClearStringProperty(kEapCaCertNssProperty, nss_nickname);
+ SetOrClearStringProperty(kEapCaCertNssProperty, nss_nickname,
+ &eap_server_ca_cert_nss_nickname_);
}
void WifiNetwork::SetEAPClientCertPkcs11Id(const std::string& pkcs11_id) {
VLOG(1) << "SetEAPClientCertPkcs11Id " << pkcs11_id;
- eap_client_cert_pkcs11_id_ = pkcs11_id;
- SetOrClearStringProperty(kEapCertIDProperty, pkcs11_id);
+ SetOrClearStringProperty(kEapCertIDProperty, pkcs11_id,
+ &eap_client_cert_pkcs11_id_);
}
void WifiNetwork::SetEAPUseSystemCAs(bool use_system_cas) {
- eap_use_system_cas_ = use_system_cas;
- SetBooleanProperty(kEapUseSystemCAsProperty, use_system_cas);
+ SetBooleanProperty(kEapUseSystemCAsProperty, use_system_cas,
+ &eap_use_system_cas_);
}
void WifiNetwork::SetEAPIdentity(const std::string& identity) {
- eap_identity_ = identity;
- SetOrClearStringProperty(kEapIdentityProperty, identity);
+ SetOrClearStringProperty(kEapIdentityProperty, identity, &eap_identity_);
}
void WifiNetwork::SetEAPAnonymousIdentity(const std::string& identity) {
- eap_anonymous_identity_ = identity;
- SetOrClearStringProperty(kEapAnonymousIdentityProperty, identity);
+ SetOrClearStringProperty(kEapAnonymousIdentityProperty, identity,
+ &eap_anonymous_identity_);
}
void WifiNetwork::SetEAPPassphrase(const std::string& passphrase) {
- eap_passphrase_ = passphrase;
- SetOrClearStringProperty(kEapPasswordProperty, passphrase);
+ SetOrClearStringProperty(kEapPasswordProperty, passphrase, &eap_passphrase_);
}
std::string WifiNetwork::GetEncryptionString() const {
@@ -1923,10 +2072,10 @@ class NetworkLibraryImpl : public NetworkLibrary {
const std::string& IPAddress() const {
// Returns IP address for the active network.
+ // TODO(stevenjb): Fix this for VPNs. See chromium-os:13972.
const Network* result = active_network();
- if (active_virtual_ && active_virtual_->is_active() &&
- (!result || active_virtual_->priority_ > result->priority_))
- result = active_virtual_;
+ if (!result)
+ result = connected_network(); // happens if we are connected to a VPN.
if (!result)
result = ethernet_; // Use non active ethernet addr if no active network.
if (result)
@@ -2001,6 +2150,14 @@ class NetworkLibraryImpl : public NetworkLibrary {
return NULL;
}
+ virtual VirtualNetwork* FindVirtualNetworkByPath(
+ const std::string& path) const {
+ Network* network = FindNetworkByPath(path);
+ if (network && network->type() == TYPE_VPN)
+ return static_cast<VirtualNetwork*>(network);
+ return NULL;
+ }
+
virtual const CellularDataPlanVector* GetDataPlans(
const std::string& path) const {
CellularDataPlanMap::const_iterator iter = data_plan_map_.find(path);
@@ -2124,74 +2281,77 @@ class NetworkLibraryImpl : public NetworkLibrary {
return true;
}
- static void WirelessConnectCallback(void *object,
- const char *path,
- NetworkMethodErrorType error,
- const char* error_message) {
+ static void NetworkConnectCallback(void *object,
+ const char *path,
+ NetworkMethodErrorType error,
+ const char* error_message) {
NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
DCHECK(networklib);
- WirelessNetwork* wireless = networklib->FindWirelessNetworkByPath(path);
- if (!wireless) {
- LOG(ERROR) << "No wireless network for path: " << path;
+ Network* network = networklib->FindNetworkByPath(path);
+ if (!network) {
+ LOG(ERROR) << "No network for path: " << path;
return;
}
if (error != NETWORK_METHOD_ERROR_NONE) {
+ LOG(WARNING) << "Error from ServiceConnect callback for: "
+ << network->name()
+ << " Error: " << error << " Message: " << error_message;
if (error_message &&
strcmp(error_message, kErrorPassphraseRequiredMsg) == 0) {
// This will trigger the connection failed notification.
// TODO(stevenjb): Remove if chromium-os:13203 gets fixed.
- wireless->set_state(STATE_FAILURE);
- wireless->set_error(ERROR_BAD_PASSPHRASE);
+ network->set_state(STATE_FAILURE);
+ network->set_error(ERROR_BAD_PASSPHRASE);
networklib->NotifyNetworkManagerChanged(true); // Forced update.
- } else {
- LOG(WARNING) << "Error from ServiceConnect callback: "
- << error_message;
}
return;
}
+ VLOG(1) << "Connected to service: " << network->name();
+
// Update local cache and notify listeners.
- if (wireless->type() == TYPE_WIFI) {
- WifiNetwork* wifi = static_cast<WifiNetwork *>(wireless);
+ if (network->type() == TYPE_WIFI) {
+ WifiNetwork* wifi = static_cast<WifiNetwork *>(network);
// If the user asked not to save credentials, flimflam will have
// forgotten them. Wipe our cache as well.
if (!wifi->save_credentials()) {
wifi->EraseCredentials();
}
networklib->active_wifi_ = wifi;
- } else if (wireless->type() == TYPE_CELLULAR) {
- networklib->active_cellular_ = static_cast<CellularNetwork *>(wireless);
+ } else if (network->type() == TYPE_CELLULAR) {
+ networklib->active_cellular_ = static_cast<CellularNetwork *>(network);
+ } else if (network->type() == TYPE_VPN) {
+ networklib->active_virtual_ = static_cast<VirtualNetwork *>(network);
} else {
- LOG(ERROR) << "Network of unexpected type: " << wireless->type();
+ LOG(ERROR) << "Network of unexpected type: " << network->type();
}
// If we succeed, this network will be remembered; request an update.
// TODO(stevenjb): flimflam should do this automatically.
networklib->RequestRememberedNetworksUpdate();
// Notify observers.
- networklib->NotifyNetworkManagerChanged(false); // Not forced.
- networklib->NotifyUserConnectionInitiated(wireless);
+ networklib->NotifyNetworkManagerChanged(true); // Forced update.
+ networklib->NotifyUserConnectionInitiated(network);
}
- void CallConnectToNetworkForWifi(WifiNetwork* wifi) {
- // If we haven't correctly set the parameters (e.g. passphrase), flimflam
- // might fail without attempting a connection. In order to trigger any
- // notifications, set the state locally and notify observers.
- // TODO(stevenjb): Remove if chromium-os:13203 gets fixed.
- wifi->set_connecting(true);
+ void CallConnectToNetwork(Network* network) {
+ // In order to be certain to trigger any notifications, set the connecting
+ // state locally and notify observers. Otherwise there might be a state
+ // change without a forced notify.
+ network->set_connecting(true);
NotifyNetworkManagerChanged(true); // Forced update.
- RequestNetworkServiceConnect(wifi->service_path().c_str(),
- WirelessConnectCallback, this);
+ RequestNetworkServiceConnect(network->service_path().c_str(),
+ NetworkConnectCallback, this);
}
virtual void ConnectToWifiNetwork(WifiNetwork* wifi) {
DCHECK(wifi);
if (!EnsureCrosLoaded() || !wifi)
return;
- CallConnectToNetworkForWifi(wifi);
+ CallConnectToNetwork(wifi);
}
// Use this to connect to a wifi network by service path.
@@ -2204,7 +2364,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
<< service_path;
return;
}
- CallConnectToNetworkForWifi(wifi);
+ CallConnectToNetwork(wifi);
}
// Use this to connect to an unlisted wifi network.
@@ -2214,16 +2374,20 @@ class NetworkLibraryImpl : public NetworkLibrary {
const std::string& ssid,
const std::string& passphrase,
const std::string& identity,
- const std::string& certpath,
- bool auto_connect) {
+ const std::string& certpath) {
if (!EnsureCrosLoaded())
return;
+ // Store the connection data to be used by the callback.
+ connect_data_.service_name = ssid;
+ connect_data_.passphrase = passphrase;
+ connect_data_.identity = identity;
+ connect_data_.cert_path = certpath;
+ // Asynchronously request service properties and call
+ // WifiServiceUpdateAndConnect.
RequestHiddenWifiNetwork(ssid.c_str(),
SecurityToString(security),
WifiServiceUpdateAndConnect,
this);
- // Store the connection data to be used by the callback.
- connect_data_.SetData(ssid, passphrase, identity, certpath, auto_connect);
}
// Callback
@@ -2237,38 +2401,33 @@ class NetworkLibraryImpl : public NetworkLibrary {
const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
Network* network =
networklib->ParseNetwork(std::string(service_path), dict);
- // Blocking DBus call. TODO(stevenjb): make async.
- networklib->ConnectToNetworkUsingConnectData(network);
+ DCHECK(network->type() == TYPE_WIFI);
+ networklib->ConnectToWifiNetworkUsingConnectData(
+ static_cast<WifiNetwork*>(network));
}
}
- void ConnectToNetworkUsingConnectData(Network* network) {
+ void ConnectToWifiNetworkUsingConnectData(WifiNetwork* wifi) {
ConnectData& data = connect_data_;
- if (network->name() != data.name) {
- LOG(WARNING) << "Network name does not match ConnectData: "
- << network->name() << " != " << data.name;
+ if (wifi->name() != data.service_name) {
+ LOG(WARNING) << "Wifi network name does not match ConnectData: "
+ << wifi->name() << " != " << data.service_name;
return;
}
+ wifi->set_added(true);
+ wifi->SetIdentity(data.identity);
+ wifi->SetPassphrase(data.passphrase);
+ if (!data.cert_path.empty())
+ wifi->SetCertPath(data.cert_path);
- WifiNetwork *wifi = static_cast<WifiNetwork *>(network);
- if (!data.passphrase.empty())
- wifi->SetPassphrase(data.passphrase);
- if (!data.identity.empty())
- wifi->SetIdentity(data.identity);
- if (!data.certpath.empty())
- wifi->SetCertPath(data.certpath);
- wifi->SetAutoConnect(data.auto_connect);
-
- CallConnectToNetworkForWifi(wifi);
+ CallConnectToNetwork(wifi);
}
virtual void ConnectToCellularNetwork(CellularNetwork* network) {
DCHECK(network);
if (!EnsureCrosLoaded() || !network)
return;
-
- RequestNetworkServiceConnect(network->service_path().c_str(),
- WirelessConnectCallback, this);
+ CallConnectToNetwork(network);
}
// Records information that cellular play payment had happened.
@@ -2283,22 +2442,92 @@ class NetworkLibraryImpl : public NetworkLibrary {
cellular_plan_payment_time_).InHours() < kRecentPlanPaymentHours;
}
- virtual void DisconnectFromWirelessNetwork(const WirelessNetwork* network) {
+ virtual void ConnectToVirtualNetwork(VirtualNetwork* network) {
+ DCHECK(network);
+ if (!EnsureCrosLoaded() || !network)
+ return;
+ CallConnectToNetwork(network);
+ }
+
+ virtual void ConnectToVirtualNetworkPSK(
+ const std::string& service_name,
+ const std::string& server,
+ const std::string& psk,
+ const std::string& username,
+ const std::string& user_passphrase) {
+ if (!EnsureCrosLoaded())
+ return;
+ // Store the connection data to be used by the callback.
+ connect_data_.service_name = service_name;
+ connect_data_.psk_key = psk;
+ connect_data_.server_hostname = server;
+ connect_data_.identity = username;
+ connect_data_.passphrase = user_passphrase;
+ RequestVirtualNetwork(service_name.c_str(),
+ server.c_str(),
+ kProviderL2tpIpsec,
+ VPNServiceUpdateAndConnect,
+ this);
+ }
+
+ // Callback
+ static void VPNServiceUpdateAndConnect(void* object,
+ const char* service_path,
+ const Value* info) {
+ NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
+ DCHECK(networklib);
+ if (service_path && info) {
+ VLOG(1) << "Connecting to new VPN Service: " << service_path;
+ DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
+ const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
+ Network* network =
+ networklib->ParseNetwork(std::string(service_path), dict);
+ DCHECK(network->type() == TYPE_VPN);
+ networklib->ConnectToVirtualNetworkUsingConnectData(
+ static_cast<VirtualNetwork*>(network));
+ } else {
+ LOG(WARNING) << "Unable to create VPN Service: " << service_path;
+ }
+ }
+
+ void ConnectToVirtualNetworkUsingConnectData(VirtualNetwork* vpn) {
+ ConnectData& data = connect_data_;
+ if (vpn->name() != data.service_name) {
+ LOG(WARNING) << "Virtual network name does not match ConnectData: "
+ << vpn->name() << " != " << data.service_name;
+ return;
+ }
+
+ vpn->set_added(true);
+ vpn->set_server_hostname(data.server_hostname);
+ vpn->SetCACert("");
+ vpn->SetUserCert("");
+ vpn->SetUserCertKey("");
+ vpn->SetPSKPassphrase(data.psk_key);
+ vpn->SetUsername(data.identity);
+ vpn->SetUserPassphrase(data.passphrase);
+
+ CallConnectToNetwork(vpn);
+ }
+
+ virtual void DisconnectFromNetwork(const Network* network) {
DCHECK(network);
if (!EnsureCrosLoaded() || !network)
return;
- if (DisconnectFromNetwork(network->service_path().c_str())) {
+ VLOG(1) << "Disconnect from network: " << network->service_path();
+ if (chromeos::DisconnectFromNetwork(network->service_path().c_str())) {
// Update local cache and notify listeners.
- WirelessNetwork* wireless =
- FindWirelessNetworkByPath(network->service_path());
- if (wireless) {
- wireless->set_connected(false);
- if (wireless == active_wifi_)
+ Network* found_network = FindNetworkByPath(network->service_path());
+ if (found_network) {
+ found_network->set_connected(false);
+ if (found_network == active_wifi_)
active_wifi_ = NULL;
- else if (wireless == active_cellular_)
+ else if (found_network == active_cellular_)
active_cellular_ = NULL;
+ else if (found_network == active_virtual_)
+ active_virtual_ = NULL;
}
- NotifyNetworkManagerChanged(false); // Not forced.
+ NotifyNetworkManagerChanged(true); // Forced update.
}
}
@@ -2313,7 +2542,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
// https://crosbug.com/9295
if (DeleteRememberedService(service_path.c_str())) {
DeleteRememberedNetwork(service_path);
- NotifyNetworkManagerChanged(false); // Not forced.
+ NotifyNetworkManagerChanged(true); // Forced update.
}
}
@@ -2350,11 +2579,30 @@ class NetworkLibraryImpl : public NetworkLibrary {
Network* result = NULL;
if (ethernet_ && ethernet_->is_active())
result = ethernet_;
- if (active_wifi_ && active_wifi_->is_active() &&
- (!result || active_wifi_->priority_ > result->priority_))
+ if ((active_wifi_ && active_wifi_->is_active()) &&
+ (!result ||
+ active_wifi_->priority_order_ < result->priority_order_))
+ result = active_wifi_;
+ if ((active_cellular_ && active_cellular_->is_active()) &&
+ (!result ||
+ active_cellular_->priority_order_ < result->priority_order_))
+ result = active_cellular_;
+ return result;
+ }
+
+ virtual const Network* connected_network() const {
+ // Use flimflam's ordering of the services to determine what the connected
+ // network is (i.e. don't assume priority of network types).
+ Network* result = NULL;
+ if (ethernet_ && ethernet_->connected())
+ result = ethernet_;
+ if ((active_wifi_ && active_wifi_->connected()) &&
+ (!result ||
+ active_wifi_->priority_order_ < result->priority_order_))
result = active_wifi_;
- if (active_cellular_ && active_cellular_->is_active() &&
- (!result || active_cellular_->priority_ > result->priority_))
+ if ((active_cellular_ && active_cellular_->connected()) &&
+ (!result ||
+ active_cellular_->priority_order_ < result->priority_order_))
result = active_cellular_;
return result;
}
@@ -2419,62 +2667,6 @@ class NetworkLibraryImpl : public NetworkLibrary {
return ipconfig_vector;
}
- virtual std::string GetHtmlInfo(int refresh) {
- std::string output;
- output.append("<html><head><title>About Network</title>");
- if (refresh > 0)
- output.append("<meta http-equiv=\"refresh\" content=\"" +
- base::IntToString(refresh) + "\"/>");
- output.append("</head><body>");
- if (refresh > 0) {
- output.append("(Auto-refreshing page every " +
- base::IntToString(refresh) + "s)");
- } else {
- output.append("(To auto-refresh this page: about:network/&lt;secs&gt;)");
- }
-
- if (ethernet_enabled()) {
- output.append("<h3>Ethernet:</h3><table border=1>");
- if (ethernet_) {
- output.append("<tr>" + ToHtmlTableHeader(ethernet_) + "</tr>");
- output.append("<tr>" + ToHtmlTableRow(ethernet_) + "</tr>");
- }
- }
-
- if (wifi_enabled()) {
- output.append("</table><h3>Wifi:</h3><table border=1>");
- for (size_t i = 0; i < wifi_networks_.size(); ++i) {
- if (i == 0)
- output.append("<tr>" + ToHtmlTableHeader(wifi_networks_[i]) +
- "</tr>");
- output.append("<tr>" + ToHtmlTableRow(wifi_networks_[i]) + "</tr>");
- }
- }
-
- if (cellular_enabled()) {
- output.append("</table><h3>Cellular:</h3><table border=1>");
- for (size_t i = 0; i < cellular_networks_.size(); ++i) {
- if (i == 0)
- output.append("<tr>" + ToHtmlTableHeader(cellular_networks_[i]) +
- "</tr>");
- output.append("<tr>" + ToHtmlTableRow(cellular_networks_[i]) + "</tr>");
- }
- }
-
- output.append("</table><h3>Remembered Wifi:</h3><table border=1>");
- for (size_t i = 0; i < remembered_wifi_networks_.size(); ++i) {
- if (i == 0)
- output.append(
- "<tr>" + ToHtmlTableHeader(remembered_wifi_networks_[i]) +
- "</tr>");
- output.append("<tr>" + ToHtmlTableRow(remembered_wifi_networks_[i]) +
- "</tr>");
- }
-
- output.append("</table></body></html>");
- return output;
- }
-
private:
typedef std::map<std::string, Network*> NetworkMap;
@@ -2633,10 +2825,13 @@ class NetworkLibraryImpl : public NetworkLibrary {
static void NetworkManagerUpdate(void* object,
const char* manager_path,
const Value* info) {
- VLOG(1) << "Received NetworkManagerUpdate.";
NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
DCHECK(networklib);
- DCHECK(info);
+ if (!info) {
+ LOG(ERROR) << "Error retrieving manager properties: " << manager_path;
+ return;
+ }
+ VLOG(1) << "Received NetworkManagerUpdate.";
DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
networklib->ParseNetworkManager(dict);
@@ -2658,7 +2853,11 @@ class NetworkLibraryImpl : public NetworkLibrary {
const Value* info) {
NetworkLibraryImpl* networklib = static_cast<NetworkLibraryImpl*>(object);
DCHECK(networklib);
- DCHECK(info);
+ if (!info) {
+ LOG(ERROR) << "Error retrieving profile: " << profile_path;
+ return;
+ }
+ VLOG(1) << "Received ProfileUpdate for: " << profile_path;
DCHECK_EQ(info->GetType(), Value::TYPE_DICTIONARY);
const DictionaryValue* dict = static_cast<const DictionaryValue*>(info);
ListValue* entries(NULL);
@@ -2921,7 +3120,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
NetworkMap old_network_map = network_map_;
ClearNetworks(false /*don't delete*/);
// Clear the list of update requests.
- int network_priority = 0;
+ int network_priority_order = 0;
network_update_requests_.clear();
// wifi_scanning_ will remain false unless we request a network update.
wifi_scanning_ = false;
@@ -2944,7 +3143,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
// rely on watched network updates and only request updates here for
// new networks.
// Use update_request map to store network priority.
- network_update_requests_[service_path] = network_priority++;
+ network_update_requests_[service_path] = network_priority_order++;
wifi_scanning_ = true;
RequestNetworkServiceInfo(service_path.c_str(),
&NetworkServiceUpdate,
@@ -3057,7 +3256,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
// Find and erase entry in update_requests, and set network priority.
PriorityMap::iterator found2 = network_update_requests_.find(service_path);
if (found2 != network_update_requests_.end()) {
- network->priority_ = found2->second;
+ network->priority_order_ = found2->second;
network_update_requests_.erase(found2);
if (network_update_requests_.empty()) {
// Clear wifi_scanning_ when we have no pending requests.
@@ -3069,7 +3268,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
// << service_path;
}
- VLOG(1) << "ParseNetwork:" << network->name();
+ VLOG(1) << "ParseNetwork: " << network->name();
NotifyNetworkManagerChanged(false); // Not forced.
return network;
}
@@ -3086,7 +3285,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
AddRememberedNetwork(network);
}
network->ParseInfo(info); // virtual.
- VLOG(1) << "ParseRememberedNetwork:" << network->name();
+ VLOG(1) << "ParseRememberedNetwork: " << network->name();
NotifyNetworkManagerChanged(false); // Not forced.
return network;
}
@@ -3235,6 +3434,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
}
void NotifyNetworkChanged(Network* network) {
+ VLOG(2) << "Network changed: " << network->name();
DCHECK(network);
NetworkObserverMap::const_iterator iter = network_observers_.find(
network->service_path());
@@ -3316,7 +3516,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
return;
Network* network = FindNetworkByPath(path);
if (network) {
- VLOG(1) << "UpdateNetworkStatus: " << network->name() << "." << key;
+ VLOG(2) << "UpdateNetworkStatus: " << network->name() << "." << key;
// Note: ParseValue is virtual.
int index = property_index_parser().Get(std::string(key));
if (!network->ParseValue(index, value)) {
@@ -3448,6 +3648,7 @@ class NetworkLibraryImpl : public NetworkLibrary {
wifi1->set_name("Fake Wifi Connected");
wifi1->set_strength(90);
wifi1->set_connected(true);
+ wifi1->set_active(true);
wifi1->set_encryption(SECURITY_NONE);
AddNetwork(wifi1);
@@ -3481,7 +3682,8 @@ class NetworkLibraryImpl : public NetworkLibrary {
CellularNetwork* cellular1 = new CellularNetwork("fc1");
cellular1->set_name("Fake Cellular");
cellular1->set_strength(70);
- cellular1->set_connected(false);
+ cellular1->set_connected(true);
+ cellular1->set_active(true);
cellular1->set_activation_state(ACTIVATION_STATE_ACTIVATED);
cellular1->set_payment_url(std::string("http://www.google.com"));
cellular1->set_usage_url(std::string("http://www.google.com"));
@@ -3524,6 +3726,32 @@ class NetworkLibraryImpl : public NetworkLibrary {
remembered_wifi2->set_encryption(SECURITY_WEP);
AddRememberedNetwork(remembered_wifi2);
+ // VPNs.
+ VirtualNetwork* vpn1 = new VirtualNetwork("fv1");
+ vpn1->set_name("Fake VPN Provider 1");
+ vpn1->set_server_hostname("vpn1server.fake.com");
+ vpn1->set_provider_type(VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK);
+ vpn1->set_username("VPN User 1");
+ vpn1->set_connected(false);
+ AddNetwork(vpn1);
+
+ VirtualNetwork* vpn2 = new VirtualNetwork("fv2");
+ vpn2->set_name("Fake VPN Provider 2");
+ vpn2->set_server_hostname("vpn2server.fake.com");
+ vpn2->set_provider_type(VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT);
+ vpn2->set_username("VPN User 2");
+ vpn2->set_connected(true);
+ AddNetwork(vpn2);
+
+ VirtualNetwork* vpn3 = new VirtualNetwork("fv3");
+ vpn3->set_name("Fake VPN Provider 3");
+ vpn3->set_server_hostname("vpn3server.fake.com");
+ vpn3->set_provider_type(VirtualNetwork::PROVIDER_TYPE_OPEN_VPN);
+ vpn3->set_connected(false);
+ AddNetwork(vpn3);
+
+ active_virtual_ = vpn2;
+
wifi_scanning_ = false;
offline_mode_ = false;
}
@@ -3623,23 +3851,12 @@ class NetworkLibraryImpl : public NetworkLibrary {
// Temporary connection data for async connect calls.
struct ConnectData {
- ConnectData() : auto_connect(false) {}
- void SetData(const std::string& n,
- const std::string& p,
- const std::string& id,
- const std::string& cert,
- bool autocon) {
- name = n;
- passphrase = p;
- identity = id;
- certpath = cert;
- auto_connect = autocon;
- }
- std::string name;
+ std::string service_name;
std::string passphrase;
std::string identity;
- std::string certpath;
- bool auto_connect;
+ std::string cert_path;
+ std::string psk_key;
+ std::string server_hostname;
};
ConnectData connect_data_;
@@ -3733,6 +3950,8 @@ class NetworkLibraryStubImpl : public NetworkLibrary {
const std::string& path) const { return NULL; }
virtual CellularNetwork* FindCellularNetworkByPath(
const std::string& path) const { return NULL; }
+ virtual VirtualNetwork* FindVirtualNetworkByPath(
+ const std::string& path) const { return NULL; }
virtual const CellularDataPlanVector* GetDataPlans(
const std::string& path) const { return NULL; }
virtual const CellularDataPlan* GetSignificantDataPlan(
@@ -3755,12 +3974,18 @@ class NetworkLibraryStubImpl : public NetworkLibrary {
const std::string& ssid,
const std::string& passphrase,
const std::string& identity,
- const std::string& certpath,
- bool auto_connect) {}
+ const std::string& certpath) {}
virtual void ConnectToCellularNetwork(CellularNetwork* network) {}
+ virtual void ConnectToVirtualNetwork(VirtualNetwork* network) {}
+ virtual void ConnectToVirtualNetworkPSK(
+ const std::string& service_name,
+ const std::string& server,
+ const std::string& psk,
+ const std::string& username,
+ const std::string& user_passphrase) {}
virtual void SignalCellularPlanPayment() {}
virtual bool HasRecentCellularPlanPayment() { return false; }
- virtual void DisconnectFromWirelessNetwork(const WirelessNetwork* network) {}
+ virtual void DisconnectFromNetwork(const Network* network) {}
virtual void ForgetWifiNetwork(const std::string& service_path) {}
virtual bool ethernet_available() const { return true; }
virtual bool wifi_available() const { return false; }
@@ -3770,6 +3995,7 @@ class NetworkLibraryStubImpl : public NetworkLibrary {
virtual bool cellular_enabled() const { return false; }
virtual bool wifi_scanning() const { return false; }
virtual const Network* active_network() const { return NULL; }
+ virtual const Network* connected_network() const { return NULL; }
virtual bool offline_mode() const { return false; }
virtual void EnableEthernetNetworkDevice(bool enable) {}
virtual void EnableWifiNetworkDevice(bool enable) {}
@@ -3780,7 +4006,6 @@ class NetworkLibraryStubImpl : public NetworkLibrary {
hardware_address->clear();
return NetworkIPConfigVector();
}
- virtual std::string GetHtmlInfo(int refresh) { return std::string(); }
private:
std::string ip_address_;
diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h
index 41411a0..e80a810 100644
--- a/chrome/browser/chromeos/cros/network_library.h
+++ b/chrome/browser/chromeos/cros/network_library.h
@@ -227,9 +227,7 @@ class Network {
ConnectionType type() const { return type_; }
ConnectionMode mode() const { return mode_; }
ConnectionState connection_state() const { return state_; }
- bool connecting() const { return state_ == STATE_ASSOCIATION ||
- state_ == STATE_CONFIGURATION ||
- state_ == STATE_CARRIER; }
+ bool connecting() const { return IsConnectingState(state_); }
bool configuring() const { return state_ == STATE_CONFIGURATION; }
bool connected() const { return state_ == STATE_READY; }
bool connecting_or_connected() const { return connecting() || connected(); }
@@ -249,6 +247,7 @@ class Network {
bool favorite() const { return favorite_; }
bool auto_connect() const { return auto_connect_; }
ConnectivityState connectivity_state() const { return connectivity_state_; }
+ bool added() const { return added_; }
// We don't have a setter for |favorite_| because to unfavorite a network is
// equivalent to forget a network, so we call forget network on cros for
@@ -261,6 +260,12 @@ class Network {
// Return a string representation of the error code.
std::string GetErrorString() const;
+ static bool IsConnectingState(ConnectionState state) {
+ return (state == STATE_ASSOCIATION ||
+ state == STATE_CONFIGURATION ||
+ state == STATE_CARRIER);
+ }
+
protected:
Network(const std::string& service_path, ConnectionType type)
: state_(STATE_UNKNOWN),
@@ -270,23 +275,27 @@ class Network {
favorite_(false),
auto_connect_(false),
connectivity_state_(CONN_STATE_UNKNOWN),
- priority_(0),
+ priority_order_(0),
+ added_(false),
service_path_(service_path),
type_(type) {}
// Parse name/value pairs from libcros.
virtual bool ParseValue(int index, const Value* value);
- void ParseInfo(const DictionaryValue* info);
+ virtual void ParseInfo(const DictionaryValue* info);
// Methods to asynchronously set network service properties
- virtual void SetStringProperty(const char* prop, const std::string& str);
- virtual void SetBooleanProperty(const char* prop, bool b);
- virtual void SetIntegerProperty(const char* prop, int i);
+ virtual void SetStringProperty(const char* prop, const std::string& str,
+ std::string* dest);
+ virtual void SetBooleanProperty(const char* prop, bool b, bool* dest);
+ virtual void SetIntegerProperty(const char* prop, int i, int* dest);
virtual void SetValueProperty(const char* prop, Value* val);
virtual void ClearProperty(const char* prop);
+
// This will clear the property if string is empty. Otherwise, it will set it.
virtual void SetOrClearStringProperty(const char* prop,
- const std::string& str);
+ const std::string& str,
+ std::string* dest);
std::string device_path_;
std::string name_;
@@ -315,12 +324,16 @@ class Network {
void set_connectivity_state(ConnectivityState connectivity_state) {
connectivity_state_ = connectivity_state;
}
+ void set_added(bool added) { added_ = added; }
// Initialize the IP address field
void InitIPAddress();
- // Priority value, corresponds to index in list from flimflam (0 = highest)
- int priority_;
+ // Priority value, corresponds to index in list from flimflam (0 = first)
+ int priority_order_;
+
+ // Set to true if the UI requested this as a new network.
+ bool added_;
// These must not be modified after construction.
std::string service_path_;
@@ -328,6 +341,7 @@ class Network {
friend class NetworkLibraryImpl;
friend class NetworkLibraryStubImpl;
+ DISALLOW_COPY_AND_ASSIGN(Network);
// ChangeAutoConnectSaveTest accesses |favorite_|.
FRIEND_TEST_ALL_PREFIXES(WifiConfigViewTest, ChangeAutoConnectSaveTest);
};
@@ -338,14 +352,92 @@ class EthernetNetwork : public Network {
explicit EthernetNetwork(const std::string& service_path) :
Network(service_path, TYPE_ETHERNET) {
}
+ private:
+ friend class NetworkLibraryImpl;
+ DISALLOW_COPY_AND_ASSIGN(EthernetNetwork);
};
// Class for networks of TYPE_VPN.
class VirtualNetwork : public Network {
public:
+ enum ProviderType {
+ PROVIDER_TYPE_L2TP_IPSEC_PSK,
+ PROVIDER_TYPE_L2TP_IPSEC_USER_CERT,
+ PROVIDER_TYPE_OPEN_VPN,
+ // Add new provider types before PROVIDER_TYPE_MAX.
+ PROVIDER_TYPE_MAX,
+ };
+
explicit VirtualNetwork(const std::string& service_path) :
- Network(service_path, TYPE_VPN) {
+ Network(service_path, TYPE_VPN),
+ provider_type_(PROVIDER_TYPE_L2TP_IPSEC_PSK) {
}
+
+ const std::string& server_hostname() const { return server_hostname_; }
+ ProviderType provider_type() const { return provider_type_; }
+ const std::string& ca_cert() const { return ca_cert_; }
+ const std::string& psk_passphrase() const { return psk_passphrase_; }
+ const std::string& user_cert() const { return user_cert_; }
+ const std::string& user_cert_key() const { return user_cert_key_; }
+ const std::string& username() const { return username_; }
+ const std::string& user_passphrase() const { return user_passphrase_; }
+
+ bool NeedMoreInfoToConnect() const;
+
+ // Public setters.
+ void SetCACert(const std::string& ca_cert);
+ void SetPSKPassphrase(const std::string& psk_passphrase);
+ void SetUserCert(const std::string& user_cert);
+ void SetUserCertKey(const std::string& key);
+ void SetUsername(const std::string& username);
+ void SetUserPassphrase(const std::string& user_passphrase);
+
+ std::string GetProviderTypeString() const;
+
+ private:
+ // Network overrides.
+ virtual bool ParseValue(int index, const Value* value);
+ virtual void ParseInfo(const DictionaryValue* info);
+
+ // VirtualNetwork private methods.
+ bool ParseProviderValue(int index, const Value* value);
+
+ void set_server_hostname(const std::string& server_hostname) {
+ server_hostname_ = server_hostname;
+ }
+ void set_provider_type(ProviderType provider_type) {
+ provider_type_ = provider_type;
+ }
+ void set_ca_cert(const std::string& ca_cert) {
+ ca_cert_ = ca_cert;
+ }
+ void set_psk_passphrase(const std::string& psk_passphrase) {
+ psk_passphrase_ = psk_passphrase;
+ }
+ void set_user_cert(const std::string& user_cert) {
+ user_cert_ = user_cert;
+ }
+ void set_user_cert_key(const std::string& key) {
+ user_cert_key_ = key;
+ }
+ void set_username(const std::string& username) {
+ username_ = username;
+ }
+ void set_user_passphrase(const std::string& user_passphrase) {
+ user_passphrase_ = user_passphrase;
+ }
+
+ std::string server_hostname_;
+ ProviderType provider_type_;
+ std::string ca_cert_;
+ std::string psk_passphrase_;
+ std::string user_cert_;
+ std::string user_cert_key_;
+ std::string username_;
+ std::string user_passphrase_;
+
+ friend class NetworkLibraryImpl;
+ DISALLOW_COPY_AND_ASSIGN(VirtualNetwork);
};
typedef std::vector<VirtualNetwork*> VirtualNetworkVector;
@@ -368,6 +460,7 @@ class WirelessNetwork : public Network {
friend class NetworkLibraryImpl;
friend class NetworkLibraryStubImpl;
+ DISALLOW_COPY_AND_ASSIGN(WirelessNetwork);
};
// Class for networks of TYPE_CELLULAR.
@@ -490,6 +583,7 @@ class CellularNetwork : public WirelessNetwork {
friend class NetworkLibraryImpl;
friend class NetworkLibraryStubImpl;
+ DISALLOW_COPY_AND_ASSIGN(CellularNetwork);
};
typedef std::vector<CellularNetwork*> CellularNetworkVector;
@@ -598,6 +692,7 @@ class WifiNetwork : public WirelessNetwork {
std::string user_passphrase_;
friend class NetworkLibraryImpl;
+ DISALLOW_COPY_AND_ASSIGN(WifiNetwork);
};
typedef std::vector<WifiNetwork*> WifiNetworkVector;
@@ -854,6 +949,8 @@ class NetworkLibrary {
virtual WifiNetwork* FindWifiNetworkByPath(const std::string& path) const = 0;
virtual CellularNetwork* FindCellularNetworkByPath(
const std::string& path) const = 0;
+ virtual VirtualNetwork* FindVirtualNetworkByPath(
+ const std::string& path) const = 0;
// Retrieves the data plans associated with |path|, NULL if there are no
// associated plans.
@@ -903,13 +1000,13 @@ class NetworkLibrary {
// Same as above but searches for an existing network by name.
virtual void ConnectToWifiNetwork(const std::string& service_path) = 0;
- // Connect to the specified network with security, ssid, and passphrase.
+ // Connect to the specified network with security, ssid, passphrase, identity,
+ // and (optionally) certpath.
virtual void ConnectToWifiNetwork(ConnectionSecurity security,
const std::string& ssid,
const std::string& passphrase,
const std::string& identity,
- const std::string& certpath,
- bool auto_connect) = 0;
+ const std::string& certpath) = 0;
// Connect to the specified cellular network.
virtual void ConnectToCellularNetwork(CellularNetwork* network) = 0;
@@ -920,9 +1017,20 @@ class NetworkLibrary {
// Returns true if cellular plan payment had been recorded recently.
virtual bool HasRecentCellularPlanPayment() = 0;
- // Disconnect from the specified wireless (either cellular or wifi) network.
- virtual void DisconnectFromWirelessNetwork(
- const WirelessNetwork* network) = 0;
+ // Connect to the specified virtual network.
+ virtual void ConnectToVirtualNetwork(VirtualNetwork* network) = 0;
+
+ // Connect to the specified virtual network with service name,
+ // server hostname, provider_type, PSK passphrase, username and passphrase.
+ virtual void ConnectToVirtualNetworkPSK(
+ const std::string& service_name,
+ const std::string& server_hostname,
+ const std::string& psk,
+ const std::string& username,
+ const std::string& user_passphrase) = 0;
+
+ // Disconnect from the specified network.
+ virtual void DisconnectFromNetwork(const Network* network) = 0;
// Forget the wifi network corresponding to service_path.
virtual void ForgetWifiNetwork(const std::string& service_path) = 0;
@@ -938,6 +1046,7 @@ class NetworkLibrary {
virtual bool wifi_scanning() const = 0;
virtual const Network* active_network() const = 0;
+ virtual const Network* connected_network() const = 0;
virtual bool offline_mode() const = 0;
@@ -961,10 +1070,6 @@ class NetworkLibrary {
const std::string& device_path,
std::string* hardware_address) = 0;
- // Fetches debug network info for display in about:network.
- // The page will have a meta refresh of |refresh| seconds if |refresh| > 0.
- virtual std::string GetHtmlInfo(int refresh) = 0;
-
// Factory function, creates a new instance and returns ownership.
// For normal usage, access the singleton via CrosLibrary::Get().
static NetworkLibrary* GetImpl(bool stub);
diff --git a/chrome/browser/chromeos/network_login_observer.cc b/chrome/browser/chromeos/network_login_observer.cc
index 09e1a8e..9fa09d0 100644
--- a/chrome/browser/chromeos/network_login_observer.cc
+++ b/chrome/browser/chromeos/network_login_observer.cc
@@ -19,7 +19,8 @@
namespace chromeos {
NetworkLoginObserver::NetworkLoginObserver(NetworkLibrary* netlib) {
- RefreshStoredNetworks(netlib->wifi_networks());
+ RefreshStoredNetworks(netlib->wifi_networks(),
+ netlib->virtual_networks());
netlib->AddNetworkManagerObserver(this);
}
@@ -49,39 +50,49 @@ void NetworkLoginObserver::CreateModalPopup(views::WindowDelegate* view) {
}
void NetworkLoginObserver::RefreshStoredNetworks(
- const WifiNetworkVector& wifi_networks) {
- wifi_network_failures_.clear();
+ const WifiNetworkVector& wifi_networks,
+ const VirtualNetworkVector& virtual_networks) {
+ network_failures_.clear();
for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
- it < wifi_networks.end(); it++) {
+ it != wifi_networks.end(); it++) {
const WifiNetwork* wifi = *it;
- wifi_network_failures_[wifi->service_path()] = wifi->failed();
+ network_failures_[wifi->service_path()] = wifi->failed();
+ }
+ for (VirtualNetworkVector::const_iterator it = virtual_networks.begin();
+ it != virtual_networks.end(); it++) {
+ const VirtualNetwork* vpn = *it;
+ network_failures_[vpn->service_path()] = vpn->failed();
}
}
void NetworkLoginObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
const WifiNetworkVector& wifi_networks = cros->wifi_networks();
+ const VirtualNetworkVector& virtual_networks = cros->virtual_networks();
NetworkConfigView* view = NULL;
// Check to see if we have any newly failed wifi network.
for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
- it < wifi_networks.end(); it++) {
+ it != wifi_networks.end(); it++) {
WifiNetwork* wifi = *it;
if (wifi->failed()) {
- WifiFailureMap::iterator iter =
- wifi_network_failures_.find(wifi->service_path());
+ NetworkFailureMap::iterator iter =
+ network_failures_.find(wifi->service_path());
// If the network did not previously exist, then don't do anything.
// For example, if the user travels to a location and finds a service
// that has previously failed, we don't want to show an error.
- if (iter == wifi_network_failures_.end())
+ if (iter == network_failures_.end())
continue;
// If this network was in a failed state previously, then it's not new.
if (iter->second)
continue;
- // Display login box again for bad_passphrase and bad_wepkey errors.
+ // Display login dialog again for bad_passphrase and bad_wepkey errors.
+ // Always re-display the login dialog for added networks that failed to
+ // connect for any reason (e.g. incorrect security type was chosen).
if (wifi->error() == ERROR_BAD_PASSPHRASE ||
- wifi->error() == ERROR_BAD_WEPKEY) {
+ wifi->error() == ERROR_BAD_WEPKEY ||
+ wifi->added()) {
// The NetworkConfigView will show the appropriate error message.
view = new NetworkConfigView(wifi);
// There should only be one wifi network that failed to connect.
@@ -91,8 +102,28 @@ void NetworkLoginObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
}
}
}
+ // Check to see if we have any newly failed virtual network.
+ // See wifi section for detailed comments.
+ if (!view) {
+ for (VirtualNetworkVector::const_iterator it = virtual_networks.begin();
+ it != virtual_networks.end(); it++) {
+ VirtualNetwork* vpn = *it;
+ if (vpn->failed()) {
+ NetworkFailureMap::iterator iter =
+ network_failures_.find(vpn->service_path());
+ if (iter == network_failures_.end())
+ continue; // New network.
+ if (iter->second)
+ continue; // Previous failure.
+ if (vpn->error() == ERROR_BAD_PASSPHRASE || vpn->added()) {
+ view = new NetworkConfigView(vpn);
+ break;
+ }
+ }
+ }
+ }
- RefreshStoredNetworks(wifi_networks);
+ RefreshStoredNetworks(wifi_networks, virtual_networks);
// Show login box if necessary.
if (view)
diff --git a/chrome/browser/chromeos/network_login_observer.h b/chrome/browser/chromeos/network_login_observer.h
index 0c5df5f..34970aa 100644
--- a/chrome/browser/chromeos/network_login_observer.h
+++ b/chrome/browser/chromeos/network_login_observer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -25,17 +25,18 @@ class NetworkLoginObserver : public NetworkLibrary::NetworkManagerObserver {
explicit NetworkLoginObserver(NetworkLibrary* netlib);
virtual ~NetworkLoginObserver();
- typedef std::map<std::string, bool> WifiFailureMap;
+ typedef std::map<std::string, bool> NetworkFailureMap;
private:
virtual void CreateModalPopup(views::WindowDelegate* view);
- virtual void RefreshStoredNetworks(const WifiNetworkVector& wifi_networks);
+ virtual void RefreshStoredNetworks(const WifiNetworkVector& wifi_networks,
+ const VirtualNetworkVector& vpn_networks);
// NetworkLibrary::NetworkManagerObserver implementation.
virtual void OnNetworkManagerChanged(NetworkLibrary* obj);
// Wifi networks by service path mapped to if it failed previously.
- WifiFailureMap wifi_network_failures_;
+ NetworkFailureMap network_failures_;
DISALLOW_COPY_AND_ASSIGN(NetworkLoginObserver);
};
diff --git a/chrome/browser/chromeos/network_message_observer.cc b/chrome/browser/chromeos/network_message_observer.cc
index ece96d6..477c307 100644
--- a/chrome/browser/chromeos/network_message_observer.cc
+++ b/chrome/browser/chromeos/network_message_observer.cc
@@ -62,8 +62,6 @@ NetworkMessageObserver::~NetworkMessageObserver() {
notification_connection_error_.Hide();
notification_low_data_.Hide();
notification_no_data_.Hide();
- STLDeleteValues(&cellular_networks_);
- STLDeleteValues(&wifi_networks_);
}
// static
@@ -162,63 +160,83 @@ void NetworkMessageObserver::ShowLowDataNotification(
false, false);
}
-void NetworkMessageObserver::OnNetworkManagerChanged(NetworkLibrary* obj) {
- const WifiNetworkVector& wifi_networks = obj->wifi_networks();
- const CellularNetworkVector& cellular_networks = obj->cellular_networks();
-
- std::string new_failed_network;
- // Check to see if we have any newly failed wifi network.
- for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
- it < wifi_networks.end(); it++) {
- const WifiNetwork* wifi = *it;
- if (wifi->failed()) {
- ServicePathWifiMap::iterator iter =
- wifi_networks_.find(wifi->service_path());
- // If the network did not previously exist, then don't do anything.
- // For example, if the user travels to a location and finds a service
- // that has previously failed, we don't want to show a notification.
- if (iter == wifi_networks_.end())
- continue;
-
- const WifiNetwork* wifi_old = iter->second;
- // If network connection failed, display a notification.
- // We only do this if we were trying to make a new connection.
- // So if a previously connected network got disconnected for any reason,
- // we don't display notification.
- if (wifi_old->connecting()) {
- new_failed_network = wifi->name();
- // Like above, there should only be one newly failed network.
- break;
- }
+bool NetworkMessageObserver::CheckNetworkFailed(const Network* network) {
+ if (network->failed()) {
+ NetworkStateMap::iterator iter =
+ network_states_.find(network->service_path());
+ // If the network did not previously exist, then don't do anything.
+ // For example, if the user travels to a location and finds a service
+ // that has previously failed, we don't want to show a notification.
+ if (iter == network_states_.end())
+ return false;
+ // If network connection failed, display a notification.
+ // We only do this if we were trying to make a new connection.
+ // So if a previously connected network got disconnected for any reason,
+ // we don't display notification.
+ ConnectionState prev_state = iter->second;
+ if (Network::IsConnectingState(prev_state))
+ return true;
+ }
+ return false;
+}
+
+void NetworkMessageObserver::OnNetworkManagerChanged(NetworkLibrary* cros) {
+ const Network* new_failed_network = NULL;
+ // Check to see if we have any newly failed networks.
+ for (WifiNetworkVector::const_iterator it = cros->wifi_networks().begin();
+ it != cros->wifi_networks().end(); it++) {
+ const WifiNetwork* net = *it;
+ if (CheckNetworkFailed(net)) {
+ new_failed_network = net;
+ break; // There should only be one failed network.
}
}
- // Refresh stored networks.
- STLDeleteValues(&wifi_networks_);
- wifi_networks_.clear();
- for (WifiNetworkVector::const_iterator it = wifi_networks.begin();
- it < wifi_networks.end(); it++) {
- const WifiNetwork* wifi = *it;
- wifi_networks_[wifi->service_path()] = new WifiNetwork(*wifi);
+ if (!new_failed_network) {
+ for (CellularNetworkVector::const_iterator it =
+ cros->cellular_networks().begin();
+ it != cros->cellular_networks().end(); it++) {
+ const CellularNetwork* net = *it;
+ if (CheckNetworkFailed(net)) {
+ new_failed_network = net;
+ break; // There should only be one failed network.
+ }
+ }
}
- STLDeleteValues(&cellular_networks_);
- cellular_networks_.clear();
- for (CellularNetworkVector::const_iterator it = cellular_networks.begin();
- it < cellular_networks.end(); it++) {
- const CellularNetwork* cellular = *it;
- cellular_networks_[cellular->service_path()] =
- new CellularNetwork(*cellular);
+ if (!new_failed_network) {
+ for (VirtualNetworkVector::const_iterator it =
+ cros->virtual_networks().begin();
+ it != cros->virtual_networks().end(); it++) {
+ const VirtualNetwork* net = *it;
+ if (CheckNetworkFailed(net)) {
+ new_failed_network = net;
+ break; // There should only be one failed network.
+ }
+ }
}
+ network_states_.clear();
+ for (WifiNetworkVector::const_iterator it = cros->wifi_networks().begin();
+ it != cros->wifi_networks().end(); it++)
+ network_states_[(*it)->service_path()] = (*it)->state();
+ for (CellularNetworkVector::const_iterator it =
+ cros->cellular_networks().begin();
+ it != cros->cellular_networks().end(); it++)
+ network_states_[(*it)->service_path()] = (*it)->state();
+ for (VirtualNetworkVector::const_iterator it =
+ cros->virtual_networks().begin();
+ it != cros->virtual_networks().end(); it++)
+ network_states_[(*it)->service_path()] = (*it)->state();
+
// Show connection error notification if necessary.
- if (!new_failed_network.empty()) {
+ if (new_failed_network) {
// Hide if already shown to force show it in case user has closed it.
if (notification_connection_error_.visible())
notification_connection_error_.Hide();
notification_connection_error_.Show(l10n_util::GetStringFUTF16(
IDS_NETWORK_CONNECTION_ERROR_MESSAGE,
- ASCIIToUTF16(new_failed_network)), false, false);
+ ASCIIToUTF16(new_failed_network->name())), false, false);
}
}
@@ -279,7 +297,7 @@ void NetworkMessageObserver::OnCellularDataPlanChanged(NetworkLibrary* cros) {
cellular_data_plan_type_ = current_plan->plan_type;
}
-void NetworkMessageObserver::OnConnectionInitiated(NetworkLibrary* obj,
+void NetworkMessageObserver::OnConnectionInitiated(NetworkLibrary* cros,
const Network* network) {
// If user initiated any network connection, we hide the error notification.
notification_connection_error_.Hide();
diff --git a/chrome/browser/chromeos/network_message_observer.h b/chrome/browser/chromeos/network_message_observer.h
index 9fe263c..78112d5 100644
--- a/chrome/browser/chromeos/network_message_observer.h
+++ b/chrome/browser/chromeos/network_message_observer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -27,8 +27,6 @@ class NetworkMessageObserver : public NetworkLibrary::NetworkManagerObserver,
explicit NetworkMessageObserver(Profile* profile);
virtual ~NetworkMessageObserver();
- typedef std::map<std::string, WifiNetwork*> ServicePathWifiMap;
- typedef std::map<std::string, CellularNetwork*> ServicePathCellularMap;
static bool IsApplicableBackupPlan(const CellularDataPlan* plan,
const CellularDataPlan* other_plan);
private:
@@ -38,6 +36,7 @@ class NetworkMessageObserver : public NetworkLibrary::NetworkManagerObserver,
virtual void ShowNeedsPlanNotification(const CellularNetwork* cellular);
virtual void ShowNoDataNotification(CellularDataPlanType plan_type);
virtual void ShowLowDataNotification(const CellularDataPlan* plan);
+ virtual bool CheckNetworkFailed(const Network* network);
// NetworkLibrary::NetworkManagerObserver implementation.
virtual void OnNetworkManagerChanged(NetworkLibrary* obj);
@@ -47,10 +46,10 @@ class NetworkMessageObserver : public NetworkLibrary::NetworkManagerObserver,
virtual void OnConnectionInitiated(NetworkLibrary* obj,
const Network* network);
- // Wifi networks by service path.
- ServicePathWifiMap wifi_networks_;
- // Cellular networks by service path.
- ServicePathCellularMap cellular_networks_;
+ typedef std::map<std::string, ConnectionState> NetworkStateMap;
+
+ // Network state by service path.
+ NetworkStateMap network_states_;
// Current connect celluar service path.
std::string cellular_service_path_;
diff --git a/chrome/browser/chromeos/options/network_config_view.cc b/chrome/browser/chromeos/options/network_config_view.cc
index 8b4f9f0..39afba8 100644
--- a/chrome/browser/chromeos/options/network_config_view.cc
+++ b/chrome/browser/chromeos/options/network_config_view.cc
@@ -8,6 +8,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/chromeos/options/vpn_config_view.h"
#include "chrome/browser/chromeos/options/wifi_config_view.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
@@ -23,20 +24,35 @@ using views::WidgetGtk;
namespace chromeos {
-NetworkConfigView::NetworkConfigView(WifiNetwork* wifi)
+// static
+const int ChildNetworkConfigView::kPassphraseWidth = 150;
+
+NetworkConfigView::NetworkConfigView(Network* network)
: browser_mode_(true),
- title_(UTF16ToWide(
- l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS))),
- wificonfig_view_(new WifiConfigView(this, wifi)),
delegate_(NULL) {
+ if (network->type() == TYPE_WIFI) {
+ child_config_view_ =
+ new WifiConfigView(this, static_cast<WifiNetwork*>(network));
+ } else if (network->type() == TYPE_VPN) {
+ child_config_view_ =
+ new VPNConfigView(this, static_cast<VirtualNetwork*>(network));
+ } else {
+ NOTREACHED();
+ child_config_view_ = NULL;
+ }
}
-NetworkConfigView::NetworkConfigView()
+NetworkConfigView::NetworkConfigView(ConnectionType type)
: browser_mode_(true),
- title_(UTF16ToWide(
- l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS))),
- wificonfig_view_(new WifiConfigView(this)),
delegate_(NULL) {
+ if (type == TYPE_WIFI) {
+ child_config_view_ = new WifiConfigView(this);
+ } else if (type == TYPE_VPN) {
+ child_config_view_ = new VPNConfigView(this);
+ } else {
+ NOTREACHED();
+ child_config_view_ = NULL;
+ }
}
gfx::NativeWindow NetworkConfigView::GetNativeWindow() const {
@@ -55,26 +71,26 @@ bool NetworkConfigView::IsDialogButtonEnabled(
MessageBoxFlags::DialogButton button) const {
// Disable connect button if cannot login.
if (button == MessageBoxFlags::DIALOGBUTTON_OK)
- return wificonfig_view_->CanLogin();
+ return child_config_view_->CanLogin();
return true;
}
bool NetworkConfigView::Cancel() {
if (delegate_)
delegate_->OnDialogCancelled();
- wificonfig_view_->Cancel();
+ child_config_view_->Cancel();
return true;
}
bool NetworkConfigView::Accept() {
- bool result = wificonfig_view_->Login();
+ bool result = child_config_view_->Login();
if (result && delegate_)
delegate_->OnDialogAccepted();
return result;
}
std::wstring NetworkConfigView::GetWindowTitle() const {
- return title_;
+ return UTF16ToWide(child_config_view_->GetTitle());
}
void NetworkConfigView::GetAccessibleState(ui::AccessibleViewState* state) {
@@ -84,14 +100,17 @@ void NetworkConfigView::GetAccessibleState(ui::AccessibleViewState* state) {
}
void NetworkConfigView::Layout() {
- wificonfig_view_->SetBounds(0, 0, width(), height());
+ child_config_view_->SetBounds(0, 0, width(), height());
}
gfx::Size NetworkConfigView::GetPreferredSize() {
gfx::Size result(views::Window::GetLocalizedContentsSize(
IDS_JOIN_WIFI_NETWORK_DIALOG_WIDTH_CHARS,
IDS_JOIN_WIFI_NETWORK_DIALOG_MINIMUM_HEIGHT_LINES));
- result.set_height(wificonfig_view_->GetPreferredSize().height());
+ gfx::Size size = child_config_view_->GetPreferredSize();
+ result.set_height(size.height());
+ if (size.width() > result.width())
+ result.set_width(size.width());
return result;
}
@@ -100,7 +119,7 @@ void NetworkConfigView::ViewHierarchyChanged(
// Can't init before we're inserted into a Container, because we require
// a HWND to parent native child controls to.
if (is_add && child == this)
- AddChildView(wificonfig_view_);
+ AddChildView(child_config_view_);
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/options/network_config_view.h b/chrome/browser/chromeos/options/network_config_view.h
index d3de6bb..02e4762 100644
--- a/chrome/browser/chromeos/options/network_config_view.h
+++ b/chrome/browser/chromeos/options/network_config_view.h
@@ -16,7 +16,7 @@ class Window;
namespace chromeos {
-class WifiConfigView;
+class ChildNetworkConfigView;
// A dialog box for showing a password textfield.
class NetworkConfigView : public views::View,
@@ -34,10 +34,10 @@ class NetworkConfigView : public views::View,
virtual ~Delegate() {}
};
- // Login dialog for wifi.
- explicit NetworkConfigView(WifiNetwork* wifi);
- // Login dialog for hidden networks.
- explicit NetworkConfigView();
+ // Login dialog for known networks.
+ explicit NetworkConfigView(Network* network);
+ // Login dialog for new/hidden networks.
+ explicit NetworkConfigView(ConnectionType type);
virtual ~NetworkConfigView() {}
// Returns corresponding native window.
@@ -83,17 +83,50 @@ class NetworkConfigView : public views::View,
// True when opening in browser, otherwise in OOBE/login mode.
bool browser_mode_;
- std::wstring title_;
-
- // WifiConfig is the only child of this class.
- // It will get deleted when NetworkConfigView gets cleaned up.
- WifiConfigView* wificonfig_view_;
+ // There's always only one child view, which will get deleted when
+ // NetworkConfigView gets cleaned up.
+ ChildNetworkConfigView* child_config_view_;
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(NetworkConfigView);
};
+// Children of NetworkConfigView must subclass this and implement the virtual
+// methods, which are called by NetworkConfigView.
+class ChildNetworkConfigView : public views::View {
+ public:
+ // Called to get title for parent NetworkConfigView dialog box.
+ virtual string16 GetTitle() = 0;
+
+ // Called to determine if "Connect" button should be enabled.
+ virtual bool CanLogin() = 0;
+
+ // Called when "Connect" button is clicked.
+ // Should return false if dialog should remain open.
+ virtual bool Login() = 0;
+
+ // Called when "Cancel" button is clicked.
+ virtual void Cancel() = 0;
+
+ // Width of passphrase fields.
+ static const int kPassphraseWidth;
+
+ protected:
+ explicit ChildNetworkConfigView(NetworkConfigView* parent, Network* network)
+ : service_path_(network->service_path()),
+ parent_(parent) {}
+ explicit ChildNetworkConfigView(NetworkConfigView* parent)
+ : parent_(parent) {}
+ virtual ~ChildNetworkConfigView() {}
+
+ std::string service_path_;
+ NetworkConfigView* parent_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ChildNetworkConfigView);
+};
+
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_OPTIONS_NETWORK_CONFIG_VIEW_H_
diff --git a/chrome/browser/chromeos/options/vpn_config_view.cc b/chrome/browser/chromeos/options/vpn_config_view.cc
new file mode 100644
index 0000000..d1456dc
--- /dev/null
+++ b/chrome/browser/chromeos/options/vpn_config_view.cc
@@ -0,0 +1,443 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/options/vpn_config_view.h"
+
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "grit/theme_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "views/controls/button/image_button.h"
+#include "views/controls/button/native_button.h"
+#include "views/controls/label.h"
+#include "views/controls/textfield/textfield.h"
+#include "views/layout/grid_layout.h"
+#include "views/layout/layout_constants.h"
+#include "views/window/window.h"
+
+namespace {
+
+string16 ProviderTypeToString(chromeos::VirtualNetwork::ProviderType type) {
+ switch (type) {
+ case chromeos::VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK:
+ return l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK);
+ case chromeos::VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
+ return l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT);
+ case chromeos::VirtualNetwork::PROVIDER_TYPE_OPEN_VPN:
+ return l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN);
+ case chromeos::VirtualNetwork::PROVIDER_TYPE_MAX:
+ break;
+ }
+ NOTREACHED();
+ return string16();
+}
+
+} // namespace
+
+namespace chromeos {
+
+int VPNConfigView::ProviderTypeComboboxModel::GetItemCount() {
+ // TODO(stevenjb): Include OpenVPN option once enabled.
+ return VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT + 1;
+ // return VirtualNetwork::PROVIDER_TYPE_MAX;
+}
+
+string16 VPNConfigView::ProviderTypeComboboxModel::GetItemAt(int index) {
+ VirtualNetwork::ProviderType type =
+ static_cast<VirtualNetwork::ProviderType>(index);
+ return ProviderTypeToString(type);
+}
+
+VPNConfigView::UserCertComboboxModel::UserCertComboboxModel() {
+ // TODO(jamescook): populate user_certs_. chromium-os:14111
+}
+
+int VPNConfigView::UserCertComboboxModel::GetItemCount() {
+ return static_cast<int>(user_certs_.size());
+}
+
+string16 VPNConfigView::UserCertComboboxModel::GetItemAt(int index) {
+ if (index >= 0 && index < static_cast<int>(user_certs_.size()))
+ return ASCIIToUTF16(user_certs_[index]);
+ return string16();
+}
+
+VPNConfigView::VPNConfigView(NetworkConfigView* parent, VirtualNetwork* vpn)
+ : ChildNetworkConfigView(parent, vpn) {
+ Init(vpn);
+}
+
+VPNConfigView::VPNConfigView(NetworkConfigView* parent)
+ : ChildNetworkConfigView(parent) {
+ Init(NULL);
+}
+
+VPNConfigView::~VPNConfigView() {
+}
+
+void VPNConfigView::UpdateCanLogin() {
+ parent_->GetDialogClientView()->UpdateDialogButtons();
+}
+
+string16 VPNConfigView::GetTitle() {
+ return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_ADD_VPN);
+}
+
+bool VPNConfigView::CanLogin() {
+ static const size_t kMinPassphraseLen = 0; // TODO(stevenjb): min length?
+ if (service_path_.empty() &&
+ (GetService().empty() || GetServer().empty()))
+ return false;
+ if (provider_type_ == VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK &&
+ psk_passphrase_textfield_->text().length() < kMinPassphraseLen)
+ return false;
+ if (GetUsername().empty())
+ return false;
+ if (user_passphrase_textfield_->text().length() < kMinPassphraseLen)
+ return false;
+ return true;
+}
+
+void VPNConfigView::UpdateErrorLabel() {
+ std::string error_msg;
+ if (!service_path_.empty()) {
+ // TODO(kuan): differentiate between bad psk and user passphrases.
+ NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+ VirtualNetwork* vpn = cros->FindVirtualNetworkByPath(service_path_);
+ if (vpn && vpn->failed()) {
+ if (vpn->error() == ERROR_BAD_PASSPHRASE) {
+ error_msg = l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_PASSPHRASE);
+ } else {
+ error_msg = vpn->GetErrorString();
+ }
+ }
+ }
+ if (!error_msg.empty()) {
+ error_label_->SetText(UTF8ToWide(error_msg));
+ error_label_->SetVisible(true);
+ } else {
+ error_label_->SetVisible(false);
+ }
+}
+
+void VPNConfigView::ContentsChanged(views::Textfield* sender,
+ const string16& new_contents) {
+ if (sender == server_textfield_ && !service_text_modified_) {
+ // Set the service name to the server name up to '.', unless it has
+ // been explicityly set by the user.
+ string16 server = server_textfield_->text();
+ string16::size_type n = server.find_first_of(L'.');
+ service_name_from_server_ = server.substr(0, n);
+ service_textfield_->SetText(service_name_from_server_);
+ }
+ if (sender == service_textfield_) {
+ if (new_contents.empty())
+ service_text_modified_ = false;
+ else if (new_contents != service_name_from_server_)
+ service_text_modified_ = true;
+ }
+ UpdateCanLogin();
+}
+
+bool VPNConfigView::HandleKeyEvent(views::Textfield* sender,
+ const views::KeyEvent& key_event) {
+ if ((sender == psk_passphrase_textfield_ ||
+ sender == user_passphrase_textfield_) &&
+ key_event.key_code() == ui::VKEY_RETURN) {
+ parent_->GetDialogClientView()->AcceptWindow();
+ }
+ return false;
+}
+
+void VPNConfigView::ButtonPressed(views::Button* sender,
+ const views::Event& event) {
+}
+
+void VPNConfigView::ItemChanged(views::Combobox* combo_box,
+ int prev_index, int new_index) {
+ if (prev_index == new_index)
+ return;
+ if (combo_box == provider_type_combobox_) {
+ provider_type_ = static_cast<VirtualNetwork::ProviderType>(new_index);
+ EnableControls();
+ } else if (combo_box == user_cert_combobox_) {
+ // Nothing to do for now.
+ } else {
+ NOTREACHED();
+ }
+ UpdateCanLogin();
+}
+
+bool VPNConfigView::Login() {
+ NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+ if (service_path_.empty()) {
+ switch (provider_type_) {
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK:
+ cros->ConnectToVirtualNetworkPSK(GetService(),
+ GetServer(),
+ GetPSKPassphrase(),
+ GetUsername(),
+ GetUserPassphrase());
+ break;
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
+ case VirtualNetwork::PROVIDER_TYPE_OPEN_VPN:
+ // TODO(stevenjb): Add support for OpenVPN and user certs.
+ LOG(WARNING) << "Unsupported provider type: " << provider_type_;
+ break;
+ case VirtualNetwork::PROVIDER_TYPE_MAX:
+ break;
+ }
+ } else {
+ VirtualNetwork* vpn = cros->FindVirtualNetworkByPath(service_path_);
+ if (!vpn) {
+ // TODO(stevenjb): Add notification for this.
+ LOG(WARNING) << "VPN no longer exists: " << service_path_;
+ return true; // Close dialog.
+ }
+ switch (provider_type_) {
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK:
+ vpn->SetPSKPassphrase(GetPSKPassphrase());
+ break;
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
+ case VirtualNetwork::PROVIDER_TYPE_OPEN_VPN: {
+ const std::string user_cert = UTF16ToUTF8(
+ user_cert_combobox_->model()->GetItemAt(
+ user_cert_combobox_->selected_item()));
+ vpn->SetUserCert(user_cert);
+ break;
+ }
+ case VirtualNetwork::PROVIDER_TYPE_MAX:
+ break;
+ }
+ vpn->SetUsername(GetUsername());
+ vpn->SetUserPassphrase(GetUserPassphrase());
+
+ cros->ConnectToVirtualNetwork(vpn);
+ }
+ // Connection failures are responsible for updating the UI, including
+ // reopening dialogs.
+ return true; // Close dialog.
+}
+
+void VPNConfigView::Cancel() {
+}
+
+const std::string VPNConfigView::GetTextFromField(
+ views::Textfield* textfield, bool trim_whitespace) const {
+ std::string untrimmed = UTF16ToUTF8(textfield->text());
+ if (!trim_whitespace)
+ return untrimmed;
+ std::string result;
+ TrimWhitespaceASCII(untrimmed, TRIM_ALL, &result);
+ return result;
+}
+
+const std::string VPNConfigView::GetService() const {
+ if (service_textfield_ != NULL)
+ return GetTextFromField(service_textfield_, true);
+ return service_path_;
+}
+
+const std::string VPNConfigView::GetServer() const {
+ if (server_textfield_ != NULL)
+ return GetTextFromField(server_textfield_, true);
+ return server_hostname_;
+}
+
+const std::string VPNConfigView::GetPSKPassphrase() const {
+ if (psk_passphrase_textfield_->IsEnabled() &&
+ psk_passphrase_textfield_->IsVisible())
+ return GetTextFromField(psk_passphrase_textfield_, false);
+ return std::string();
+}
+
+const std::string VPNConfigView::GetUsername() const {
+ return GetTextFromField(username_textfield_, true);
+}
+
+const std::string VPNConfigView::GetUserPassphrase() const {
+ return GetTextFromField(user_passphrase_textfield_, false);
+}
+
+void VPNConfigView::Init(VirtualNetwork* vpn) {
+ views::GridLayout* layout = views::GridLayout::CreatePanel(this);
+ SetLayoutManager(layout);
+
+ int column_view_set_id = 0;
+ views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
+ // Label.
+ column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
+ views::GridLayout::USE_PREF, 0, 0);
+ column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
+ // Textfield, combobox.
+ column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
+ views::GridLayout::USE_PREF, 0,
+ ChildNetworkConfigView::kPassphraseWidth);
+ column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
+ // Passphrase visible button.
+ column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
+ views::GridLayout::USE_PREF, 0, 0);
+
+ // Initialize members.
+ service_text_modified_ = false;
+ provider_type_ = vpn ?
+ vpn->provider_type() :
+ chromeos::VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK;
+
+ // Server label and input.
+ layout->StartRow(0, column_view_set_id);
+ layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVER_HOSTNAME))));
+ if (!vpn) {
+ server_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
+ server_textfield_->SetController(this);
+ layout->AddView(server_textfield_);
+ server_text_ = NULL;
+ } else {
+ server_hostname_ = vpn->server_hostname();
+ server_text_ = new views::Label(ASCIIToWide(server_hostname_));
+ server_text_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ layout->AddView(server_text_);
+ server_textfield_ = NULL;
+ }
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ // Service label and name or input.
+ layout->StartRow(0, column_view_set_id);
+ layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_SERVICE_NAME))));
+ if (!vpn) {
+ service_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
+ service_textfield_->SetController(this);
+ layout->AddView(service_textfield_);
+ service_text_ = NULL;
+ } else {
+ service_text_ = new views::Label(ASCIIToWide(vpn->name()));
+ service_text_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ layout->AddView(service_text_);
+ service_textfield_ = NULL;
+ }
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ // Provider type label and select.
+ layout->StartRow(0, column_view_set_id);
+ layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PROVIDER_TYPE))));
+ if (!vpn) {
+ provider_type_combobox_ =
+ new views::Combobox(new ProviderTypeComboboxModel());
+ provider_type_combobox_->set_listener(this);
+ layout->AddView(provider_type_combobox_);
+ provider_type_text_label_ = NULL;
+ } else {
+ provider_type_text_label_ =
+ new views::Label(UTF16ToWide(ProviderTypeToString(provider_type_)));
+ layout->AddView(provider_type_text_label_);
+ provider_type_combobox_ = NULL;
+ }
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ // PSK passphrase label, input and visible button.
+ layout->StartRow(0, column_view_set_id);
+ psk_passphrase_label_ = new views::Label(UTF16ToWide(
+ l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_PSK_PASSPHRASE)));
+ layout->AddView(psk_passphrase_label_);
+ psk_passphrase_textfield_ = new views::Textfield(
+ views::Textfield::STYLE_PASSWORD);
+ psk_passphrase_textfield_->SetController(this);
+ if (vpn && !vpn->psk_passphrase().empty())
+ psk_passphrase_textfield_->SetText(UTF8ToUTF16(vpn->psk_passphrase()));
+ layout->AddView(psk_passphrase_textfield_);
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ // User certificate label and input.
+ layout->StartRow(0, column_view_set_id);
+ user_cert_label_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USER_CERT)));
+ layout->AddView(user_cert_label_);
+ user_cert_combobox_ = new views::Combobox(new UserCertComboboxModel());
+ user_cert_combobox_->set_listener(this);
+ if (vpn && !vpn->user_cert().empty()) {
+ string16 user_cert = UTF8ToUTF16(vpn->user_cert());
+ for (int i = 0; i < user_cert_combobox_->model()->GetItemCount(); ++i) {
+ if (user_cert_combobox_->model()->GetItemAt(i) == user_cert) {
+ user_cert_combobox_->SetSelectedItem(i);
+ break;
+ }
+ }
+ }
+ layout->AddView(user_cert_combobox_);
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ // Username label and input.
+ layout->StartRow(0, column_view_set_id);
+ layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USERNAME))));
+ username_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
+ username_textfield_->SetController(this);
+ if (vpn && !vpn->username().empty())
+ username_textfield_->SetText(UTF8ToUTF16(vpn->username()));
+ layout->AddView(username_textfield_);
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ // User passphrase label, input and visble button.
+ layout->StartRow(0, column_view_set_id);
+ layout->AddView(new views::Label(UTF16ToWide(
+ l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_VPN_USER_PASSPHRASE))));
+ user_passphrase_textfield_ = new views::Textfield(
+ views::Textfield::STYLE_PASSWORD);
+ user_passphrase_textfield_->SetController(this);
+ if (vpn && !vpn->user_passphrase().empty())
+ user_passphrase_textfield_->SetText(UTF8ToUTF16(vpn->user_passphrase()));
+ layout->AddView(user_passphrase_textfield_);
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ // Error label.
+ layout->StartRow(0, column_view_set_id);
+ layout->SkipColumns(1);
+ error_label_ = new views::Label();
+ error_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ error_label_->SetColor(SK_ColorRED);
+ layout->AddView(error_label_);
+
+ // Enable controls based on provider type combo.
+ EnableControls();
+
+ // Set or hide the error text.
+ UpdateErrorLabel();
+}
+
+void VPNConfigView::EnableControls() {
+ switch (provider_type_) {
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_PSK:
+ psk_passphrase_label_->SetEnabled(true);
+ psk_passphrase_textfield_->SetEnabled(true);
+ user_cert_label_->SetEnabled(false);
+ user_cert_combobox_->SetEnabled(false);
+ break;
+ case VirtualNetwork::PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
+ case VirtualNetwork::PROVIDER_TYPE_OPEN_VPN:
+ psk_passphrase_label_->SetEnabled(false);
+ psk_passphrase_textfield_->SetEnabled(false);
+ user_cert_label_->SetEnabled(true);
+ user_cert_combobox_->SetEnabled(true);
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/options/vpn_config_view.h b/chrome/browser/chromeos/options/vpn_config_view.h
new file mode 100644
index 0000000..17a81de
--- /dev/null
+++ b/chrome/browser/chromeos/options/vpn_config_view.h
@@ -0,0 +1,125 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_OPTIONS_VPN_CONFIG_VIEW_H_
+#define CHROME_BROWSER_CHROMEOS_OPTIONS_VPN_CONFIG_VIEW_H_
+#pragma once
+
+#include <string>
+
+#include "base/string16.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
+#include "chrome/browser/chromeos/options/network_config_view.h"
+#include "chrome/browser/ui/shell_dialogs.h"
+#include "ui/base/models/combobox_model.h"
+#include "views/controls/button/button.h"
+#include "views/controls/button/native_button.h"
+#include "views/controls/combobox/combobox.h"
+#include "views/controls/textfield/textfield_controller.h"
+#include "views/view.h"
+
+namespace views {
+class Label;
+}
+
+namespace chromeos {
+
+// A dialog box to allow configuration of VPN connection.
+class VPNConfigView : public ChildNetworkConfigView,
+ public views::TextfieldController,
+ public views::ButtonListener,
+ public views::Combobox::Listener {
+ public:
+ VPNConfigView(NetworkConfigView* parent, VirtualNetwork* vpn);
+ explicit VPNConfigView(NetworkConfigView* parent);
+ virtual ~VPNConfigView();
+
+ // views::TextfieldController methods.
+ virtual void ContentsChanged(views::Textfield* sender,
+ const string16& new_contents);
+ virtual bool HandleKeyEvent(views::Textfield* sender,
+ const views::KeyEvent& key_event);
+
+ // views::ButtonListener
+ virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+
+ // views::Combobox::Listener
+ virtual void ItemChanged(views::Combobox* combo_box,
+ int prev_index, int new_index);
+
+ // ChildNetworkConfigView implementation.
+ virtual string16 GetTitle() OVERRIDE;
+ virtual bool CanLogin() OVERRIDE;
+ virtual bool Login() OVERRIDE;
+ virtual void Cancel() OVERRIDE;
+
+ private:
+ class ProviderTypeComboboxModel : public ui::ComboboxModel {
+ public:
+ ProviderTypeComboboxModel() {}
+ virtual ~ProviderTypeComboboxModel() {}
+ virtual int GetItemCount();
+ virtual string16 GetItemAt(int index);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ProviderTypeComboboxModel);
+ };
+
+ class UserCertComboboxModel : public ui::ComboboxModel {
+ public:
+ UserCertComboboxModel();
+ virtual ~UserCertComboboxModel() {}
+ virtual int GetItemCount();
+ virtual string16 GetItemAt(int index);
+ private:
+ std::vector<std::string> user_certs_;
+ DISALLOW_COPY_AND_ASSIGN(UserCertComboboxModel);
+ };
+
+ // Initializes data members and create UI controls.
+ void Init(VirtualNetwork* vpn);
+
+ void EnableControls();
+
+ // Update state of the Login button.
+ void UpdateCanLogin();
+
+ // Update the error text label.
+ void UpdateErrorLabel();
+
+ // Get text from input field.
+ const std::string GetTextFromField(views::Textfield* textfield,
+ bool trim_whitespace) const;
+
+ // Convenience methods to get text from input field or cached VirtualNetwork.
+ const std::string GetService() const;
+ const std::string GetServer() const;
+ const std::string GetPSKPassphrase() const;
+ const std::string GetUsername() const;
+ const std::string GetUserPassphrase() const;
+
+ std::string server_hostname_;
+ string16 service_name_from_server_;
+ bool service_text_modified_;
+ VirtualNetwork::ProviderType provider_type_;
+
+ views::Label* service_text_;
+ views::Textfield* service_textfield_;
+ views::Label* server_text_;
+ views::Textfield* server_textfield_;
+ views::Combobox* provider_type_combobox_;
+ views::Label* provider_type_text_label_;
+ views::Label* psk_passphrase_label_;
+ views::Textfield* psk_passphrase_textfield_;
+ views::Label* user_cert_label_;
+ views::Combobox* user_cert_combobox_;
+ views::Textfield* username_textfield_;
+ views::Textfield* user_passphrase_textfield_;
+ views::Label* error_label_;
+
+ DISALLOW_COPY_AND_ASSIGN(VPNConfigView);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_OPTIONS_VPN_CONFIG_VIEW_H_
diff --git a/chrome/browser/chromeos/options/wifi_config_view.cc b/chrome/browser/chromeos/options/wifi_config_view.cc
index 70ccaa4..efed960 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.cc
+++ b/chrome/browser/chromeos/options/wifi_config_view.cc
@@ -9,7 +9,6 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/browser/chromeos/options/network_config_view.h"
#include "chrome/browser/chromeos/options/wifi_config_model.h"
#include "chrome/common/chrome_switches.h" // TODO(jamescook): Remove.
#include "grit/chromium_strings.h"
@@ -31,9 +30,6 @@ namespace chromeos {
namespace {
-// The width of the password field.
-const int kPasswordWidth = 150;
-
enum SecurityComboboxIndex {
SECURITY_INDEX_NONE = 0,
SECURITY_INDEX_WEP = 1,
@@ -240,10 +236,9 @@ class ClientCertComboboxModel : public ui::ComboboxModel {
} // namespace
WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi)
- : parent_(parent),
+ : ChildNetworkConfigView(parent, wifi),
wifi_config_model_(new WifiConfigModel()),
is_8021x_(false),
- service_path_(wifi->service_path()),
ssid_textfield_(NULL),
eap_method_combobox_(NULL),
phase_2_auth_label_(NULL),
@@ -266,7 +261,7 @@ WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi)
}
WifiConfigView::WifiConfigView(NetworkConfigView* parent)
- : parent_(parent),
+ : ChildNetworkConfigView(parent),
wifi_config_model_(new WifiConfigModel()),
is_8021x_(false),
ssid_textfield_(NULL),
@@ -293,6 +288,10 @@ WifiConfigView::WifiConfigView(NetworkConfigView* parent)
WifiConfigView::~WifiConfigView() {
}
+string16 WifiConfigView::GetTitle() {
+ return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS);
+}
+
bool WifiConfigView::CanLogin() {
static const size_t kMinWirelessPasswordLen = 5;
@@ -361,27 +360,25 @@ void WifiConfigView::RefreshEAPFields() {
identity_anonymous_textfield_->SetText(string16());
}
-void WifiConfigView::UpdateErrorLabel(bool failed) {
- static const int kNoError = -1;
- int id = kNoError;
+void WifiConfigView::UpdateErrorLabel() {
+ std::string error_msg;
if (!service_path_.empty()) {
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
const WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
- if (wifi) {
- // Right now, only displaying bad_passphrase and bad_wepkey errors.
- if (wifi->error() == ERROR_BAD_PASSPHRASE)
- id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_PASSPHRASE;
- else if (wifi->error() == ERROR_BAD_WEPKEY)
- id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_WEPKEY;
+ if (wifi && wifi->failed()) {
+ if (wifi->error() == ERROR_BAD_PASSPHRASE) {
+ error_msg = l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_PASSPHRASE);
+ } else if (wifi->error() == ERROR_BAD_WEPKEY) {
+ error_msg = l10n_util::GetStringUTF8(
+ IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_WEPKEY);
+ } else {
+ error_msg = wifi->GetErrorString();
+ }
}
}
- if (id == kNoError && failed) {
- // We don't know what the error was. For now assume bad identity or
- // passphrase. See TODO comment in Login() and crosbug.com/9538.
- id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_CREDENTIALS;
- }
- if (id != kNoError) {
- error_label_->SetText(UTF16ToWide(l10n_util::GetStringUTF16(id)));
+ if (!error_msg.empty()) {
+ error_label_->SetText(UTF8ToWide(error_msg));
error_label_->SetVisible(true);
} else {
error_label_->SetVisible(false);
@@ -452,7 +449,7 @@ bool WifiConfigView::Login() {
break;
}
cros->ConnectToWifiNetwork(
- sec, GetSSID(), GetPassphrase(), std::string(), std::string(), true);
+ sec, GetSSID(), GetPassphrase(), std::string(), std::string());
} else {
WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
if (!wifi) {
@@ -606,7 +603,8 @@ void WifiConfigView::Init(WifiNetwork* wifi) {
views::GridLayout::USE_PREF, 0, 0);
// Textfield
column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
- views::GridLayout::USE_PREF, 0, kPasswordWidth);
+ views::GridLayout::USE_PREF, 0,
+ ChildNetworkConfigView::kPassphraseWidth);
// Password visible button
column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
views::GridLayout::USE_PREF, 0, 0);
@@ -675,8 +673,8 @@ void WifiConfigView::Init(WifiNetwork* wifi) {
IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA)));
layout->AddView(server_ca_cert_label_);
server_ca_cert_combobox_ = new ComboboxWithWidth(
- new ServerCACertComboboxModel(
- wifi_config_model_.get()), kPasswordWidth);
+ new ServerCACertComboboxModel(wifi_config_model_.get()),
+ ChildNetworkConfigView::kPassphraseWidth);
server_ca_cert_label_->SetEnabled(false);
server_ca_cert_combobox_->SetEnabled(false);
server_ca_cert_combobox_->set_listener(this);
@@ -888,7 +886,7 @@ void WifiConfigView::Init(WifiNetwork* wifi) {
layout->AddView(error_label_);
// Set or hide the error text.
- UpdateErrorLabel(false);
+ UpdateErrorLabel();
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/options/wifi_config_view.h b/chrome/browser/chromeos/options/wifi_config_view.h
index b80c0c1..2961879 100644
--- a/chrome/browser/chromeos/options/wifi_config_view.h
+++ b/chrome/browser/chromeos/options/wifi_config_view.h
@@ -12,6 +12,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "chrome/browser/chromeos/cros/network_library.h"
+#include "chrome/browser/chromeos/options/network_config_view.h"
#include "chrome/browser/ui/shell_dialogs.h"
#include "ui/base/models/combobox_model.h"
#include "views/controls/button/button.h"
@@ -29,11 +30,10 @@ class FilePath;
namespace chromeos {
-class NetworkConfigView;
class WifiConfigModel;
// A dialog box for showing a password textfield.
-class WifiConfigView : public views::View,
+class WifiConfigView : public ChildNetworkConfigView,
public views::TextfieldController,
public views::ButtonListener,
public views::Combobox::Listener {
@@ -58,10 +58,12 @@ class WifiConfigView : public views::View,
virtual void ItemChanged(views::Combobox* combo_box,
int prev_index, int new_index);
+ // ChildNetworkConfigView implementation.
+ virtual string16 GetTitle();
+ virtual bool CanLogin();
+
// Login to network. Returns false if the dialog should remain open.
virtual bool Login();
-
- // Cancel the dialog.
virtual void Cancel();
// Get the typed in ssid.
@@ -69,9 +71,6 @@ class WifiConfigView : public views::View,
// Get the typed in passphrase.
std::string GetPassphrase() const;
- // Returns whether or not we can login.
- bool CanLogin();
-
private:
// Initializes UI.
void Init(WifiNetwork* wifi);
@@ -83,17 +82,13 @@ class WifiConfigView : public views::View,
void RefreshEAPFields();
// Updates the error text label.
- void UpdateErrorLabel(bool failed);
-
- NetworkConfigView* parent_;
+ void UpdateErrorLabel();
scoped_ptr<WifiConfigModel> wifi_config_model_;
// Whether or not it is an 802.1x network.
bool is_8021x_;
- std::string service_path_;
-
views::Textfield* ssid_textfield_;
views::Combobox* eap_method_combobox_;
views::Label* phase_2_auth_label_;
diff --git a/chrome/browser/chromeos/status/network_menu.cc b/chrome/browser/chromeos/status/network_menu.cc
index 19ac0a8..cbe473c 100644
--- a/chrome/browser/chromeos/status/network_menu.cc
+++ b/chrome/browser/chromeos/status/network_menu.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "base/logging.h"
+#include "base/command_line.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/choose_mobile_network_dialog.h"
@@ -16,6 +17,7 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/views/window.h"
#include "chrome/common/url_constants.h"
+#include "chrome/common/chrome_switches.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "net/base/escape.h"
@@ -28,69 +30,46 @@
namespace chromeos {
-////////////////////////////////////////////////////////////////////////////////
-// NetworkMenu
+class MainMenuModel : public NetworkMenuModel {
+ public:
+ explicit MainMenuModel(NetworkMenu* owner);
+ virtual ~MainMenuModel() {}
-// static
-const int NetworkMenu::kNumBarsImages = 4;
+ // NetworkMenuModel implementation.
+ virtual void InitMenuItems(bool is_browser_mode,
+ bool should_open_button_options);
-// NOTE: Use an array rather than just calculating a resource number to avoid
-// creating implicit ordering dependencies on the resource values.
-// static
-const int NetworkMenu::kBarsImages[kNumBarsImages] = {
- IDR_STATUSBAR_NETWORK_BARS1,
- IDR_STATUSBAR_NETWORK_BARS2,
- IDR_STATUSBAR_NETWORK_BARS3,
- IDR_STATUSBAR_NETWORK_BARS4,
-};
-// static
-const int NetworkMenu::kBarsImagesBlack[kNumBarsImages] = {
- IDR_STATUSBAR_NETWORK_BARS1_BLACK,
- IDR_STATUSBAR_NETWORK_BARS2_BLACK,
- IDR_STATUSBAR_NETWORK_BARS3_BLACK,
- IDR_STATUSBAR_NETWORK_BARS4_BLACK,
-};
-/*
-// static
-const int NetworkMenu::kBarsImagesLowData[kNumBarsImages] = {
- IDR_STATUSBAR_NETWORK_BARS1_ORANGE,
- IDR_STATUSBAR_NETWORK_BARS2_ORANGE,
- IDR_STATUSBAR_NETWORK_BARS3_ORANGE,
- IDR_STATUSBAR_NETWORK_BARS4_ORANGE,
-};
-// static
-const int NetworkMenu::kBarsImagesVLowData[kNumBarsImages] = {
- IDR_STATUSBAR_NETWORK_BARS1_RED,
- IDR_STATUSBAR_NETWORK_BARS2_RED,
- IDR_STATUSBAR_NETWORK_BARS3_RED,
- IDR_STATUSBAR_NETWORK_BARS4_RED,
+ private:
+ scoped_ptr<NetworkMenuModel> vpn_menu_model_;
+
+ DISALLOW_COPY_AND_ASSIGN(MainMenuModel);
};
-*/
-// static
-const int NetworkMenu::kNumAnimatingImages = 10;
+class VPNMenuModel : public NetworkMenuModel {
+ public:
+ explicit VPNMenuModel(NetworkMenu* owner);
+ virtual ~VPNMenuModel() {}
-// static
-SkBitmap NetworkMenu::kAnimatingImages[kNumAnimatingImages];
+ // NetworkMenuModel implementation.
+ virtual void InitMenuItems(bool is_browser_mode,
+ bool should_open_button_options);
-// static
-SkBitmap NetworkMenu::kAnimatingImagesBlack[kNumAnimatingImages];
+ static SkBitmap IconForDisplay(const Network* network);
-NetworkMenu::NetworkMenu()
- : min_width_(-1) {
- network_menu_.reset(new views::Menu2(this));
-}
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VPNMenuModel);
+};
-NetworkMenu::~NetworkMenu() {
-}
+////////////////////////////////////////////////////////////////////////////////
+// NetworkMenuModel, public methods:
-bool NetworkMenu::ConnectToNetworkAt(int index,
- const std::string& passphrase,
- const std::string& ssid,
- int auto_connect) const {
+bool NetworkMenuModel::ConnectToNetworkAt(int index,
+ const std::string& passphrase,
+ const std::string& ssid,
+ int auto_connect) const {
int flags = menu_items_[index].flags;
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
- const std::string& service_path = menu_items_[index].wireless_path;
+ const std::string& service_path = menu_items_[index].service_path;
if (flags & FLAG_WIFI) {
WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path);
if (wifi) {
@@ -115,6 +94,8 @@ bool NetworkMenu::ConnectToNetworkAt(int index,
} else {
// If we are attempting to connect to a network that no longer exists,
// display a notification.
+ LOG(WARNING) << "Wi-fi network does not exist to connect to: "
+ << service_path;
// TODO(stevenjb): Show notification.
}
} else if (flags & FLAG_CELLULAR) {
@@ -137,43 +118,70 @@ bool NetworkMenu::ConnectToNetworkAt(int index,
} else {
// If we are attempting to connect to a network that no longer exists,
// display a notification.
+ LOG(WARNING) << "Cellular network does not exist to connect to: "
+ << service_path;
+ // TODO(stevenjb): Show notification.
+ }
+ } else if (flags & FLAG_ADD_WIFI) {
+ ShowOther(TYPE_WIFI);
+ } else if (flags & FLAG_ADD_VPN) {
+ ShowOther(TYPE_VPN);
+ } else if (flags & FLAG_VPN) {
+ VirtualNetwork* vpn = cros->FindVirtualNetworkByPath(service_path);
+ if (vpn) {
+ // Connect or reconnect.
+ if (vpn->connecting_or_connected()) {
+ // Show the config settings for the connected network.
+ if (cros->connected_network())
+ ShowTabbedNetworkSettings(cros->connected_network());
+ return true;
+ }
+ // Show the connection UI if info for a field is missing.
+ if (vpn->NeedMoreInfoToConnect()) {
+ ShowNetworkConfigView(new NetworkConfigView(vpn));
+ return true;
+ }
+ cros->ConnectToVirtualNetwork(vpn);
+ // Connection failures are responsible for updating the UI, including
+ // reopening dialogs.
+ return true;
+ } else {
+ // If we are attempting to connect to a network that no longer exists,
+ // display a notification.
+ LOG(WARNING) << "VPN does not exist to connect to: " << service_path;
// TODO(stevenjb): Show notification.
}
- } else if (flags & FLAG_OTHER_WIFI_NETWORK) {
- ShowOtherWifi();
- } else if (flags & FLAG_OTHER_CELLULAR_NETWORK) {
- ShowOtherCellular();
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
-// NetworkMenu, ui::MenuModel implementation:
+// NetworkMenuModel, ui::MenuModel implementation:
-int NetworkMenu::GetItemCount() const {
+int NetworkMenuModel::GetItemCount() const {
return static_cast<int>(menu_items_.size());
}
-ui::MenuModel::ItemType NetworkMenu::GetTypeAt(int index) const {
+ui::MenuModel::ItemType NetworkMenuModel::GetTypeAt(int index) const {
return menu_items_[index].type;
}
-string16 NetworkMenu::GetLabelAt(int index) const {
+string16 NetworkMenuModel::GetLabelAt(int index) const {
return menu_items_[index].label;
}
-const gfx::Font* NetworkMenu::GetLabelFontAt(int index) const {
+const gfx::Font* NetworkMenuModel::GetLabelFontAt(int index) const {
return (menu_items_[index].flags & FLAG_ASSOCIATED) ?
&ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) :
NULL;
}
-bool NetworkMenu::IsItemCheckedAt(int index) const {
+bool NetworkMenuModel::IsItemCheckedAt(int index) const {
// All ui::MenuModel::TYPE_CHECK menu items are checked.
return true;
}
-bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) {
+bool NetworkMenuModel::GetIconAt(int index, SkBitmap* icon) {
if (!menu_items_[index].icon.empty()) {
*icon = menu_items_[index].icon;
return true;
@@ -181,19 +189,23 @@ bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) {
return false;
}
-bool NetworkMenu::IsEnabledAt(int index) const {
+bool NetworkMenuModel::IsEnabledAt(int index) const {
return !(menu_items_[index].flags & FLAG_DISABLED);
}
-void NetworkMenu::ActivatedAt(int index) {
+ui::MenuModel* NetworkMenuModel::GetSubmenuModelAt(int index) const {
+ return menu_items_[index].sub_menu_model;
+}
+
+void NetworkMenuModel::ActivatedAt(int index) {
// When we are refreshing the menu, ignore menu item activation.
- if (refreshing_menu_)
+ if (owner_->refreshing_menu_)
return;
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
int flags = menu_items_[index].flags;
if (flags & FLAG_OPTIONS) {
- OpenButtonOptions();
+ owner_->OpenButtonOptions();
} else if (flags & FLAG_TOGGLE_ETHERNET) {
cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled());
} else if (flags & FLAG_TOGGLE_WIFI) {
@@ -208,7 +220,7 @@ void NetworkMenu::ActivatedAt(int index) {
cellular->sim_lock_state() == SIM_UNKNOWN) {
cros->EnableCellularNetworkDevice(!cros->cellular_enabled());
} else {
- SimUnlockDialogDelegate::ShowDialog(GetNativeWindow());
+ SimUnlockDialogDelegate::ShowDialog(owner_->GetNativeWindow());
}
}
} else if (flags & FLAG_TOGGLE_OFFLINE) {
@@ -217,251 +229,88 @@ void NetworkMenu::ActivatedAt(int index) {
if (cros->ethernet_connected()) {
ShowTabbedNetworkSettings(cros->ethernet_network());
}
- } else if (flags & FLAG_WIFI) {
- ConnectToNetworkAt(index, std::string(), std::string(), -1);
- } else if (flags & FLAG_OTHER_WIFI_NETWORK) {
- ConnectToNetworkAt(index, std::string(), std::string(), -1);
- } else if (flags & FLAG_CELLULAR) {
- ConnectToNetworkAt(index, std::string(), std::string(), -1);
- } else if (flags & FLAG_OTHER_CELLULAR_NETWORK) {
+ } else if (flags & (FLAG_WIFI | FLAG_ADD_WIFI |
+ FLAG_CELLULAR | FLAG_ADD_CELLULAR |
+ FLAG_VPN | FLAG_ADD_VPN)) {
ConnectToNetworkAt(index, std::string(), std::string(), -1);
+ } else if (flags & FLAG_DISCONNECT_VPN) {
+ const VirtualNetwork* active_vpn = cros->virtual_network();
+ if (active_vpn)
+ cros->DisconnectFromNetwork(active_vpn);
}
}
-void NetworkMenu::SetFirstLevelMenuWidth(int width) {
- min_width_ = width;
- // This actually has no effect since menu is rebuilt before showing.
- network_menu_->SetMinimumWidth(width);
-}
-
-void NetworkMenu::CancelMenu() {
- network_menu_->CancelMenu();
-}
+////////////////////////////////////////////////////////////////////////////////
+// NetworkMenuModel, private methods:
-void NetworkMenu::UpdateMenu() {
- refreshing_menu_ = true;
- InitMenuItems();
- network_menu_->Rebuild();
- refreshing_menu_ = false;
+void NetworkMenuModel::ShowTabbedNetworkSettings(const Network* network) const {
+ DCHECK(network);
+ Browser* browser = BrowserList::GetLastActive();
+ if (!browser)
+ return;
+ std::string page = StringPrintf("%s?servicePath=%s&networkType=%d",
+ chrome::kInternetOptionsSubPage,
+ EscapeUrlEncodedData(network->service_path()).c_str(),
+ network->type());
+ browser->ShowOptionsTab(page);
}
-// static
-const SkBitmap* NetworkMenu::IconForNetworkStrength(const WifiNetwork* wifi,
- bool black) {
- DCHECK(wifi);
- if (wifi->strength() == 0) {
- return ResourceBundle::GetSharedInstance().GetBitmapNamed(
- black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK :
- IDR_STATUSBAR_NETWORK_BARS0);
- }
- int index = static_cast<int>(wifi->strength() / 100.0 *
- nextafter(static_cast<float>(kNumBarsImages), 0));
- index = std::max(std::min(index, kNumBarsImages - 1), 0);
- const int* images = black ? kBarsImagesBlack : kBarsImages;
- return ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]);
+// TODO(stevenjb): deprecate this once we've committed to tabbed settings
+// and the embedded menu UI (and fully deprecated NetworkConfigView).
+// Meanwhile, if MenuUI::IsEnabled() is true, always show the settings UI,
+// otherwise show NetworkConfigView only to get passwords when not connected.
+void NetworkMenuModel::ShowNetworkConfigView(NetworkConfigView* view) const {
+ view->set_browser_mode(owner_->IsBrowserMode());
+ views::Window* window = browser::CreateViewsWindow(
+ owner_->GetNativeWindow(), gfx::Rect(), view);
+ window->SetIsAlwaysOnTop(true);
+ window->Show();
}
-// static
-const SkBitmap* NetworkMenu::IconForNetworkStrength(
- const CellularNetwork* cellular, bool black) {
+void NetworkMenuModel::ActivateCellular(const CellularNetwork* cellular) const {
DCHECK(cellular);
- // If no data, then we show 0 bars.
- if (cellular->strength() == 0 ||
- cellular->data_left() == CellularNetwork::DATA_NONE) {
- return ResourceBundle::GetSharedInstance().GetBitmapNamed(
- black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK :
- IDR_STATUSBAR_NETWORK_BARS0);
- }
- int index = static_cast<int>(cellular->strength() / 100.0 *
- nextafter(static_cast<float>(kNumBarsImages), 0));
- index = std::max(std::min(index, kNumBarsImages - 1), 0);
- const int* images = black ? kBarsImagesBlack : kBarsImages;
- return ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]);
-}
-
-// static
-const SkBitmap* NetworkMenu::IconForNetworkConnecting(double animation_value,
- bool black) {
- // Draw animation of bars icon fading in and out.
- // We are fading between 0 bars and a third of the opacity of 4 bars.
- // Use the current value of the animation to calculate the alpha value
- // of how transparent the icon is.
-
- int index = static_cast<int>(animation_value *
- nextafter(static_cast<float>(kNumAnimatingImages), 0));
- index = std::max(std::min(index, kNumAnimatingImages - 1), 0);
-
- SkBitmap* images = black ? kAnimatingImagesBlack : kAnimatingImages;
- // Lazily cache images.
- if (images[index].empty()) {
- // Divide index (0-9) by 9 (assume kNumAnimatingImages==10) to get (0.0-1.0)
- // Then we take a third of that for the alpha value.
- double alpha = (static_cast<double>(index) / (kNumAnimatingImages - 1)) / 3;
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- images[index] = SkBitmapOperations::CreateBlendedBitmap(
- *rb.GetBitmapNamed(black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK :
- IDR_STATUSBAR_NETWORK_BARS0),
- *rb.GetBitmapNamed(black ? IDR_STATUSBAR_NETWORK_BARS4_BLACK :
- IDR_STATUSBAR_NETWORK_BARS4),
- alpha);
- }
- return &images[index];
-}
-
-// static
-const SkBitmap* NetworkMenu::BadgeForNetworkTechnology(
- const CellularNetwork* cellular) {
- if (!cellular)
- return NULL;
-
- int id = -1;
- switch (cellular->network_technology()) {
- case NETWORK_TECHNOLOGY_EVDO:
- switch (cellular->data_left()) {
- case CellularNetwork::DATA_NONE:
- id = IDR_STATUSBAR_NETWORK_3G_ERROR;
- break;
- case CellularNetwork::DATA_VERY_LOW:
- case CellularNetwork::DATA_LOW:
- case CellularNetwork::DATA_NORMAL:
- id = IDR_STATUSBAR_NETWORK_3G;
- break;
- case CellularNetwork::DATA_UNKNOWN:
- id = IDR_STATUSBAR_NETWORK_3G_UNKNOWN;
- break;
- }
- break;
- case NETWORK_TECHNOLOGY_1XRTT:
- switch (cellular->data_left()) {
- case CellularNetwork::DATA_NONE:
- id = IDR_STATUSBAR_NETWORK_1X_ERROR;
- break;
- case CellularNetwork::DATA_VERY_LOW:
- case CellularNetwork::DATA_LOW:
- case CellularNetwork::DATA_NORMAL:
- id = IDR_STATUSBAR_NETWORK_1X;
- break;
- case CellularNetwork::DATA_UNKNOWN:
- id = IDR_STATUSBAR_NETWORK_1X_UNKNOWN;
- break;
- }
- break;
- // Note: we may not be able to obtain data usage info
- // from GSM carriers, so there may not be a reason
- // to create _ERROR or _UNKNOWN versions of the following
- // icons.
- case NETWORK_TECHNOLOGY_GPRS:
- id = IDR_STATUSBAR_NETWORK_GPRS;
- break;
- case NETWORK_TECHNOLOGY_EDGE:
- id = IDR_STATUSBAR_NETWORK_EDGE;
- break;
- case NETWORK_TECHNOLOGY_UMTS:
- id = IDR_STATUSBAR_NETWORK_3G;
- break;
- case NETWORK_TECHNOLOGY_HSPA:
- id = IDR_STATUSBAR_NETWORK_HSPA;
- break;
- case NETWORK_TECHNOLOGY_HSPA_PLUS:
- id = IDR_STATUSBAR_NETWORK_HSPA_PLUS;
- break;
- case NETWORK_TECHNOLOGY_LTE:
- id = IDR_STATUSBAR_NETWORK_LTE;
- break;
- case NETWORK_TECHNOLOGY_LTE_ADVANCED:
- id = IDR_STATUSBAR_NETWORK_LTE_ADVANCED;
- break;
- case NETWORK_TECHNOLOGY_UNKNOWN:
- break;
- }
- if (id == -1)
- return NULL;
- else
- return ResourceBundle::GetSharedInstance().GetBitmapNamed(id);
-}
-
-// static
-const SkBitmap* NetworkMenu::BadgeForRoamingStatus(
- const CellularNetwork* cellular) {
- // TODO(nkostylev): Return "R" badge, http://crosbug.com/12010.
- if (cellular->roaming_state() == ROAMING_STATE_ROAMING)
- return NULL;
- else
- return NULL;
+ Browser* browser = BrowserList::GetLastActive();
+ if (!browser)
+ return;
+ browser->OpenMobilePlanTabAndActivate();
}
-// static
-SkBitmap NetworkMenu::IconForDisplay(const SkBitmap* icon,
- const SkBitmap* badge) {
- return IconForDisplay(icon, badge, NULL);
+void NetworkMenuModel::ShowOther(ConnectionType type) const {
+ ShowNetworkConfigView(new NetworkConfigView(type));
}
-// static
-SkBitmap NetworkMenu::IconForDisplay(const SkBitmap* icon,
- const SkBitmap* bottom_right_badge,
- const SkBitmap* top_left_badge) {
- DCHECK(icon);
- if (bottom_right_badge == NULL && top_left_badge == NULL)
- return *icon;
-
- static const int kTopLeftBadgeX = 0;
- static const int kTopLeftBadgeY = 0;
- static const int kBottomRightBadgeX = 14;
- static const int kBottomRightBadgeY = 14;
-
- gfx::CanvasSkia canvas(icon->width(), icon->height(), false);
- canvas.DrawBitmapInt(*icon, 0, 0);
- if (bottom_right_badge != NULL)
- canvas.DrawBitmapInt(*bottom_right_badge,
- kBottomRightBadgeX,
- kBottomRightBadgeY);
- if (top_left_badge != NULL)
- canvas.DrawBitmapInt(*top_left_badge, kTopLeftBadgeX, kTopLeftBadgeY);
- return canvas.ExtractBitmap();
+void NetworkMenuModel::ShowOtherCellular() const {
+ ChooseMobileNetworkDialog::ShowDialog(owner_->GetNativeWindow());
}
////////////////////////////////////////////////////////////////////////////////
-// NetworkMenu, views::ViewMenuDelegate implementation:
-
-void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) {
- refreshing_menu_ = true;
- NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
- cros->RequestNetworkScan();
-
- // Build initial menu items. They will be updated when UpdateMenu is
- // called from NetworkChanged.
- InitMenuItems();
- network_menu_->Rebuild();
+// MainMenuModel
- // Restore menu width, if it was set up.
- // NOTE: width isn't checked for correctness here since all width-related
- // logic implemented inside |network_menu_|.
- if (min_width_ != -1)
- network_menu_->SetMinimumWidth(min_width_);
- refreshing_menu_ = false;
- network_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
+MainMenuModel::MainMenuModel(NetworkMenu* owner)
+ : NetworkMenuModel(owner) {
+ vpn_menu_model_.reset(new VPNMenuModel(owner));
}
-void NetworkMenu::InitMenuItems() {
+void MainMenuModel::InitMenuItems(bool is_browser_mode,
+ bool should_open_button_options) {
// This gets called on initialization, so any changes should be reflected
// in CrosMock::SetNetworkLibraryStatusAreaExpectations().
menu_items_.clear();
- // Populate our MenuItems with the current list of wifi networks.
- NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
-
- string16 label;
+ NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
if (cros->IsLocked()) {
- label = l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_LOCKED);
menu_items_.push_back(
MenuItem(ui::MenuModel::TYPE_COMMAND,
- label, SkBitmap(),
- std::string(), FLAG_DISABLED));
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_LOCKED),
+ SkBitmap(), std::string(), FLAG_DISABLED));
return;
}
+ // Populate our MenuItems with the current list of networks.
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ string16 label;
+
// Ethernet
bool ethernet_available = cros->ethernet_available();
bool ethernet_enabled = cros->ethernet_enabled();
@@ -485,7 +334,8 @@ void NetworkMenu::InitMenuItems() {
flag |= FLAG_ASSOCIATED;
menu_items_.push_back(
MenuItem(ui::MenuModel::TYPE_COMMAND, label,
- IconForDisplay(icon, badge), std::string(), flag));
+ NetworkMenu::IconForDisplay(icon, badge), std::string(),
+ flag));
}
// Wifi Networks
@@ -515,20 +365,21 @@ void NetworkMenu::InitMenuItems() {
}
}
- const SkBitmap* icon = IconForNetworkStrength(wifi_networks[i], true);
+ const SkBitmap* icon = NetworkMenu::IconForNetworkStrength(
+ wifi_networks[i], true);
const SkBitmap* badge = wifi_networks[i]->encrypted() ?
rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : NULL;
int flag = FLAG_WIFI;
// If a network is not connectable from login/oobe, we disable it.
// We do not allow configuring a network (e.g. 802.1x) from login/oobe.
- if (!IsBrowserMode() && !wifi_networks[i]->connectable())
+ if (!owner_->IsBrowserMode() && !wifi_networks[i]->connectable())
flag |= FLAG_DISABLED;
if (active_wifi
&& wifi_networks[i]->service_path() == active_wifi->service_path())
flag |= FLAG_ASSOCIATED;
menu_items_.push_back(
MenuItem(ui::MenuModel::TYPE_COMMAND, label,
- IconForDisplay(icon, badge),
+ NetworkMenu::IconForDisplay(icon, badge),
wifi_networks[i]->service_path(), flag));
}
if (!separator_added && !menu_items_.empty())
@@ -537,7 +388,7 @@ void NetworkMenu::InitMenuItems() {
ui::MenuModel::TYPE_COMMAND,
l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_WIFI_NETWORKS),
*rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0_BLACK),
- std::string(), FLAG_OTHER_WIFI_NETWORK));
+ std::string(), FLAG_ADD_WIFI));
}
// Cellular Networks
@@ -558,7 +409,7 @@ void NetworkMenu::InitMenuItems() {
is_gsm = true;
// If we are on the OOBE/login screen, do not show activating 3G option.
- if (!IsBrowserMode() && activation_state != ACTIVATION_STATE_ACTIVATED)
+ if (!is_browser_mode && activation_state != ACTIVATION_STATE_ACTIVATED)
continue;
if (activation_state == ACTIVATION_STATE_NOT_ACTIVATED ||
@@ -588,9 +439,12 @@ void NetworkMenu::InitMenuItems() {
}
}
- const SkBitmap* icon = IconForNetworkStrength(cell_networks[i], true);
- const SkBitmap* badge = BadgeForNetworkTechnology(cell_networks[i]);
- const SkBitmap* roaming_badge = BadgeForRoamingStatus(cell_networks[i]);
+ const SkBitmap* icon = NetworkMenu::IconForNetworkStrength(
+ cell_networks[i], true);
+ const SkBitmap* badge = NetworkMenu::BadgeForNetworkTechnology(
+ cell_networks[i]);
+ const SkBitmap* roaming_badge = NetworkMenu::BadgeForRoamingStatus(
+ cell_networks[i]);
int flag = FLAG_CELLULAR;
bool isActive = active_cellular &&
cell_networks[i]->service_path() == active_cellular->service_path() &&
@@ -599,7 +453,8 @@ void NetworkMenu::InitMenuItems() {
flag |= FLAG_ASSOCIATED;
menu_items_.push_back(
MenuItem(ui::MenuModel::TYPE_COMMAND, label,
- IconForDisplay(icon, badge, roaming_badge),
+ NetworkMenu::IconForDisplay(icon, badge, roaming_badge,
+ NULL),
cell_networks[i]->service_path(), flag));
if (isActive) {
label.clear();
@@ -630,7 +485,7 @@ void NetworkMenu::InitMenuItems() {
l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_OTHER_CELLULAR_NETWORKS),
*rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0_BLACK),
- std::string(), FLAG_OTHER_CELLULAR_NETWORK));
+ std::string(), FLAG_ADD_CELLULAR));
}
}
@@ -642,6 +497,19 @@ void NetworkMenu::InitMenuItems() {
SkBitmap(), std::string(), FLAG_DISABLED));
}
+ if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableVPN)) {
+ // If there's a connected network, add submenu for Private Networks.
+ const Network* connected_network = cros->connected_network();
+ if (connected_network) {
+ menu_items_.push_back(MenuItem()); // Separator
+ menu_items_.push_back(MenuItem(
+ ui::MenuModel::TYPE_SUBMENU,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_PRIVATE_NETWORKS),
+ VPNMenuModel::IconForDisplay(connected_network),
+ vpn_menu_model_.get(), FLAG_PRIVATE_NETWORKS));
+ }
+ }
+
// Enable / disable wireless.
if (wifi_available || cellular_available) {
menu_items_.push_back(MenuItem()); // Separator
@@ -692,7 +560,7 @@ void NetworkMenu::InitMenuItems() {
// SkBitmap(), std::string(), FLAG_TOGGLE_OFFLINE));
bool connected = cros->Connected(); // always call for test expectations.
- bool oobe = !ShouldOpenButtonOptions(); // we don't show options for OOBE.
+ bool oobe = !should_open_button_options; // we don't show options for OOBE.
// Network settings. (And IP Address)
if (!oobe) {
menu_items_.push_back(MenuItem()); // Separator
@@ -706,52 +574,420 @@ void NetworkMenu::InitMenuItems() {
}
}
- label = l10n_util::GetStringUTF16(IsBrowserMode() ?
+ label = l10n_util::GetStringUTF16(is_browser_mode ?
IDS_STATUSBAR_NETWORK_OPEN_OPTIONS_DIALOG :
IDS_STATUSBAR_NETWORK_OPEN_PROXY_SETTINGS_DIALOG);
menu_items_.push_back(MenuItem(ui::MenuModel::TYPE_COMMAND, label,
SkBitmap(), std::string(), FLAG_OPTIONS));
}
+
+ // Recursively call each submenu to populate its own menu items.
+ for (size_t i = 0; i < menu_items_.size(); ++i) {
+ if (menu_items_[i].type == ui::MenuModel::TYPE_SUBMENU &&
+ menu_items_[i].sub_menu_model) {
+ menu_items_[i].sub_menu_model->InitMenuItems(is_browser_mode,
+ should_open_button_options);
+ }
+ }
}
-void NetworkMenu::ShowTabbedNetworkSettings(const Network* network) const {
- DCHECK(network);
- Browser* browser = BrowserList::GetLastActive();
- if (!browser)
+////////////////////////////////////////////////////////////////////////////////
+// VPNMenuModel
+
+VPNMenuModel::VPNMenuModel(NetworkMenu* owner)
+ : NetworkMenuModel(owner) {
+}
+
+void VPNMenuModel::InitMenuItems(bool is_browser_mode,
+ bool should_open_button_options) {
+ // This gets called on initialization, so any changes should be reflected
+ // in CrosMock::SetNetworkLibraryStatusAreaExpectations().
+
+ menu_items_.clear();
+
+ // VPN only applies if there's a connected underlying network.
+ NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+ const Network* connected_network = cros->connected_network();
+ if (!connected_network)
return;
- std::string page = StringPrintf("%s?servicePath=%s&networkType=%d",
- chrome::kInternetOptionsSubPage,
- EscapeUrlEncodedData(network->service_path()).c_str(),
- network->type());
- browser->ShowOptionsTab(page);
+
+ // Populate our MenuItems with the current list of virtual networks.
+ const VirtualNetworkVector& virtual_networks = cros->virtual_networks();
+ const VirtualNetwork* active_vpn = cros->virtual_network();
+ SkBitmap icon = VPNMenuModel::IconForDisplay(connected_network);
+ bool separator_added = false;
+ string16 label;
+
+ for (size_t i = 0; i < virtual_networks.size(); ++i) {
+ const VirtualNetwork* vpn = virtual_networks[i];
+ if (vpn->connecting()) {
+ label = l10n_util::GetStringFUTF16(
+ IDS_STATUSBAR_NETWORK_DEVICE_STATUS,
+ ASCIIToUTF16(vpn->name()),
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING));
+ } else {
+ label = ASCIIToUTF16(vpn->name());
+ }
+
+ // First add a separator if necessary.
+ if (!separator_added) {
+ separator_added = true;
+ if (!menu_items_.empty()) { // Don't add if first menu item.
+ menu_items_.push_back(MenuItem()); // Separator
+ }
+ }
+
+ int flag = FLAG_VPN;
+ if (!vpn->connectable())
+ flag |= FLAG_DISABLED;
+ if (active_vpn && vpn->service_path() == active_vpn->service_path())
+ flag |= FLAG_ASSOCIATED;
+ menu_items_.push_back(
+ MenuItem(ui::MenuModel::TYPE_COMMAND, label, icon, vpn->service_path(),
+ flag));
+ }
+
+ // Add option to add/disconnect from vpn.
+ if (!menu_items_.empty()) { // Add separator if menu is not empty.
+ menu_items_.push_back(MenuItem());
+ }
+ menu_items_.push_back(MenuItem(
+ ui::MenuModel::TYPE_COMMAND,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_ADD_VPN),
+ SkBitmap(), std::string(), FLAG_ADD_VPN));
+ if (active_vpn) {
+ menu_items_.push_back(MenuItem(
+ ui::MenuModel::TYPE_COMMAND,
+ l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DISCONNECT_VPN),
+ SkBitmap(), std::string(), FLAG_DISCONNECT_VPN));
+ }
}
-// TODO(stevenjb): deprecate this once we've committed to tabbed settings
-// and the embedded menu UI (and fully deprecated NetworkConfigView).
-// Meanwhile, if MenuUI::IsEnabled() is true, always show the settings UI,
-// otherwise show NetworkConfigView only to get passwords when not connected.
-void NetworkMenu::ShowNetworkConfigView(NetworkConfigView* view) const {
- view->set_browser_mode(IsBrowserMode());
- views::Window* window = browser::CreateViewsWindow(
- GetNativeWindow(), gfx::Rect(), view);
- window->SetIsAlwaysOnTop(true);
- window->Show();
+// static
+SkBitmap VPNMenuModel::IconForDisplay(const Network* network) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ const SkBitmap* icon = NULL;
+ const SkBitmap* bottom_right_badge = NULL;
+ const SkBitmap* top_left_badge = NULL;
+ // We know for sure |network| is the active network, so no more checking
+ // is needed by BadgeForPrivateNetworkStatus, hence pass in NULL.
+ const SkBitmap* bottom_left_badge =
+ NetworkMenu::BadgeForPrivateNetworkStatus(NULL);
+
+ switch (network->type()) {
+ case TYPE_ETHERNET :
+ icon = rb.GetBitmapNamed(IDR_STATUSBAR_WIRED_BLACK);
+ break;
+ case TYPE_WIFI :
+ icon = NetworkMenu::IconForNetworkStrength(
+ static_cast<const WifiNetwork*>(network), true);
+ break;
+ case TYPE_CELLULAR : {
+ const CellularNetwork* cellular =
+ static_cast<const CellularNetwork*>(network);
+ icon = NetworkMenu::IconForNetworkStrength(cellular, true);
+ bottom_right_badge = NetworkMenu::BadgeForNetworkTechnology(cellular);
+ top_left_badge = NetworkMenu::BadgeForRoamingStatus(cellular);
+ break;
+ }
+ default:
+ LOG(WARNING) << "VPN not handled for connection type " << network->type();
+ return SkBitmap();
+ }
+
+ return NetworkMenu::IconForDisplay(icon, bottom_right_badge, top_left_badge,
+ bottom_left_badge);
}
-void NetworkMenu::ActivateCellular(const CellularNetwork* cellular) const {
+////////////////////////////////////////////////////////////////////////////////
+// NetworkMenu
+
+// static
+const int NetworkMenu::kNumBarsImages = 4;
+
+// NOTE: Use an array rather than just calculating a resource number to avoid
+// creating implicit ordering dependencies on the resource values.
+// static
+const int NetworkMenu::kBarsImages[kNumBarsImages] = {
+ IDR_STATUSBAR_NETWORK_BARS1,
+ IDR_STATUSBAR_NETWORK_BARS2,
+ IDR_STATUSBAR_NETWORK_BARS3,
+ IDR_STATUSBAR_NETWORK_BARS4,
+};
+// static
+const int NetworkMenu::kBarsImagesBlack[kNumBarsImages] = {
+ IDR_STATUSBAR_NETWORK_BARS1_BLACK,
+ IDR_STATUSBAR_NETWORK_BARS2_BLACK,
+ IDR_STATUSBAR_NETWORK_BARS3_BLACK,
+ IDR_STATUSBAR_NETWORK_BARS4_BLACK,
+};
+/*
+// static
+const int NetworkMenu::kBarsImagesLowData[kNumBarsImages] = {
+ IDR_STATUSBAR_NETWORK_BARS1_ORANGE,
+ IDR_STATUSBAR_NETWORK_BARS2_ORANGE,
+ IDR_STATUSBAR_NETWORK_BARS3_ORANGE,
+ IDR_STATUSBAR_NETWORK_BARS4_ORANGE,
+};
+// static
+const int NetworkMenu::kBarsImagesVLowData[kNumBarsImages] = {
+ IDR_STATUSBAR_NETWORK_BARS1_RED,
+ IDR_STATUSBAR_NETWORK_BARS2_RED,
+ IDR_STATUSBAR_NETWORK_BARS3_RED,
+ IDR_STATUSBAR_NETWORK_BARS4_RED,
+};
+*/
+
+// static
+const int NetworkMenu::kNumAnimatingImages = 10;
+
+// static
+SkBitmap NetworkMenu::kAnimatingImages[kNumAnimatingImages];
+
+// static
+SkBitmap NetworkMenu::kAnimatingImagesBlack[kNumAnimatingImages];
+
+NetworkMenu::NetworkMenu()
+ : min_width_(-1) {
+ main_menu_model_.reset(new MainMenuModel(this));
+ network_menu_.reset(new views::Menu2(main_menu_model_.get()));
+}
+
+NetworkMenu::~NetworkMenu() {
+}
+
+void NetworkMenu::SetFirstLevelMenuWidth(int width) {
+ min_width_ = width;
+ // This actually has no effect since menu is rebuilt before showing.
+ network_menu_->SetMinimumWidth(width);
+}
+
+void NetworkMenu::CancelMenu() {
+ network_menu_->CancelMenu();
+}
+
+void NetworkMenu::UpdateMenu() {
+ refreshing_menu_ = true;
+ main_menu_model_->InitMenuItems(IsBrowserMode(), ShouldOpenButtonOptions());
+ network_menu_->Rebuild();
+ refreshing_menu_ = false;
+}
+
+// static
+const SkBitmap* NetworkMenu::IconForNetworkStrength(const WifiNetwork* wifi,
+ bool black) {
+ DCHECK(wifi);
+ if (wifi->strength() == 0) {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK :
+ IDR_STATUSBAR_NETWORK_BARS0);
+ }
+ int index = static_cast<int>(wifi->strength() / 100.0 *
+ nextafter(static_cast<float>(kNumBarsImages), 0));
+ index = std::max(std::min(index, kNumBarsImages - 1), 0);
+ const int* images = black ? kBarsImagesBlack : kBarsImages;
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]);
+}
+
+// static
+const SkBitmap* NetworkMenu::IconForNetworkStrength(
+ const CellularNetwork* cellular, bool black) {
DCHECK(cellular);
- Browser* browser = BrowserList::GetLastActive();
- if (!browser)
- return;
- browser->OpenMobilePlanTabAndActivate();
+ // If no data, then we show 0 bars.
+ if (cellular->strength() == 0 ||
+ cellular->data_left() == CellularNetwork::DATA_NONE) {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK :
+ IDR_STATUSBAR_NETWORK_BARS0);
+ }
+ int index = static_cast<int>(cellular->strength() / 100.0 *
+ nextafter(static_cast<float>(kNumBarsImages), 0));
+ index = std::max(std::min(index, kNumBarsImages - 1), 0);
+ const int* images = black ? kBarsImagesBlack : kBarsImages;
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(images[index]);
}
-void NetworkMenu::ShowOtherWifi() const {
- ShowNetworkConfigView(new NetworkConfigView());
+// static
+const SkBitmap* NetworkMenu::IconForNetworkConnecting(double animation_value,
+ bool black) {
+ // Draw animation of bars icon fading in and out.
+ // We are fading between 0 bars and a third of the opacity of 4 bars.
+ // Use the current value of the animation to calculate the alpha value
+ // of how transparent the icon is.
+ int index = static_cast<int>(animation_value *
+ nextafter(static_cast<float>(kNumAnimatingImages), 0));
+ index = std::max(std::min(index, kNumAnimatingImages - 1), 0);
+
+ SkBitmap* images = black ? kAnimatingImagesBlack : kAnimatingImages;
+ // Lazily cache images.
+ if (images[index].empty()) {
+ // Divide index (0-9) by 9 (assume kNumAnimatingImages==10) to get (0.0-1.0)
+ // Then we take a third of that for the alpha value.
+ double alpha = (static_cast<double>(index) / (kNumAnimatingImages - 1)) / 3;
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ images[index] = SkBitmapOperations::CreateBlendedBitmap(
+ *rb.GetBitmapNamed(black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK :
+ IDR_STATUSBAR_NETWORK_BARS0),
+ *rb.GetBitmapNamed(black ? IDR_STATUSBAR_NETWORK_BARS4_BLACK :
+ IDR_STATUSBAR_NETWORK_BARS4),
+ alpha);
+ }
+ return &images[index];
+}
+
+// static
+const SkBitmap* NetworkMenu::BadgeForNetworkTechnology(
+ const CellularNetwork* cellular) {
+ if (!cellular)
+ return NULL;
+
+ int id = -1;
+ switch (cellular->network_technology()) {
+ case NETWORK_TECHNOLOGY_EVDO:
+ switch (cellular->data_left()) {
+ case CellularNetwork::DATA_NONE:
+ id = IDR_STATUSBAR_NETWORK_3G_ERROR;
+ break;
+ case CellularNetwork::DATA_VERY_LOW:
+ case CellularNetwork::DATA_LOW:
+ case CellularNetwork::DATA_NORMAL:
+ id = IDR_STATUSBAR_NETWORK_3G;
+ break;
+ case CellularNetwork::DATA_UNKNOWN:
+ id = IDR_STATUSBAR_NETWORK_3G_UNKNOWN;
+ break;
+ }
+ break;
+ case NETWORK_TECHNOLOGY_1XRTT:
+ switch (cellular->data_left()) {
+ case CellularNetwork::DATA_NONE:
+ id = IDR_STATUSBAR_NETWORK_1X_ERROR;
+ break;
+ case CellularNetwork::DATA_VERY_LOW:
+ case CellularNetwork::DATA_LOW:
+ case CellularNetwork::DATA_NORMAL:
+ id = IDR_STATUSBAR_NETWORK_1X;
+ break;
+ case CellularNetwork::DATA_UNKNOWN:
+ id = IDR_STATUSBAR_NETWORK_1X_UNKNOWN;
+ break;
+ }
+ break;
+ // Note: we may not be able to obtain data usage info
+ // from GSM carriers, so there may not be a reason
+ // to create _ERROR or _UNKNOWN versions of the following
+ // icons.
+ case NETWORK_TECHNOLOGY_GPRS:
+ id = IDR_STATUSBAR_NETWORK_GPRS;
+ break;
+ case NETWORK_TECHNOLOGY_EDGE:
+ id = IDR_STATUSBAR_NETWORK_EDGE;
+ break;
+ case NETWORK_TECHNOLOGY_UMTS:
+ id = IDR_STATUSBAR_NETWORK_3G;
+ break;
+ case NETWORK_TECHNOLOGY_HSPA:
+ id = IDR_STATUSBAR_NETWORK_HSPA;
+ break;
+ case NETWORK_TECHNOLOGY_HSPA_PLUS:
+ id = IDR_STATUSBAR_NETWORK_HSPA_PLUS;
+ break;
+ case NETWORK_TECHNOLOGY_LTE:
+ id = IDR_STATUSBAR_NETWORK_LTE;
+ break;
+ case NETWORK_TECHNOLOGY_LTE_ADVANCED:
+ id = IDR_STATUSBAR_NETWORK_LTE_ADVANCED;
+ break;
+ case NETWORK_TECHNOLOGY_UNKNOWN:
+ break;
+ }
+ if (id == -1)
+ return NULL;
+ else
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(id);
+}
+
+// static
+const SkBitmap* NetworkMenu::BadgeForRoamingStatus(
+ const CellularNetwork* cellular) {
+ // TODO(nkostylev): Return "R" badge, http://crosbug.com/12010.
+ if (cellular->roaming_state() == ROAMING_STATE_ROAMING)
+ return NULL;
+ else
+ return NULL;
+}
+
+const SkBitmap* NetworkMenu::BadgeForPrivateNetworkStatus(
+ const Network* network) {
+ // If network is not null, check if it's the active network with vpn on it.
+ if (network) {
+ NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+ if (!(cros->virtual_network() && network == cros->connected_network()))
+ return NULL;
+ }
+ // TODO(kuan): yellow lock icon not ready yet; for now, return the black one
+ // used by secure wifi network.
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_STATUSBAR_NETWORK_SECURE);
+}
+
+// static
+SkBitmap NetworkMenu::IconForDisplay(const SkBitmap* icon,
+ const SkBitmap* badge) {
+ return IconForDisplay(icon, badge, NULL, NULL);
+}
+
+// static
+SkBitmap NetworkMenu::IconForDisplay(const SkBitmap* icon,
+ const SkBitmap* bottom_right_badge,
+ const SkBitmap* top_left_badge,
+ const SkBitmap* bottom_left_badge) {
+ DCHECK(icon);
+ if (bottom_right_badge == NULL && top_left_badge == NULL &&
+ bottom_left_badge == NULL)
+ return *icon;
+
+ static const int kTopLeftBadgeX = 0;
+ static const int kTopLeftBadgeY = 0;
+ static const int kBottomRightBadgeX = 14;
+ static const int kBottomRightBadgeY = 14;
+ static const int kBottomLeftBadgeX = 0;
+ static const int kBottomLeftBadgeY = 14;
+
+ gfx::CanvasSkia canvas(icon->width(), icon->height(), false);
+ canvas.DrawBitmapInt(*icon, 0, 0);
+ if (bottom_right_badge != NULL)
+ canvas.DrawBitmapInt(*bottom_right_badge,
+ kBottomRightBadgeX,
+ kBottomRightBadgeY);
+ if (top_left_badge != NULL)
+ canvas.DrawBitmapInt(*top_left_badge, kTopLeftBadgeX, kTopLeftBadgeY);
+ if (bottom_left_badge != NULL)
+ canvas.DrawBitmapInt(*bottom_left_badge, kBottomLeftBadgeX,
+ kBottomLeftBadgeY);
+ return canvas.ExtractBitmap();
}
-void NetworkMenu::ShowOtherCellular() const {
- ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
+////////////////////////////////////////////////////////////////////////////////
+// NetworkMenu, views::ViewMenuDelegate implementation:
+
+void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) {
+ refreshing_menu_ = true;
+ NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
+ cros->RequestNetworkScan();
+
+ // Build initial menu items. They will be updated when UpdateMenu is
+ // called from NetworkChanged.
+ main_menu_model_->InitMenuItems(IsBrowserMode(), ShouldOpenButtonOptions());
+ network_menu_->Rebuild();
+
+ // Restore menu width, if it was set up.
+ // NOTE: width isn't checked for correctness here since all width-related
+ // logic implemented inside |network_menu_|.
+ if (min_width_ != -1)
+ network_menu_->SetMinimumWidth(min_width_);
+ refreshing_menu_ = false;
+ network_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT);
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/status/network_menu.h b/chrome/browser/chromeos/status/network_menu.h
index 13ad95b..05b1b88 100644
--- a/chrome/browser/chromeos/status/network_menu.h
+++ b/chrome/browser/chromeos/status/network_menu.h
@@ -11,7 +11,7 @@
#include "chrome/browser/chromeos/options/network_config_view.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/models/simple_menu_model.h"
+#include "ui/base/models/menu_model.h"
#include "ui/gfx/native_widget_types.h"
#include "views/controls/menu/view_menu_delegate.h"
@@ -25,31 +25,9 @@ class Menu2;
namespace chromeos {
-// Menu for network menu button in the status area/welcome screen.
-// This class will populating the menu with the list of networks.
-// It will also handle connecting to another wifi/cellular network.
-//
-// The network menu looks like this:
-//
-// <icon> Ethernet
-// <icon> Wifi Network A
-// <icon> Wifi Network B
-// <icon> Wifi Network C
-// <icon> Cellular Network A
-// <icon> Cellular Network B
-// <icon> Cellular Network C
-// <icon> Other...
-// --------------------------------
-// Disable Wifi
-// Disable Celluar
-// --------------------------------
-// <IP Address>
-// Network settings...
-//
-// <icon> will show the strength of the wifi/cellular networks.
-// The label will be BOLD if the network is currently connected.
-class NetworkMenu : public views::ViewMenuDelegate,
- public ui::MenuModel {
+class NetworkMenu;
+
+class NetworkMenuModel : public ui::MenuModel {
public:
struct NetworkInfo {
NetworkInfo() :
@@ -72,8 +50,8 @@ class NetworkMenu : public views::ViewMenuDelegate,
bool auto_connect;
};
- NetworkMenu();
- virtual ~NetworkMenu();
+ explicit NetworkMenuModel(NetworkMenu* owner) : owner_(owner) {}
+ virtual ~NetworkMenuModel() {}
// Connect or reconnect to the network at |index|.
// If remember >= 0, set the favorite state of the network.
@@ -83,6 +61,10 @@ class NetworkMenu : public views::ViewMenuDelegate,
const std::string& ssid,
int remember) const;
+ // Called by NetworkMenu::RunMenu to initialize list of menu items.
+ virtual void InitMenuItems(bool is_browser_mode,
+ bool should_open_button_options) {}
+
// ui::MenuModel implementation.
virtual bool HasIcons() const { return true; }
virtual int GetItemCount() const;
@@ -100,17 +82,122 @@ class NetworkMenu : public views::ViewMenuDelegate,
return NULL;
}
virtual bool IsEnabledAt(int index) const;
- virtual ui::MenuModel* GetSubmenuModelAt(int index) const { return NULL; }
+ virtual ui::MenuModel* GetSubmenuModelAt(int index) const;
virtual void HighlightChangedTo(int index) {}
virtual void ActivatedAt(int index);
virtual void MenuWillShow() {}
virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) {}
+ protected:
+ enum MenuItemFlags {
+ FLAG_DISABLED = 1 << 0,
+ FLAG_TOGGLE_ETHERNET = 1 << 1,
+ FLAG_TOGGLE_WIFI = 1 << 2,
+ FLAG_TOGGLE_CELLULAR = 1 << 3,
+ FLAG_TOGGLE_OFFLINE = 1 << 4,
+ FLAG_ASSOCIATED = 1 << 5,
+ FLAG_ETHERNET = 1 << 6,
+ FLAG_WIFI = 1 << 7,
+ FLAG_CELLULAR = 1 << 8,
+ FLAG_PRIVATE_NETWORKS = 1 << 9,
+ FLAG_OPTIONS = 1 << 10,
+ FLAG_ADD_WIFI = 1 << 11,
+ FLAG_ADD_CELLULAR = 1 << 12,
+ FLAG_VPN = 1 << 13,
+ FLAG_ADD_VPN = 1 << 14,
+ FLAG_DISCONNECT_VPN = 1 << 15,
+ };
+
+ struct MenuItem {
+ MenuItem()
+ : type(ui::MenuModel::TYPE_SEPARATOR),
+ sub_menu_model(NULL),
+ flags(0) {}
+ MenuItem(ui::MenuModel::ItemType type, string16 label, SkBitmap icon,
+ const std::string& service_path, int flags)
+ : type(type),
+ label(label),
+ icon(icon),
+ service_path(service_path),
+ sub_menu_model(NULL),
+ flags(flags) {}
+ MenuItem(ui::MenuModel::ItemType type, string16 label, SkBitmap icon,
+ NetworkMenuModel* sub_menu_model, int flags)
+ : type(type),
+ label(label),
+ icon(icon),
+ sub_menu_model(sub_menu_model),
+ flags(flags) {}
+
+ ui::MenuModel::ItemType type;
+ string16 label;
+ SkBitmap icon;
+ std::string service_path;
+ NetworkMenuModel* sub_menu_model; // Weak.
+ int flags;
+ };
+ typedef std::vector<MenuItem> MenuItemVector;
+
+ // Our menu items.
+ MenuItemVector menu_items_;
+
+ NetworkMenu* owner_; // Weak pointer to NetworkMenu that owns this MenuModel.
+
+ private:
+ // Shows network details in Web UI options window.
+ void ShowTabbedNetworkSettings(const Network* network) const;
+
+ // Show a NetworkConfigView modal dialog instance.
+ void ShowNetworkConfigView(NetworkConfigView* view) const;
+
+ void ActivateCellular(const CellularNetwork* cellular) const;
+ void ShowOther(ConnectionType type) const;
+ void ShowOtherCellular() const;
+
+ DISALLOW_COPY_AND_ASSIGN(NetworkMenuModel);
+};
+
+// Menu for network menu button in the status area/welcome screen.
+// This class will populating the menu with the list of networks.
+// It will also handle connecting to another wifi/cellular network.
+//
+// The network menu looks like this:
+//
+// <icon> Ethernet
+// <icon> Wifi Network A
+// <icon> Wifi Network B
+// <icon> Wifi Network C
+// <icon> Cellular Network A
+// <icon> Cellular Network B
+// <icon> Cellular Network C
+// <icon> Other...
+// <icon> Private networks ->
+// <icon> Virtual Network A
+// <icon> Virtual Network B
+// ----------------------------------
+// Add private network...
+// Disconnect private network
+// --------------------------------
+// Disable Wifi
+// Disable Celluar
+// --------------------------------
+// <IP Address>
+// Network settings...
+//
+// <icon> will show the strength of the wifi/cellular networks.
+// The label will be BOLD if the network is currently connected.
+class NetworkMenu : public views::ViewMenuDelegate {
+ public:
+ NetworkMenu();
+ virtual ~NetworkMenu();
+
void SetFirstLevelMenuWidth(int width);
// Cancels the active menu.
void CancelMenu();
+ virtual bool IsBrowserMode() const = 0;
+
// The following methods returns pointer to a shared instance of the SkBitmap.
// This shared bitmap is owned by the resource bundle and should not be freed.
@@ -133,6 +220,7 @@ class NetworkMenu : public views::ViewMenuDelegate,
// Expected to never return NULL.
static const SkBitmap* IconForNetworkConnecting(double animation_value,
bool black);
+
// Returns the Badge for a given network technology.
// This returns different colored symbols depending on cellular data left.
// Returns NULL if not badge is needed.
@@ -142,21 +230,29 @@ class NetworkMenu : public views::ViewMenuDelegate,
// This returns "R" badge if network is in roaming state, otherwise
// returns NULL. Badge is supposed to be shown on top right of the icon.
static const SkBitmap* BadgeForRoamingStatus(const CellularNetwork* cellular);
+ // Returns the badge for the given network if it's active with vpn.
+ // If |network| is not null, will check if it's the active network.
+ // If |network| is null or if |network| is the active one, the yellow lock
+ // badge will be returned, otherwise returns null.
+ // Badge is supposed to be shown on in bottom left corner of the icon.
+ static const SkBitmap* BadgeForPrivateNetworkStatus(const Network* network);
+
// This method will convert the |icon| bitmap to the correct size for display.
// |icon| must be non-NULL.
- // If the |badge| icon is not NULL, it will draw that on top of the icon.
+ // If |badge| icon is not NULL, it will be drawn on top of the icon in
+ // the bottom-right corner.
static SkBitmap IconForDisplay(const SkBitmap* icon, const SkBitmap* badge);
-
// This method will convert the |icon| bitmap to the correct size for display.
// |icon| must be non-NULL.
- // If one of the |bottom_right_badge| or |top_left_badge| icons are not NULL,
- // they will be drawn on top of the icon.
+ // If one of the |bottom_right_badge| or |top_left_badge| or
+ // |bottom_left_badge| icons are not NULL, they will be drawn on top of the
+ // icon.
static SkBitmap IconForDisplay(const SkBitmap* icon,
const SkBitmap* bottom_right_badge,
- const SkBitmap* top_left_badge);
+ const SkBitmap* top_left_badge,
+ const SkBitmap* bottom_left_badge);
protected:
- virtual bool IsBrowserMode() const = 0;
virtual gfx::NativeWindow GetNativeWindow() const = 0;
virtual void OpenButtonOptions() = 0;
virtual bool ShouldOpenButtonOptions() const = 0;
@@ -168,58 +264,11 @@ class NetworkMenu : public views::ViewMenuDelegate,
void UpdateMenu();
private:
- enum MenuItemFlags {
- FLAG_DISABLED = 1 << 0,
- FLAG_TOGGLE_ETHERNET = 1 << 1,
- FLAG_TOGGLE_WIFI = 1 << 2,
- FLAG_TOGGLE_CELLULAR = 1 << 3,
- FLAG_TOGGLE_OFFLINE = 1 << 4,
- FLAG_ASSOCIATED = 1 << 5,
- FLAG_ETHERNET = 1 << 6,
- FLAG_WIFI = 1 << 7,
- FLAG_CELLULAR = 1 << 8,
- FLAG_OPTIONS = 1 << 9,
- FLAG_OTHER_WIFI_NETWORK = 1 << 10,
- FLAG_OTHER_CELLULAR_NETWORK = 1 << 11,
- };
-
- struct MenuItem {
- MenuItem()
- : type(ui::MenuModel::TYPE_SEPARATOR),
- flags(0) {}
- MenuItem(ui::MenuModel::ItemType type, string16 label, SkBitmap icon,
- const std::string& wireless_path, int flags)
- : type(type),
- label(label),
- icon(icon),
- wireless_path(wireless_path),
- flags(flags) {}
-
- ui::MenuModel::ItemType type;
- string16 label;
- SkBitmap icon;
- std::string wireless_path;
- int flags;
- };
- typedef std::vector<MenuItem> MenuItemVector;
+ friend class NetworkMenuModel;
// views::ViewMenuDelegate implementation.
virtual void RunMenu(views::View* source, const gfx::Point& pt);
- // Called by RunMenu to initialize our list of menu items.
- void InitMenuItems();
-
- // Shows network details in Web UI options window.
- void ShowTabbedNetworkSettings(const Network* network) const;
-
- // Show a NetworkConfigView modal dialog instance.
- // TODO(stevenjb): deprecate this once all of the UI is embedded in the menu.
- void ShowNetworkConfigView(NetworkConfigView* view) const;
-
- void ActivateCellular(const CellularNetwork* cellular) const;
- void ShowOtherWifi() const;
- void ShowOtherCellular() const;
-
// Set to true if we are currently refreshing the menu.
bool refreshing_menu_;
@@ -239,12 +288,11 @@ class NetworkMenu : public views::ViewMenuDelegate,
static SkBitmap kAnimatingImages[];
static SkBitmap kAnimatingImagesBlack[];
- // Our menu items.
- MenuItemVector menu_items_;
-
// The network menu.
scoped_ptr<views::Menu2> network_menu_;
+ scoped_ptr<NetworkMenuModel> main_menu_model_;
+
// Holds minimum width or -1 if it wasn't set up.
int min_width_;
diff --git a/chrome/browser/chromeos/status/network_menu_button.cc b/chrome/browser/chromeos/status/network_menu_button.cc
index 422b225..c5ddd42 100644
--- a/chrome/browser/chromeos/status/network_menu_button.cc
+++ b/chrome/browser/chromeos/status/network_menu_button.cc
@@ -32,7 +32,8 @@ NetworkMenuButton::NetworkMenuButton(StatusAreaHost* host)
NetworkMenu(),
host_(host),
icon_(NULL),
- badge_(NULL),
+ right_badge_(NULL),
+ left_badge_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(animation_connecting_(this)) {
animation_connecting_.SetThrobDuration(kThrobDuration);
animation_connecting_.SetTweenType(ui::Tween::EASE_IN_OUT);
@@ -116,21 +117,28 @@ void NetworkMenuButton::OnLocaleChanged() {
////////////////////////////////////////////////////////////////////////////////
// NetworkMenuButton, private methods
-void NetworkMenuButton::SetIconAndBadge(const SkBitmap* icon,
- const SkBitmap* badge) {
+void NetworkMenuButton::SetIconAndBadges(const SkBitmap* icon,
+ const SkBitmap* right_badge,
+ const SkBitmap* left_badge) {
icon_ = icon;
- badge_ = badge;
- SetIcon(IconForDisplay(icon_, badge_));
+ right_badge_ = right_badge;
+ left_badge_ = left_badge;
+ SetIcon(IconForDisplay(icon_, right_badge_, NULL /*no top_left_icon*/,
+ left_badge_));
}
void NetworkMenuButton::SetIconOnly(const SkBitmap* icon) {
icon_ = icon;
- SetIcon(IconForDisplay(icon_, badge_));
+ SetIcon(IconForDisplay(icon_, right_badge_, NULL /*no top_left_icon*/,
+ left_badge_));
}
-void NetworkMenuButton::SetBadgeOnly(const SkBitmap* badge) {
- badge_ = badge;
- SetIcon(IconForDisplay(icon_, badge_));
+void NetworkMenuButton::SetBadgesOnly(const SkBitmap* right_badge,
+ const SkBitmap* left_badge) {
+ right_badge_ = right_badge;
+ left_badge_ = left_badge;
+ SetIcon(IconForDisplay(icon_, right_badge_, NULL /*no top_left_icon*/,
+ left_badge_));
}
void NetworkMenuButton::SetNetworkIcon(NetworkLibrary* cros,
@@ -138,8 +146,9 @@ void NetworkMenuButton::SetNetworkIcon(NetworkLibrary* cros,
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
if (!cros || !CrosLibrary::Get()->EnsureLoaded()) {
- SetIconAndBadge(rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0),
- rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_WARNING));
+ SetIconAndBadges(rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0),
+ rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_WARNING),
+ NULL);
SetTooltipText(UTF16ToWide(l10n_util::GetStringUTF16(
IDS_STATUSBAR_NETWORK_NO_NETWORK_TOOLTIP)));
return;
@@ -147,8 +156,9 @@ void NetworkMenuButton::SetNetworkIcon(NetworkLibrary* cros,
if (!cros->Connected() && !cros->Connecting()) {
animation_connecting_.Stop();
- SetIconAndBadge(rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0),
- rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED));
+ SetIconAndBadges(rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0),
+ rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED),
+ NULL);
SetTooltipText(UTF16ToWide(l10n_util::GetStringUTF16(
IDS_STATUSBAR_NETWORK_NO_NETWORK_TOOLTIP)));
return;
@@ -164,10 +174,10 @@ void NetworkMenuButton::SetNetworkIcon(NetworkLibrary* cros,
const WirelessNetwork* wireless = NULL;
if (cros->wifi_connecting()) {
wireless = cros->wifi_network();
- SetBadgeOnly(NULL);
+ SetBadgesOnly(NULL, NULL);
} else { // cellular_connecting
wireless = cros->cellular_network();
- SetBadgeOnly(BadgeForNetworkTechnology(cros->cellular_network()));
+ SetBadgesOnly(BadgeForNetworkTechnology(cros->cellular_network()), NULL);
}
SetTooltipText(UTF16ToWide(l10n_util::GetStringFUTF16(
wireless->configuring() ? IDS_STATUSBAR_NETWORK_CONFIGURING_TOOLTIP
@@ -178,8 +188,13 @@ void NetworkMenuButton::SetNetworkIcon(NetworkLibrary* cros,
animation_connecting_.Stop();
// Only set the icon, if it is an active network that changed.
if (network && network->is_active()) {
+ const SkBitmap* right_badge(NULL);
+ const SkBitmap* left_badge(NULL);
+ if (cros->virtual_network())
+ left_badge = rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE);
if (network->type() == TYPE_ETHERNET) {
- SetIconAndBadge(rb.GetBitmapNamed(IDR_STATUSBAR_WIRED), NULL);
+ SetIconAndBadges(rb.GetBitmapNamed(IDR_STATUSBAR_WIRED),
+ right_badge, left_badge);
SetTooltipText(
UTF16ToWide(l10n_util::GetStringFUTF16(
IDS_STATUSBAR_NETWORK_CONNECTED_TOOLTIP,
@@ -187,15 +202,17 @@ void NetworkMenuButton::SetNetworkIcon(NetworkLibrary* cros,
IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET))));
} else if (network->type() == TYPE_WIFI) {
const WifiNetwork* wifi = static_cast<const WifiNetwork*>(network);
- SetIconAndBadge(IconForNetworkStrength(wifi, false), NULL);
+ SetIconAndBadges(IconForNetworkStrength(wifi, false),
+ right_badge, left_badge);
SetTooltipText(UTF16ToWide(l10n_util::GetStringFUTF16(
IDS_STATUSBAR_NETWORK_CONNECTED_TOOLTIP,
UTF8ToUTF16(wifi->name()))));
} else if (network->type() == TYPE_CELLULAR) {
const CellularNetwork* cellular =
static_cast<const CellularNetwork*>(network);
- SetIconAndBadge(IconForNetworkStrength(cellular, false),
- BadgeForNetworkTechnology(cellular));
+ right_badge = BadgeForNetworkTechnology(cellular);
+ SetIconAndBadges(IconForNetworkStrength(cellular, false),
+ right_badge, left_badge);
SetTooltipText(UTF16ToWide(l10n_util::GetStringFUTF16(
IDS_STATUSBAR_NETWORK_CONNECTED_TOOLTIP,
UTF8ToUTF16(cellular->name()))));
diff --git a/chrome/browser/chromeos/status/network_menu_button.h b/chrome/browser/chromeos/status/network_menu_button.h
index 77c4526..31c1275 100644
--- a/chrome/browser/chromeos/status/network_menu_button.h
+++ b/chrome/browser/chromeos/status/network_menu_button.h
@@ -65,9 +65,11 @@ class NetworkMenuButton : public StatusAreaButton,
// NetworkLibrary::CellularDataPlanObserver implementation.
virtual void OnCellularDataPlanChanged(NetworkLibrary* cros);
- private:
// NetworkMenu implementation:
virtual bool IsBrowserMode() const;
+
+ protected:
+ // NetworkMenu implementation:
virtual gfx::NativeWindow GetNativeWindow() const;
virtual void OpenButtonOptions();
virtual bool ShouldOpenButtonOptions() const;
@@ -75,12 +77,15 @@ class NetworkMenuButton : public StatusAreaButton,
// views::View
virtual void OnLocaleChanged() OVERRIDE;
- // Sets the icon and the badge.
- void SetIconAndBadge(const SkBitmap* icon, const SkBitmap* badge);
+ private:
+ // Sets the icon and the badges (badges are at the bottom of the icon).
+ void SetIconAndBadges(const SkBitmap* icon,
+ const SkBitmap* right_badge,
+ const SkBitmap* left_badge);
// Sets the icon only. Keep the previous badge.
void SetIconOnly(const SkBitmap* icon);
- // Sets the badge only. Keep the previous icon.
- void SetBadgeOnly(const SkBitmap* badge);
+ // Sets the badges only. Keep the previous icon.
+ void SetBadgesOnly(const SkBitmap* right_badge, const SkBitmap* left_badge);
// Set the network icon based on the status of the |network|
void SetNetworkIcon(NetworkLibrary* cros, const Network* network);
@@ -93,8 +98,10 @@ class NetworkMenuButton : public StatusAreaButton,
// The icon showing the network strength.
const SkBitmap* icon_;
- // A badge icon displayed on top of the icon.
- const SkBitmap* badge_;
+ // A badge icon displayed on top of icon, in bottom-right corner.
+ const SkBitmap* right_badge_;
+ // A badge icon displayed on top of icon, in bottom-left corner.
+ const SkBitmap* left_badge_;
// The throb animation that does the wifi connecting animation.
ui::ThrobAnimation animation_connecting_;
diff --git a/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc b/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
index 81c8ee5..16da1e5 100644
--- a/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
@@ -598,7 +598,7 @@ void MobileSetupHandler::StartOTASP() {
network->connected() &&
network->activation_state() == chromeos::ACTIVATION_STATE_ACTIVATED) {
chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- DisconnectFromWirelessNetwork(network);
+ DisconnectFromNetwork(network);
} else {
EvaluateCellularNetwork(network);
}
@@ -624,7 +624,7 @@ void MobileSetupHandler::DisconnectFromNetwork(
DCHECK(network);
LOG(INFO) << "Disconnecting from: " << network->service_path();
chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- DisconnectFromWirelessNetwork(network);
+ DisconnectFromNetwork(network);
// Disconnect will force networks to be reevaluated, so
// we don't want to continue processing on this path anymore.
evaluating_ = false;
@@ -696,7 +696,7 @@ void MobileSetupHandler::ForceReconnect(
// First, disconnect...
LOG(INFO) << "Disconnecting from " << network->service_path();
chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- DisconnectFromWirelessNetwork(network);
+ DisconnectFromNetwork(network);
// Check the network state 3s after we disconnect to make sure.
scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(),
delay);
@@ -760,8 +760,7 @@ void MobileSetupHandler::EvaluateCellularNetwork(
}
default: {
if (network->failed_or_disconnected() ||
- network->connection_state() ==
- chromeos::STATE_ACTIVATION_FAILURE) {
+ network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
new_state = (network->activation_state() ==
chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) ?
PLAN_ACTIVATION_TRYING_OTASP :
@@ -942,7 +941,7 @@ void MobileSetupHandler::EvaluateCellularNetwork(
network->activation_state() == chromeos::ACTIVATION_STATE_ACTIVATING) &&
(network->error() == chromeos::ERROR_UNKNOWN ||
network->error() == chromeos::ERROR_OTASP_FAILED) &&
- network->connection_state() == chromeos::STATE_ACTIVATION_FAILURE) {
+ network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
LOG(WARNING) << "Activation failure detected "
<< network->service_path().c_str();
switch (state_) {
@@ -1224,7 +1223,7 @@ bool MobileSetupHandler::GotActivationError(
const char* error_code = kErrorDefault;
// This is the magic for detection of errors in during activation process.
- if (network->connection_state() == chromeos::STATE_FAILURE &&
+ if (network->state() == chromeos::STATE_FAILURE &&
network->error() == chromeos::ERROR_AAA_FAILED) {
if (network->activation_state() ==
chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
@@ -1238,8 +1237,7 @@ bool MobileSetupHandler::GotActivationError(
}
}
got_error = true;
- } else if (network->connection_state() ==
- chromeos::STATE_ACTIVATION_FAILURE) {
+ } else if (network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
if (network->error() == chromeos::ERROR_NEED_EVDO) {
if (network->activation_state() ==
chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED)
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
index 3be430c..3f8ad78 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
@@ -648,6 +648,14 @@ void InternetOptionsHandler::PopulateDictionaryDetails(
} else {
PopulateCellularDetails(cros, cellular, &dictionary);
}
+ } else if (type == chromeos::TYPE_VPN) {
+ const chromeos::VirtualNetwork* vpn =
+ cros->FindVirtualNetworkByPath(net->service_path());
+ if (!vpn) {
+ LOG(WARNING) << "Cannot find network " << net->service_path();
+ } else {
+ PopulateVPNDetails(vpn, &dictionary);
+ }
}
web_ui_->CallJavascriptFunction(
@@ -724,6 +732,12 @@ void InternetOptionsHandler::PopulateCellularDetails(
SetActivationButtonVisibility(cellular, dictionary);
}
+void InternetOptionsHandler::PopulateVPNDetails(
+ const chromeos::VirtualNetwork* vpn,
+ DictionaryValue* dictionary) {
+ // TODO(altimofeev): implement this.
+}
+
void InternetOptionsHandler::SetActivationButtonVisibility(
const chromeos::CellularNetwork* cellular,
DictionaryValue* dictionary) {
@@ -801,8 +815,7 @@ void InternetOptionsHandler::LoginToOtherCallback(const ListValue* args) {
chromeos::NetworkLibrary* cros =
chromeos::CrosLibrary::Get()->GetNetworkLibrary();
- cros->ConnectToWifiNetwork(sec, ssid, password, std::string(), std::string(),
- true);
+ cros->ConnectToWifiNetwork(sec, ssid, password, std::string(), std::string());
}
void InternetOptionsHandler::CreateModalPopup(views::WindowDelegate* view) {
@@ -843,6 +856,8 @@ void InternetOptionsHandler::ButtonClickCallback(const ListValue* args) {
HandleWifiButtonClick(service_path, command);
} else if (type == chromeos::TYPE_CELLULAR) {
HandleCellularButtonClick(service_path, command);
+ } else if (type == chromeos::TYPE_VPN) {
+ HandleVPNButtonClick(service_path, command);
} else {
NOTREACHED();
}
@@ -862,7 +877,7 @@ void InternetOptionsHandler::HandleWifiButtonClick(
cros->ForgetWifiNetwork(service_path);
} else if (!use_settings_ui_ && service_path == kOtherNetworksFakePath) {
// Other wifi networks.
- CreateModalPopup(new chromeos::NetworkConfigView());
+ CreateModalPopup(new chromeos::NetworkConfigView(chromeos::TYPE_WIFI));
} else if ((wifi = cros->FindWifiNetworkByPath(service_path))) {
if (command == "connect") {
// Connect to wifi here. Open password page if appropriate.
@@ -883,7 +898,7 @@ void InternetOptionsHandler::HandleWifiButtonClick(
cros->ConnectToWifiNetwork(wifi);
}
} else if (command == "disconnect") {
- cros->DisconnectFromWirelessNetwork(wifi);
+ cros->DisconnectFromNetwork(wifi);
} else if (command == "options") {
PopulateDictionaryDetails(wifi, cros);
}
@@ -901,7 +916,7 @@ void InternetOptionsHandler::HandleCellularButtonClick(
if (command == "connect") {
cros->ConnectToCellularNetwork(cellular);
} else if (command == "disconnect") {
- cros->DisconnectFromWirelessNetwork(cellular);
+ cros->DisconnectFromNetwork(cellular);
} else if (command == "activate") {
Browser* browser = BrowserList::GetLastActive();
if (browser)
@@ -912,6 +927,35 @@ void InternetOptionsHandler::HandleCellularButtonClick(
}
}
+void InternetOptionsHandler::HandleVPNButtonClick(
+ const std::string& service_path,
+ const std::string& command) {
+ chromeos::NetworkLibrary* cros =
+ chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+ chromeos::VirtualNetwork* network = NULL;
+ // TODO(altimofeev): verify if service_path in condition is correct.
+ if (!use_settings_ui_ && service_path == kOtherNetworksFakePath) {
+ // Other VPN networks.
+ CreateModalPopup(new chromeos::NetworkConfigView(chromeos::TYPE_VPN));
+ } else if ((network = cros->FindVirtualNetworkByPath(service_path))) {
+ if (command == "connect") {
+ // Connect to VPN here. Open password page if appropriate.
+ if (network->NeedMoreInfoToConnect()) {
+ if (use_settings_ui_) {
+ // TODO(altimofeev): implement this.
+ } else {
+ CreateModalPopup(new chromeos::NetworkConfigView(network));
+ }
+ } else {
+ cros->ConnectToVirtualNetwork(network);
+ }
+ } else if (command == "disconnect") {
+ cros->DisconnectFromNetwork(network);
+ } else if (command == "options") {
+ PopulateDictionaryDetails(network, cros);
+ }
+ }
+}
void InternetOptionsHandler::RefreshCellularPlanCallback(
const ListValue* args) {
std::string service_path;
@@ -1000,13 +1044,16 @@ ListValue* InternetOptionsHandler::GetWiredList() {
const chromeos::EthernetNetwork* ethernet_network =
cros->ethernet_network();
const SkBitmap* icon = rb.GetBitmapNamed(IDR_STATUSBAR_WIRED_BLACK);
- const SkBitmap* badge = !ethernet_network ||
+ const SkBitmap* bottom_right_badge = !ethernet_network ||
(!ethernet_network->connecting() && !ethernet_network->connected()) ?
rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED) : NULL;
+ const SkBitmap* bottom_left_badge =
+ chromeos::NetworkMenu::BadgeForPrivateNetworkStatus(ethernet_network);
if (ethernet_network) {
list->Append(GetNetwork(
ethernet_network->service_path(),
- chromeos::NetworkMenu::IconForDisplay(icon, badge),
+ chromeos::NetworkMenu::IconForDisplay(icon, bottom_right_badge, NULL,
+ bottom_left_badge),
l10n_util::GetStringUTF8(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET),
ethernet_network->connecting(),
ethernet_network->connected(),
@@ -1026,16 +1073,24 @@ ListValue* InternetOptionsHandler::GetWirelessList() {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
ListValue* list = new ListValue();
+ const chromeos::Network* active_network = cros->active_network();
+ bool has_vpn = active_network && cros->virtual_network();
+ bool vpn_on_wireless = has_vpn &&
+ active_network->type() == chromeos::TYPE_WIFI;
const chromeos::WifiNetworkVector& wifi_networks = cros->wifi_networks();
for (chromeos::WifiNetworkVector::const_iterator it =
wifi_networks.begin(); it != wifi_networks.end(); ++it) {
const SkBitmap* icon =
chromeos::NetworkMenu::IconForNetworkStrength(*it, true);
- const SkBitmap* badge = (*it)->encrypted() ?
+ const SkBitmap* bottom_right_badge = (*it)->encrypted() ?
rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : NULL;
+ const SkBitmap* bottom_left_badge =
+ vpn_on_wireless && active_network == (*it) ?
+ chromeos::NetworkMenu::BadgeForPrivateNetworkStatus(NULL) : NULL;
list->Append(GetNetwork(
(*it)->service_path(),
- chromeos::NetworkMenu::IconForDisplay(icon, badge),
+ chromeos::NetworkMenu::IconForDisplay(icon, bottom_right_badge, NULL,
+ bottom_left_badge),
(*it)->name(),
(*it)->connecting(),
(*it)->connected(),
@@ -1061,19 +1116,25 @@ ListValue* InternetOptionsHandler::GetWirelessList() {
false));
}
+ bool vpn_on_cellular = has_vpn &&
+ active_network->type() == chromeos::TYPE_CELLULAR;
const chromeos::CellularNetworkVector cellular_networks =
cros->cellular_networks();
for (chromeos::CellularNetworkVector::const_iterator it =
cellular_networks.begin(); it != cellular_networks.end(); ++it) {
const SkBitmap* icon =
chromeos::NetworkMenu::IconForNetworkStrength(*it, true);
- const SkBitmap* badge =
+ const SkBitmap* bottom_right_badge =
chromeos::NetworkMenu::BadgeForNetworkTechnology(*it);
const SkBitmap* roaming_badge =
chromeos::NetworkMenu::BadgeForRoamingStatus(*it);
+ const SkBitmap* bottom_left_badge =
+ vpn_on_cellular && active_network == (*it) ?
+ chromeos::NetworkMenu::BadgeForPrivateNetworkStatus(NULL) : NULL;
list->Append(GetNetwork(
(*it)->service_path(),
- chromeos::NetworkMenu::IconForDisplay(icon, badge, roaming_badge),
+ chromeos::NetworkMenu::IconForDisplay(icon, bottom_right_badge,
+ roaming_badge, bottom_left_badge),
(*it)->name(),
(*it)->connecting(),
(*it)->connected(),
@@ -1101,6 +1162,9 @@ ListValue* InternetOptionsHandler::GetRememberedList() {
cros->remembered_wifi_networks();
const chromeos::WifiNetworkVector& wifi_networks =
cros->wifi_networks();
+ const chromeos::Network* active_network = cros->active_network();
+ bool vpn_on_wireless = active_network && cros->virtual_network() &&
+ active_network->type() == chromeos::TYPE_WIFI;
// The remembered networks from libcros/flimflam don't include the signal
// strength, so fall back to the detected networks for this data. We
@@ -1130,11 +1194,15 @@ ListValue* InternetOptionsHandler::GetRememberedList() {
// Place the secure badge on the icon if the remembered network is
// encrypted (the matching detected network, if any, will have the same
// encrypted property by definition).
- const SkBitmap* badge = wifi->encrypted() ?
+ const SkBitmap* bottom_right_badge = wifi->encrypted() ?
rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE) : NULL;
+ const SkBitmap* bottom_left_badge =
+ vpn_on_wireless && active_network == wifi ?
+ chromeos::NetworkMenu::BadgeForPrivateNetworkStatus(NULL) : NULL;
list->Append(GetNetwork(
wifi->service_path(),
- chromeos::NetworkMenu::IconForDisplay(icon, badge),
+ chromeos::NetworkMenu::IconForDisplay(icon, bottom_right_badge, NULL,
+ bottom_left_badge),
wifi->name(),
wifi->connecting(),
wifi->connected(),
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
index dcaf218..a4bdb56 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.h
@@ -63,6 +63,8 @@ class InternetOptionsHandler
const std::string& command);
void HandleCellularButtonClick(const std::string& service_path,
const std::string& command);
+ void HandleVPNButtonClick(const std::string& service_path,
+ const std::string& command);
// Initiates cellular plan data refresh. The results from libcros will be
// passed through CellularDataPlanChanged() callback method.
@@ -94,6 +96,8 @@ class InternetOptionsHandler
void PopulateCellularDetails(chromeos::NetworkLibrary* cros,
const chromeos::CellularNetwork* cellular,
DictionaryValue* dictionary);
+ void PopulateVPNDetails(const chromeos::VirtualNetwork* vpn,
+ DictionaryValue* dictionary);
// Converts CellularDataPlan structure into dictionary for JS. Formats plan
// settings into human readable texts.
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 072ae9d..c2312ae 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -638,6 +638,8 @@
'browser/chromeos/options/wifi_config_model.h',
'browser/chromeos/options/wifi_config_view.cc',
'browser/chromeos/options/wifi_config_view.h',
+ 'browser/chromeos/options/vpn_config_view.cc',
+ 'browser/chromeos/options/vpn_config_view.h',
'browser/chromeos/panels/panel_scroller.cc',
'browser/chromeos/panels/panel_scroller.h',
'browser/chromeos/panels/panel_scroller_container.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 83e9322..59604c6 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -1091,6 +1091,9 @@ const char kEnableDevicePolicy[] = "enable-device-policy";
// client-side certificates.
const char kEnableExperimentalEap[] = "enable-experimental-eap";
+// Enables VPN support on ChromeOS.
+const char kEnableVPN[] = "enable-vpn";
+
// Enable the redirection of viewable document requests to the Google
// Document Viewer.
const char kEnableGView[] = "enable-gview";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 248f0b8..aa51a62 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -302,6 +302,7 @@ extern const char kWinHttpProxyResolver[];
extern const char kDOMLogin[];
extern const char kEnableDevicePolicy[];
extern const char kEnableExperimentalEap[];
+extern const char kEnableVPN[];
extern const char kEnableGView[];
extern const char kEnableLoginImages[];
extern const char kLoginManager[];