summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-22 06:17:42 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-22 06:17:42 +0000
commit3c1139fc18193fa1726648c791d07a5a683802c3 (patch)
tree5ba30aeb165b0a35cfaec9164e15bc3e4bf123f4
parent0e46a85ea170a50c078a85691d8b70dff8e0ccad (diff)
downloadchromium_src-3c1139fc18193fa1726648c791d07a5a683802c3.zip
chromium_src-3c1139fc18193fa1726648c791d07a5a683802c3.tar.gz
chromium_src-3c1139fc18193fa1726648c791d07a5a683802c3.tar.bz2
Wired cellular data plan activation logic with the rest of the DOM UI on both chrome:settings/internet and chrome:mobilesetup pages.
Fixed some minor internet settings formatting issues while I was already there. BUG=chromium-os:6987, chromium-os:7619, chromium-os:7546 TEST=make sure cellular connection can be activated from chrome:settings Review URL: http://codereview.chromium.org/3744013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63488 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/chromeos/cros/mock_network_library.h2
-rw-r--r--chrome/browser/chromeos/cros/network_library.cc139
-rw-r--r--chrome/browser/chromeos/cros/network_library.h23
-rw-r--r--chrome/browser/chromeos/dom_ui/internet_options_handler.cc53
-rw-r--r--chrome/browser/chromeos/dom_ui/internet_options_handler.h3
-rw-r--r--chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc413
-rw-r--r--chrome/browser/resources/mobile_setup.html83
-rw-r--r--chrome/browser/resources/mobile_setup.js121
-rw-r--r--chrome/browser/resources/options/chromeos_internet_detail.html2
-rw-r--r--chrome/browser/resources/options/chromeos_internet_network_element.js69
-rw-r--r--chrome/browser/resources/options/chromeos_internet_options_page.css12
-rw-r--r--chrome/browser/resources/options/options_page.css8
-rw-r--r--chrome/browser/resources/options/subpages_tab_controls.css1
14 files changed, 665 insertions, 267 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 4e59d07..6632245 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -9071,6 +9071,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_OPTIONS_SETTINGS_FORGET" desc="In the settings tab, the text on the button to forget this network.">
Forget this network
</message>
+ <message name="IDS_OPTIONS_SETTINGS_ACTIVATE" desc="In the settings tab, the text on the button to activate a cellular network.">
+ Activate
+ </message>
<message name="IDS_OPTIONS_SETTINGS_OPTIONS" desc="In the settings tab, the text on the button to display more options.">
Options...
</message>
diff --git a/chrome/browser/chromeos/cros/mock_network_library.h b/chrome/browser/chromeos/cros/mock_network_library.h
index 1e43e35..603828f 100644
--- a/chrome/browser/chromeos/cros/mock_network_library.h
+++ b/chrome/browser/chromeos/cros/mock_network_library.h
@@ -19,6 +19,8 @@ class MockNetworkLibrary : public NetworkLibrary {
virtual ~MockNetworkLibrary() {}
MOCK_METHOD1(AddObserver, void(Observer*));
MOCK_METHOD1(RemoveObserver, void(Observer*));
+ MOCK_METHOD2(AddProperyObserver, void(const char*, PropertyObserver*));
+ MOCK_METHOD1(RemoveProperyObserver, void(PropertyObserver*));
MOCK_CONST_METHOD0(ethernet_network, const EthernetNetwork&(void));
MOCK_CONST_METHOD0(ethernet_connecting, bool(void));
MOCK_CONST_METHOD0(ethernet_connected, bool(void));
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc
index 896f35c..73751b3 100644
--- a/chrome/browser/chromeos/cros/network_library.cc
+++ b/chrome/browser/chromeos/cros/network_library.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/cros/network_library.h"
#include <algorithm>
+#include <map>
#include "app/l10n_util.h"
#include "base/string_number_conversions.h"
@@ -342,8 +343,9 @@ std::string CellularNetwork::GetNetworkTechnologyString() const {
}
}
-std::string CellularNetwork::GetActivationStateString() const {
- switch (this->activation_state_) {
+std::string CellularNetwork::ActivationStateToString(
+ ActivationState activation_state) {
+ switch (activation_state) {
case ACTIVATION_STATE_ACTIVATED:
return l10n_util::GetStringUTF8(
IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED);
@@ -367,6 +369,10 @@ std::string CellularNetwork::GetActivationStateString() const {
}
}
+std::string CellularNetwork::GetActivationStateString() const {
+ return ActivationStateToString(this->activation_state_);
+}
+
std::string CellularNetwork::GetRoamingStateString() const {
switch (this->roaming_state_) {
case ROAMING_STATE_HOME:
@@ -477,6 +483,13 @@ class NetworkLibraryImpl : public NetworkLibrary {
if (data_plan_monitor_) {
DisconnectDataPlanUpdateMonitor(data_plan_monitor_);
}
+ // DCHECK(!observers_.size());
+ DCHECK(!property_observers_.size());
+ for (PropertyChangeObserverMap::iterator iter = property_observers_.begin();
+ iter != property_observers_.end();
+ ++iter) {
+ delete iter->second;
+ }
}
void AddObserver(Observer* observer) {
@@ -487,6 +500,40 @@ class NetworkLibraryImpl : public NetworkLibrary {
observers_.RemoveObserver(observer);
}
+ virtual void AddProperyObserver(const char* service_path,
+ PropertyObserver* observer) {
+ DCHECK(service_path);
+ DCHECK(observer);
+ // First, add the observer to the callback map.
+ PropertyChangeObserverMap::iterator iter = property_observers_.find(
+ std::string(service_path));
+ if (iter != property_observers_.end()) {
+ iter->second->AddObserver(observer);
+ } else {
+ std::pair<PropertyChangeObserverMap::iterator, bool> inserted =
+ property_observers_.insert(
+ std::pair<std::string, PropertyObserverList*>(
+ std::string(service_path),
+ new PropertyObserverList(this, service_path)));
+ inserted.first->second->AddObserver(observer);
+ }
+ }
+
+ virtual void RemoveProperyObserver(PropertyObserver* observer) {
+ DCHECK(observer);
+ PropertyChangeObserverMap::iterator map_iter =
+ property_observers_.begin();
+ while (map_iter != property_observers_.end()) {
+ map_iter->second->RemoveObserver(observer);
+ if (!map_iter->second->size()) {
+ delete map_iter->second;
+ property_observers_.erase(map_iter++);
+ } else {
+ ++map_iter;
+ }
+ }
+ }
+
virtual const EthernetNetwork& ethernet_network() const { return ethernet_; }
virtual bool ethernet_connecting() const { return ethernet_.connecting(); }
virtual bool ethernet_connected() const { return ethernet_.connected(); }
@@ -872,6 +919,37 @@ class NetworkLibraryImpl : public NetworkLibrary {
}
private:
+
+ class PropertyObserverList : public ObserverList<PropertyObserver> {
+ public:
+ PropertyObserverList(NetworkLibraryImpl* library,
+ const char* service_path) {
+ DCHECK(service_path);
+ property_change_monitor_ = MonitorNetworkService(&PropertyChangeHandler,
+ service_path,
+ library);
+ }
+
+ virtual ~PropertyObserverList() {
+ if (property_change_monitor_)
+ DisconnectPropertyChangeMonitor(property_change_monitor_);
+ }
+
+ private:
+ static void PropertyChangeHandler(void* object,
+ const char* path,
+ const char* key,
+ const Value* value) {
+ NetworkLibraryImpl* network = static_cast<NetworkLibraryImpl*>(object);
+ DCHECK(network);
+ network->NotifyPropertyChange(path, key, value);
+ }
+ PropertyChangeMonitor property_change_monitor_;
+ };
+
+ typedef std::map<std::string, PropertyObserverList*>
+ PropertyChangeObserverMap;
+
static void NetworkStatusChangedHandler(void* object) {
NetworkLibraryImpl* network = static_cast<NetworkLibraryImpl*>(object);
DCHECK(network);
@@ -994,35 +1072,21 @@ class NetworkLibraryImpl : public NetworkLibrary {
cellular_networks_.clear();
- cellular_networks_.clear();
CellularNetwork cellular1 = CellularNetwork();
cellular1.set_service_path("fc1");
cellular1.set_name("Fake Cellular 1");
- cellular1.set_strength(90);
- cellular1.set_connected(false);
+ cellular1.set_strength(70);
+ cellular1.set_connected(true);
+ cellular1.set_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED);
+ cellular1.set_payment_url(std::string("http://www.google.com"));
cellular_networks_.push_back(cellular1);
-
- CellularNetwork cellular2 = CellularNetwork();
- cellular2.set_service_path("fc2");
- cellular2.set_name("Fake Cellular 2");
- cellular2.set_strength(70);
- cellular2.set_connected(true);
- cellular_networks_.push_back(cellular2);
-
- CellularNetwork cellular3 = CellularNetwork();
- cellular3.set_service_path("fc3");
- cellular3.set_name("Fake Cellular 3");
- cellular3.set_strength(50);
- cellular3.set_connected(false);
- cellular_networks_.push_back(cellular3);
-
- cellular_ = cellular2;
+ cellular_ = cellular1;
remembered_wifi_networks_.clear();
remembered_wifi_networks_.push_back(wifi2);
remembered_cellular_networks_.clear();
- remembered_cellular_networks_.push_back(cellular2);
+ remembered_cellular_networks_.push_back(cellular1);
int devices = (1 << TYPE_ETHERNET) | (1 << TYPE_WIFI) |
(1 << TYPE_CELLULAR);
@@ -1108,6 +1172,24 @@ class NetworkLibraryImpl : public NetworkLibrary {
FOR_EACH_OBSERVER(Observer, observers_, CellularDataPlanChanged(this));
}
+ void NotifyPropertyChange(const char* service_path,
+ const char* key,
+ const Value* value) {
+ DCHECK(service_path);
+ DCHECK(key);
+ DCHECK(value);
+ PropertyChangeObserverMap::const_iterator iter = property_observers_.find(
+ std::string(service_path));
+ if (iter != property_observers_.end()) {
+ FOR_EACH_OBSERVER(PropertyObserver, *(iter->second),
+ PropertyChanged(service_path, key, value));
+ } else {
+ NOTREACHED() <<
+ "There weren't supposed to be any property change observers of " <<
+ service_path;
+ }
+ }
+
void UpdateNetworkStatus() {
// Make sure we run on UI thread.
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
@@ -1167,12 +1249,18 @@ class NetworkLibraryImpl : public NetworkLibrary {
ObserverList<Observer> observers_;
+ // Property change observer map
+ PropertyChangeObserverMap property_observers_;
+
// The network status connection for monitoring network status changes.
MonitorNetworkConnection network_status_connection_;
// For monitoring data plan changes to the connected cellular network.
DataPlanUpdateMonitor data_plan_monitor_;
+ // The property change connection for monitoring service property changes.
+ std::map<std::string, PropertyChangeMonitor> property_change_monitors_;
+
// The ethernet network.
EthernetNetwork ethernet_;
@@ -1212,8 +1300,11 @@ class NetworkLibraryStubImpl : public NetworkLibrary {
public:
NetworkLibraryStubImpl() : ip_address_("1.1.1.1") {}
~NetworkLibraryStubImpl() {}
- void AddObserver(Observer* observer) {}
- void RemoveObserver(Observer* observer) {}
+ virtual void AddObserver(Observer* observer) {}
+ virtual void RemoveObserver(Observer* observer) {}
+ virtual void AddProperyObserver(const char* service_path,
+ PropertyObserver* observer) {}
+ virtual void RemoveProperyObserver(PropertyObserver* observer) {}
virtual const EthernetNetwork& ethernet_network() const {
return ethernet_;
}
diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h
index 5426da1..13711c0 100644
--- a/chrome/browser/chromeos/cros/network_library.h
+++ b/chrome/browser/chromeos/cros/network_library.h
@@ -15,6 +15,8 @@
#include "base/timer.h"
#include "cros/chromeos_network.h"
+class Value;
+
namespace chromeos {
// Cellular network is considered low data when less than 60 minues.
@@ -41,6 +43,8 @@ class Network {
bool connected() const { return state_ == STATE_READY; }
bool connecting_or_connected() const { return connecting() || connected(); }
bool failed() const { return state_ == STATE_FAILURE; }
+ bool failed_or_disconnected() const { return failed() ||
+ state_ == STATE_IDLE; }
ConnectionError error() const { return error_; }
ConnectionState state() const { return state_; }
@@ -146,6 +150,9 @@ class CellularNetwork : public WirelessNetwork {
// Starts device activation process. Returns false if the device state does
// not permit activation.
bool StartActivation() const;
+ void set_activation_state(ActivationState state) {
+ activation_state_ = state;
+ }
const ActivationState activation_state() const { return activation_state_; }
const NetworkTechnology network_technology() const {
return network_technology_;
@@ -156,6 +163,9 @@ class CellularNetwork : public WirelessNetwork {
const std::string& operator_name() const { return operator_name_; }
const std::string& operator_code() const { return operator_code_; }
const std::string& payment_url() const { return payment_url_; }
+ void set_payment_url(const std::string& url) {
+ payment_url_ = url;
+ }
const std::string& meid() const { return meid_; }
const std::string& imei() const { return imei_; }
const std::string& imsi() const { return imsi_; }
@@ -189,6 +199,9 @@ class CellularNetwork : public WirelessNetwork {
// Return a string representation of roaming state.
std::string GetRoamingStateString() const;
+ // Return a string representation of |activation_state|.
+ static std::string ActivationStateToString(ActivationState activation_state);
+
protected:
ActivationState activation_state_;
NetworkTechnology network_technology_;
@@ -326,9 +339,19 @@ class NetworkLibrary {
virtual void CellularDataPlanChanged(NetworkLibrary* obj) {}
};
+ class PropertyObserver {
+ public:
+ virtual void PropertyChanged(const char* service_path,
+ const char* key,
+ const Value* value) = 0;
+ };
+
virtual ~NetworkLibrary() {}
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
+ virtual void AddProperyObserver(const char* service_path,
+ PropertyObserver* observer) = 0;
+ virtual void RemoveProperyObserver(PropertyObserver* observer) = 0;
// Return the active Ethernet network (or a default structure if inactive).
virtual const EthernetNetwork& ethernet_network() const = 0;
diff --git a/chrome/browser/chromeos/dom_ui/internet_options_handler.cc b/chrome/browser/chromeos/dom_ui/internet_options_handler.cc
index 87db039..90b80e0 100644
--- a/chrome/browser/chromeos/dom_ui/internet_options_handler.cc
+++ b/chrome/browser/chromeos/dom_ui/internet_options_handler.cc
@@ -92,6 +92,9 @@ void InternetOptionsHandler::GetLocalizedValues(
localized_strings->SetString("forget_button",
l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_FORGET));
+ localized_strings->SetString("activate_button",
+ l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_ACTIVATE));
localized_strings->SetString("wifiNetworkTabLabel",
l10n_util::GetStringUTF16(
@@ -324,7 +327,10 @@ void InternetOptionsHandler::DisableCellularCallback(const ListValue* args) {
}
void InternetOptionsHandler::BuyDataPlanCallback(const ListValue* args) {
- Browser* browser = BrowserList::GetLastActive();
+ if (!dom_ui_)
+ return;
+ Browser* browser = BrowserList::FindBrowserWithFeature(
+ dom_ui_->GetProfile(), Browser::FEATURE_TABSTRIP);
if (browser)
browser->OpenMobilePlanTabAndActivate();
}
@@ -787,6 +793,10 @@ void InternetOptionsHandler::ButtonClickCallback(const ListValue* args) {
cros->ConnectToCellularNetwork(cellular);
} else if (command == "disconnect") {
cros->DisconnectFromWirelessNetwork(cellular);
+ } else if (command == "activate") {
+ Browser* browser = BrowserList::GetLastActive();
+ if (browser)
+ browser->OpenMobilePlanTabAndActivate();
} else if (command == "options") {
PopulateDictionaryDetails(cellular, cros);
}
@@ -816,17 +826,23 @@ void InternetOptionsHandler::RefreshCellularPlanCallback(
ListValue* InternetOptionsHandler::GetNetwork(const std::string& service_path,
const SkBitmap& icon, const std::string& name, bool connecting,
- bool connected, int connection_type, bool remembered) {
+ bool connected, chromeos::ConnectionType connection_type, bool remembered,
+ chromeos::ActivationState activation_state) {
ListValue* network = new ListValue();
- int s = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED;
+ int connection_state = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED;
if (connecting)
- s = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING;
+ connection_state = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING;
else if (connected)
- s = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED;
- string16 status = l10n_util::GetStringUTF16(s);
-
+ connection_state = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED;
+ std::string status = l10n_util::GetStringUTF8(connection_state);
+ if (connection_type == chromeos::TYPE_CELLULAR &&
+ activation_state != chromeos::ACTIVATION_STATE_ACTIVATED) {
+ status.append(" / ");
+ status.append(
+ chromeos::CellularNetwork::ActivationStateToString(activation_state));
+ }
// service path
network->Append(Value::CreateStringValue(service_path));
// name
@@ -834,7 +850,7 @@ ListValue* InternetOptionsHandler::GetNetwork(const std::string& service_path,
// status
network->Append(Value::CreateStringValue(status));
// type
- network->Append(Value::CreateIntegerValue(connection_type));
+ network->Append(Value::CreateIntegerValue(static_cast<int>(connection_type)));
// connected
network->Append(Value::CreateBooleanValue(connected));
// connecting
@@ -844,6 +860,9 @@ ListValue* InternetOptionsHandler::GetNetwork(const std::string& service_path,
dom_ui_util::GetImageDataUrl(icon)));
// remembered
network->Append(Value::CreateBooleanValue(remembered));
+ // activation_state
+ network->Append(Value::CreateIntegerValue(
+ static_cast<int>(activation_state)));
return network;
}
@@ -870,7 +889,8 @@ ListValue* InternetOptionsHandler::GetWiredList() {
ethernet_network.connecting(),
ethernet_network.connected(),
chromeos::TYPE_ETHERNET,
- false));
+ false,
+ chromeos::ACTIVATION_STATE_UNKNOWN));
}
return list;
}
@@ -897,7 +917,8 @@ ListValue* InternetOptionsHandler::GetWirelessList() {
it->connecting(),
it->connected(),
chromeos::TYPE_WIFI,
- false));
+ false,
+ chromeos::ACTIVATION_STATE_UNKNOWN));
}
const chromeos::CellularNetworkVector& cellular_networks =
@@ -915,7 +936,8 @@ ListValue* InternetOptionsHandler::GetWirelessList() {
it->connecting(),
it->connected(),
chromeos::TYPE_CELLULAR,
- false));
+ false,
+ it->activation_state()));
}
// Add "Other..." if wifi is enabled.
@@ -927,7 +949,8 @@ ListValue* InternetOptionsHandler::GetWirelessList() {
false,
false,
chromeos::TYPE_WIFI,
- false));
+ false,
+ chromeos::ACTIVATION_STATE_UNKNOWN));
}
return list;
@@ -955,7 +978,8 @@ ListValue* InternetOptionsHandler::GetRememberedList() {
it->connecting(),
it->connected(),
chromeos::TYPE_WIFI,
- true));
+ true,
+ chromeos::ACTIVATION_STATE_UNKNOWN));
}
const chromeos::CellularNetworkVector& cellular_networks =
@@ -972,7 +996,8 @@ ListValue* InternetOptionsHandler::GetRememberedList() {
it->connecting(),
it->connected(),
chromeos::TYPE_CELLULAR,
- true));
+ true,
+ it->activation_state()));
}
return list;
diff --git a/chrome/browser/chromeos/dom_ui/internet_options_handler.h b/chrome/browser/chromeos/dom_ui/internet_options_handler.h
index f960121..0d73822 100644
--- a/chrome/browser/chromeos/dom_ui/internet_options_handler.h
+++ b/chrome/browser/chromeos/dom_ui/internet_options_handler.h
@@ -72,7 +72,8 @@ class InternetOptionsHandler : public OptionsPageUIHandler,
// Creates the map of a network
ListValue* GetNetwork(const std::string& service_path, const SkBitmap& icon,
const std::string& name, bool connecting, bool connected,
- int connection_type, bool remembered);
+ chromeos::ConnectionType connection_type, bool remembered,
+ chromeos::ActivationState activation_state);
// Creates the map of wired networks
ListValue* GetWiredList();
diff --git a/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc b/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc
index 879d333..f4e7f52 100644
--- a/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc
+++ b/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc
@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/file_util.h"
#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/string_piece.h"
#include "base/string_util.h"
@@ -38,11 +39,12 @@
namespace {
// Host page JS API function names.
+const char kJsApiStartActivation[] = "startActivation";
const char kJsApiCloseTab[] = "closeTab";
const char kJsApiSetTransactionStatus[] = "setTransactionStatus";
const wchar_t kJsDeviceStatusChangedHandler[] =
- L"handler.MobileSetup.deviceStateChanged";
+ L"mobile.MobileSetup.deviceStateChanged";
// Collular device states that are reported to DOM UI layer.
const char kStateUnknown[] = "unknown";
@@ -116,6 +118,7 @@ class MobileSetupUIHTMLSource : public ChromeURLDataManager::DataSource {
// The handler for Javascript messages related to the "register" view.
class MobileSetupHandler : public DOMMessageHandler,
public chromeos::NetworkLibrary::Observer,
+ public chromeos::NetworkLibrary::PropertyObserver,
public base::SupportsWeakPtr<MobileSetupHandler> {
public:
MobileSetupHandler();
@@ -130,32 +133,65 @@ class MobileSetupHandler : public DOMMessageHandler,
// NetworkLibrary::Observer implementation.
virtual void NetworkChanged(chromeos::NetworkLibrary* obj);
+ // NetworkLibrary::PropertyObserver implementation.
+ virtual void PropertyChanged(const char* service_path,
+ const char* key,
+ const Value* value);
+
+ // Returns currently present cellular network, NULL if no network found.
+ static const chromeos::CellularNetwork* GetNetwork();
private:
+ typedef enum PlanActivationState {
+ PLAN_ACTIVATION_PAGE_LOADING = -1,
+ PLAN_ACTIVATION_START = 0,
+ PLAN_ACTIVATION_INITIATING_ACTIVATION = 1,
+ PLAN_ACTIVATION_ACTIVATING = 2,
+ PLAN_ACTIVATION_SHOWING_PAYMENT = 3,
+ PLAN_ACTIVATION_DONE = 4,
+ PLAN_ACTIVATION_ERROR = 5,
+ } PlanActivationState;
+
// Handlers for JS DOMUI messages.
+ void HandleStartActivation(const ListValue* args);
void HandleCloseTab(const ListValue* args);
void HandleSetTransactionStatus(const ListValue* args);
// Sends message to host registration page with system/user info data.
void SendDeviceInfo();
+ // Verify the state of cellular network and modify internal state.
+ void EvaluateCellularNetwork();
+ // Check the current cellular network for error conditions.
+ bool GotActivationError(const chromeos::CellularNetwork* network,
+ std::string* error);
+ void ChangeState(const chromeos::CellularNetwork* network,
+ PlanActivationState new_state,
+ const std::string& error_description);
+
// Converts the currently active CellularNetwork device into a JS object.
- static bool GetDeviceInfo(DictionaryValue* value);
+ static void GetDeviceInfo(const chromeos::CellularNetwork* network,
+ DictionaryValue* value);
static bool ShouldReportDeviceState(std::string* state, std::string* error);
// Performs activation state cellular device evaluation.
// Returns false if device activation failed. In this case |error|
// will contain error message to be reported to DOM UI.
- static bool CheckForActivationError(chromeos::CellularNetwork network,
- std::string* error);
+ static bool EvaluateCellularDeviceState(bool* report_status,
+ std::string* state,
+ std::string* error);
// Return error message for a given code.
static std::string GetErrorMessage(const std::string& code);
static void LoadCellularConfig();
+ static const char* GetStateDescription(PlanActivationState state);
+
static scoped_ptr<CellularConfigDocument> cellular_config_;
TabContents* tab_contents_;
+ // Internal handler state.
+ PlanActivationState state_;
DISALLOW_COPY_AND_ASSIGN(MobileSetupHandler);
};
@@ -224,10 +260,13 @@ MobileSetupUIHTMLSource::MobileSetupUIHTMLSource()
void MobileSetupUIHTMLSource::StartDataRequest(const std::string& path,
bool is_off_the_record,
int request_id) {
+ const chromeos::CellularNetwork* network = MobileSetupHandler::GetNetwork();
+
DictionaryValue strings;
strings.SetString("title", l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_TITLE));
strings.SetString("connecting_header",
- l10n_util::GetStringUTF16(IDS_MOBILE_CONNECTING_HEADER));
+ l10n_util::GetStringFUTF16(IDS_MOBILE_CONNECTING_HEADER,
+ network ? UTF8ToUTF16(network->name()) : string16()));
strings.SetString("error_header",
l10n_util::GetStringUTF16(IDS_MOBILE_ERROR_HEADER));
strings.SetString("activating_header",
@@ -256,11 +295,15 @@ void MobileSetupUIHTMLSource::StartDataRequest(const std::string& path,
// MobileSetupHandler
//
////////////////////////////////////////////////////////////////////////////////
-MobileSetupHandler::MobileSetupHandler() : tab_contents_(NULL) {
+MobileSetupHandler::MobileSetupHandler()
+ : tab_contents_(NULL), state_(PLAN_ACTIVATION_PAGE_LOADING) {
}
MobileSetupHandler::~MobileSetupHandler() {
- chromeos::CrosLibrary::Get()->GetNetworkLibrary()->RemoveObserver(this);
+ chromeos::NetworkLibrary* lib =
+ chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+ lib->RemoveObserver(this);
+ lib->RemoveProperyObserver(this);
}
DOMMessageHandler* MobileSetupHandler::Attach(DOMUI* dom_ui) {
@@ -269,13 +312,12 @@ DOMMessageHandler* MobileSetupHandler::Attach(DOMUI* dom_ui) {
void MobileSetupHandler::Init(TabContents* contents) {
tab_contents_ = contents;
- chromeos::CrosLibrary::Get()->GetNetworkLibrary()->AddObserver(this);
-
- // TODO(zelidrag): We might want to move this to another thread.
LoadCellularConfig();
}
void MobileSetupHandler::RegisterMessages() {
+ dom_ui_->RegisterMessageCallback(kJsApiStartActivation,
+ NewCallback(this, &MobileSetupHandler::HandleStartActivation));
dom_ui_->RegisterMessageCallback(kJsApiCloseTab,
NewCallback(this, &MobileSetupHandler::HandleCloseTab));
dom_ui_->RegisterMessageCallback(kJsApiSetTransactionStatus,
@@ -283,27 +325,55 @@ void MobileSetupHandler::RegisterMessages() {
}
void MobileSetupHandler::NetworkChanged(chromeos::NetworkLibrary* cros) {
- if (!dom_ui_)
- return;
- DictionaryValue device;
- GetDeviceInfo(&device);
- std::string state, error;
- if (!ShouldReportDeviceState(&state, &error))
+ if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
return;
+ EvaluateCellularNetwork();
+}
- device.SetString("state", state);
- if (error.length())
- device.SetString("error", error);
- dom_ui_->CallJavascriptFunction(
- kJsDeviceStatusChangedHandler, device);
+void MobileSetupHandler::PropertyChanged(const char* service_path,
+ const char* key,
+ const Value* value) {
+ if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
+ return;
+ const chromeos::CellularNetwork* network = GetNetwork();
+ if (network->service_path() != service_path) {
+ NOTREACHED();
+ return;
+ }
+ std::string value_string;
+ LOG(INFO) << "Cellular property change: " << key << " = " <<
+ value_string.c_str();
+ // Force status updates.
+ chromeos::CrosLibrary::Get()->GetNetworkLibrary()->UpdateSystemInfo();
+ EvaluateCellularNetwork();
}
void MobileSetupHandler::HandleCloseTab(const ListValue* args) {
- Browser* browser = BrowserList::GetLastActive();
+ if (!dom_ui_)
+ return;
+ Browser* browser = BrowserList::FindBrowserWithFeature(
+ dom_ui_->GetProfile(), Browser::FEATURE_TABSTRIP);
if (browser)
browser->CloseTabContents(tab_contents_);
}
+void MobileSetupHandler::HandleStartActivation(const ListValue* args) {
+ const chromeos::CellularNetwork* network = GetNetwork();
+ if (!network) {
+ ChangeState(NULL, PLAN_ACTIVATION_ERROR, std::string());
+ return;
+ }
+
+ // Start monitoring network and service property changes.
+ chromeos::NetworkLibrary* lib =
+ chromeos::CrosLibrary::Get()->GetNetworkLibrary();
+ lib->AddObserver(this);
+ lib->AddProperyObserver(network->service_path().c_str(),
+ this);
+ state_ = PLAN_ACTIVATION_START;
+ EvaluateCellularNetwork();
+}
+
void MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) {
const size_t kSetTransactionStatusParamCount = 1;
if (args->GetSize() != kSetTransactionStatusParamCount)
@@ -314,104 +384,235 @@ void MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) {
if (!args->GetString(0, &status))
return;
- chromeos::NetworkLibrary* network_lib =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary();
- const chromeos::CellularNetworkVector& cell_networks =
- network_lib->cellular_networks();
- if (!cell_networks.size())
- return;
-
- // We assume only one cellular network will come from flimflam for now.
- const chromeos::CellularNetwork& network = *(cell_networks.begin());
-
+ // The payment is received, try to reconnect and check the status all over
+ // again.
if (LowerCaseEqualsASCII(status, "OK")) {
- network.StartActivation();
- } else {
- DictionaryValue value;
- value.SetString("state", kFailedPaymentError);
- dom_ui_->CallJavascriptFunction(kJsDeviceStatusChangedHandler, value);
+ ChangeState(GetNetwork(), PLAN_ACTIVATION_START, std::string());
}
}
-bool MobileSetupHandler::ShouldReportDeviceState(std::string* state,
- std::string* error) {
- DCHECK(state);
- DCHECK(error);
- chromeos::NetworkLibrary* network_lib =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary();
- const chromeos::CellularNetworkVector& cell_networks =
- network_lib->cellular_networks();
- // No cellular network present? Treat as network is disconnected.
- // This could be transient state that is the result of activation process.
- if (!cell_networks.size()) {
- *state = kStateDisconnected;
- return true;
+void MobileSetupHandler::EvaluateCellularNetwork() {
+ if (!dom_ui_)
+ return;
+
+ PlanActivationState new_state = state_;
+ const chromeos::CellularNetwork* network = GetNetwork();
+ if (network) {
+ LOG(INFO) << "Cellular:\n service=" << network->GetStateString().c_str() <<
+ "\n ui=" << GetStateDescription(state_) <<
+ "\n activation=" << network->GetActivationStateString().c_str() <<
+ "\n restricted=" << (network->restricted_pool() ? "yes" : "no") <<
+ "\n error=" << network->GetErrorString().c_str() <<
+ "\n setvice_path=" << network->service_path().c_str();
+ } else {
+ LOG(WARNING) << "Cellular service lost";
}
- const chromeos::CellularNetwork& network = cell_networks.at(0);
-
- // First, check if device activation / plan payment failed.
- // It's slightly more complex than just single state check
- // that we are doing for other states below.
- if (!CheckForActivationError(network, error)) {
- *state = kStateError;
- return true;
+ switch (state_) {
+ case PLAN_ACTIVATION_START:
+ if (network) {
+ switch (network->activation_state()) {
+ case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
+ case chromeos::ACTIVATION_STATE_ACTIVATED:
+ if (network->failed_or_disconnected()) {
+ new_state = PLAN_ACTIVATION_ACTIVATING;
+ } else if (network->connection_state() == chromeos::STATE_READY) {
+ if (network->restricted_pool()) {
+ new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
+ } else {
+ new_state = PLAN_ACTIVATION_DONE;
+ }
+ }
+ break;
+ case chromeos::ACTIVATION_STATE_UNKNOWN:
+ case chromeos::ACTIVATION_STATE_NOT_ACTIVATED:
+ if (network->failed_or_disconnected()) {
+ new_state = PLAN_ACTIVATION_INITIATING_ACTIVATION;
+ } if (network->connected()) {
+ LOG(INFO) << "Disconnecting from " <<
+ network->service_path().c_str();
+ chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
+ DisconnectFromWirelessNetwork(*network);
+ }
+ break;
+ default:
+ new_state = PLAN_ACTIVATION_INITIATING_ACTIVATION;
+ break;
+ }
+ }
+ break;
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ if (network) {
+ switch (network->activation_state()) {
+ case chromeos::ACTIVATION_STATE_ACTIVATED:
+ if (network->failed_or_disconnected()) {
+ new_state = PLAN_ACTIVATION_ACTIVATING;
+ } else if (network->connection_state() == chromeos::STATE_READY) {
+ if (network->restricted_pool()) {
+ new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
+ } else {
+ new_state = PLAN_ACTIVATION_DONE;
+ }
+ }
+ break;
+ case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
+ if (network->connected())
+ new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
+ else
+ new_state = PLAN_ACTIVATION_ACTIVATING;
+ break;
+ case chromeos::ACTIVATION_STATE_NOT_ACTIVATED:
+ // Wait in this state until activation state changes.
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+ break;
+ case PLAN_ACTIVATION_ACTIVATING:
+ // Wait until the service shows up and gets activated.
+ if (network) {
+ switch (network->activation_state()) {
+ case chromeos::ACTIVATION_STATE_ACTIVATED:
+ if (network->connection_state() == chromeos::STATE_READY) {
+ if (network->restricted_pool()) {
+ new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
+ } else {
+ new_state = PLAN_ACTIVATION_DONE;
+ }
+ }
+ break;
+ case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
+ if (network->connected()) {
+ if (network->restricted_pool())
+ new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
+ }
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+ break;
+ case PLAN_ACTIVATION_PAGE_LOADING:
+ break;
+ // Just ignore all signals until the site confirms payment.
+ case PLAN_ACTIVATION_SHOWING_PAYMENT:
+ // Activation completed/failed, ignore network changes.
+ case PLAN_ACTIVATION_DONE:
+ case PLAN_ACTIVATION_ERROR:
+ break;
}
- switch (network.activation_state()) {
- case chromeos::ACTIVATION_STATE_UNKNOWN:
- case chromeos::ACTIVATION_STATE_NOT_ACTIVATED:
- // If this page is shown, I assume that we have already kicked off the
- // process of starting the activation even though the device status
- // reporting might not have caught up with us yet.
- *state = kStateConnecting;
- return true;
- case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
- case chromeos::ACTIVATION_STATE_ACTIVATING:
- *state = kStateActivating;
- return true;
- case chromeos::ACTIVATION_STATE_ACTIVATED:
- *state = kStateConnected;
- return true;
+ std::string error_description;
+ if (GotActivationError(network, &error_description)) {
+ new_state = PLAN_ACTIVATION_ERROR;
}
+ ChangeState(network, new_state, error_description);
+}
- // We don't report states that we don't understand to DOM UI.
- *state = kStateUnknown;
- return false;
+// Debugging helper function, will take it out at the end.
+const char* MobileSetupHandler::GetStateDescription(
+ PlanActivationState state) {
+ switch (state) {
+ case PLAN_ACTIVATION_PAGE_LOADING:
+ return "PAGE_LOADING";
+ case PLAN_ACTIVATION_START:
+ return "ACTIVATION_START";
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ return "INITIATING_ACTIVATION";
+ case PLAN_ACTIVATION_ACTIVATING :
+ return "ACTIVATING";
+ case PLAN_ACTIVATION_SHOWING_PAYMENT:
+ return "SHOWING_PAYMENT";
+ case PLAN_ACTIVATION_DONE:
+ return "DONE";
+ case PLAN_ACTIVATION_ERROR:
+ return "ERROR";
+ }
+ return "UNKNOWN";
+}
+
+void MobileSetupHandler::ChangeState(const chromeos::CellularNetwork* network,
+ PlanActivationState new_state,
+ const std::string& error_description) {
+ static bool first_time = true;
+ if (state_ == new_state && !first_time)
+ return;
+ LOG(INFO) << "Activation state flip old = " << GetStateDescription(state_) <<
+ ", new = " << GetStateDescription(new_state);
+ first_time = false;
+ state_ = new_state;
+ switch (new_state) {
+ case PLAN_ACTIVATION_START:
+ break;
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ DCHECK(network);
+ LOG(INFO) << "Activating service " << network->service_path().c_str();
+ if (!network->StartActivation()) {
+ new_state = PLAN_ACTIVATION_ERROR;
+ }
+ break;
+ case PLAN_ACTIVATION_ACTIVATING:
+ DCHECK(network);
+ if (network) {
+ chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
+ ConnectToCellularNetwork(*network);
+ }
+ break;
+ case PLAN_ACTIVATION_PAGE_LOADING:
+ return;
+ case PLAN_ACTIVATION_SHOWING_PAYMENT:
+ case PLAN_ACTIVATION_DONE:
+ case PLAN_ACTIVATION_ERROR:
+ break;
+ }
+
+ DictionaryValue device_dict;
+ if (network)
+ GetDeviceInfo(network, &device_dict);
+ device_dict.SetInteger("state", new_state);
+ if (error_description.length())
+ device_dict.SetString("error", error_description);
+ dom_ui_->CallJavascriptFunction(
+ kJsDeviceStatusChangedHandler, device_dict);
}
-bool MobileSetupHandler::CheckForActivationError(
- chromeos::CellularNetwork network, std::string* error) {
+bool MobileSetupHandler::GotActivationError(
+ const chromeos::CellularNetwork* network, std::string* error) {
+ if (network)
+ return false;
bool got_error = false;
const char* error_code = kErrorDefault;
- // This is the magic of error selecting based
- if (network.connection_state() == chromeos::STATE_FAILURE &&
- network.error() == chromeos::ERROR_AAA_FAILED ) {
- if (network.activation_state() ==
+ // This is the magic for detection of errors in during activation process.
+ if (network->connection_state() == chromeos::STATE_FAILURE &&
+ network->error() == chromeos::ERROR_AAA_FAILED ) {
+ if (network->activation_state() ==
chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
error_code = kErrorBadConnectionPartial;
- } else if (network.activation_state() ==
+ } else if (network->activation_state() ==
chromeos::ACTIVATION_STATE_ACTIVATED) {
- if (network.roaming_state() == chromeos::ROAMING_STATE_HOME) {
+ if (network->roaming_state() == chromeos::ROAMING_STATE_HOME) {
error_code = kErrorBadConnectionActivated;
- } else if (network.roaming_state() == chromeos::ROAMING_STATE_ROAMING) {
+ } else if (network->roaming_state() == chromeos::ROAMING_STATE_ROAMING) {
error_code = kErrorRoamingOnConnection;
}
}
got_error = true;
- } else if (network.connection_state() ==
+ } else if (network->connection_state() ==
chromeos::STATE_ACTIVATION_FAILURE) {
- if (network.error() == chromeos::ERROR_NEED_EVDO) {
- if (network.activation_state() ==
+ if (network->error() == chromeos::ERROR_NEED_EVDO) {
+ if (network->activation_state() ==
chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED)
error_code = kErrorNoEVDO;
- } else if (network.error() == chromeos::ERROR_NEED_HOME_NETWORK) {
- if (network.activation_state() ==
+ } else if (network->error() == chromeos::ERROR_NEED_HOME_NETWORK) {
+ if (network->activation_state() ==
chromeos::ACTIVATION_STATE_NOT_ACTIVATED) {
error_code = kErrorRoamingActivation;
- } else if (network.activation_state() ==
+ } else if (network->activation_state() ==
chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
error_code = kErrorRoamingPartiallyActivated;
}
@@ -422,29 +623,29 @@ bool MobileSetupHandler::CheckForActivationError(
if (got_error)
*error = GetErrorMessage(error_code);
- return !got_error;
+ return got_error;
}
-bool MobileSetupHandler::GetDeviceInfo(DictionaryValue* value) {
- DCHECK(value);
+const chromeos::CellularNetwork* MobileSetupHandler::GetNetwork() {
chromeos::NetworkLibrary* network_lib =
chromeos::CrosLibrary::Get()->GetNetworkLibrary();
const chromeos::CellularNetworkVector& cell_networks =
network_lib->cellular_networks();
- if (!cell_networks.size()) {
- return false;
- }
+ if (!cell_networks.size())
+ return NULL;
+ return &(*(cell_networks.begin()));
+}
- const chromeos::CellularNetwork& network = *(cell_networks.begin());
- value->SetString("carrier", UTF8ToUTF16(network.name()));
- value->SetString("payment_url", UTF8ToUTF16(network.payment_url()));
- value->SetString("MEID", UTF8ToUTF16(network.meid()));
- value->SetString("IMEI", UTF8ToUTF16(network.imei()));
- value->SetString("IMSI", UTF8ToUTF16(network.imsi()));
- value->SetString("ESN", UTF8ToUTF16(network.esn()));
- value->SetString("MDN", UTF8ToUTF16(network.mdn()));
- return true;
+void MobileSetupHandler::GetDeviceInfo(const chromeos::CellularNetwork* network,
+ DictionaryValue* value) {
+ if (!network)
+ return;
+ value->SetString("carrier", network->name());
+ value->SetString("payment_url", network->payment_url());
+ value->SetString("MEID", network->meid());
+ value->SetString("IMEI", network->imei());
+ value->SetString("MDN", network->mdn());
}
std::string MobileSetupHandler::GetErrorMessage(const std::string& code) {
diff --git a/chrome/browser/resources/mobile_setup.html b/chrome/browser/resources/mobile_setup.html
index 5fa2e49..eba150e 100644
--- a/chrome/browser/resources/mobile_setup.html
+++ b/chrome/browser/resources/mobile_setup.html
@@ -22,7 +22,7 @@ iframe {
top: 0;
bottom: 0;
z-index: 10;
- padding: 20px;
+ padding: 100px;
-webkit-box-align: center;
-webkit-box-pack: center;
}
@@ -45,7 +45,7 @@ iframe {
text-align: center;
}
-#payment-form {
+#paymentForm {
display: -webkit-box;
position: absolute;
left: 0;
@@ -61,7 +61,7 @@ iframe {
height: 58px;
}
-#error-msg {
+#errorMessage {
margin: 20px;
}
@@ -69,13 +69,13 @@ iframe {
display: -webkit-box;
}
-#final-logo {
+#finalLogo {
position: absolute;
- right: 30px;
+ right: 130px;
width: 150px;
}
-#activation-logo {
+#activationLogo {
background-position: center;
margin-bottom: 20px;
margin-top: 20px;
@@ -90,80 +90,39 @@ iframe {
height: 1px;
}
-body[state='connecting'] > #payment-form,
-body[state='connecting'] > #final-message,
-body[state='connecting'] > * > #error-message {
- display: none
-}
-body[state='connecting'] > #system-status {
- display: block
-}
-
-body[state='error'] > #payment-form,
-body[state='error'] > #final-message {
- display: none
-}
-body[state='error'] > * > #error-message,
-body[state='error'] > #system-status {
- display: block
-}
-
-body[state='payment'] > * > #error-message,
-body[state='payment'] > #final-message,
-body[state='payment'] > #system-status {
- display: none
-}
-body[state='payment'] > #payment-form {
- display: block
-}
-
-body[state='activating'] > #payment-form,
-body[state='activating'] > #final-message,
-body[state='activating'] > * > #error-message {
- display: none
-}
-body[state='activating'] > #system-status {
- display: block
-}
-
-body[state='connected'] > * > #error-message,
-body[state='connected'] > #system-status {
- display: none
-}
-body[state='connected'] > #payment-form,
-body[state='connected'] > #final-message {
- display: block
+.hidden {
+ display: none;
}
.testing-only {
+ position: absolute;
+ left: 0;
+ top: 0;
}
</style>
<script src="chrome://resources/js/cr.js"></script>
+<script src="chrome://resources/js/local_strings.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="mobile_setup.js"></script>
-<script>
- mobile.MobileSetup.getInstance().initialize('payment-form');
-</script>
</head>
-<body state="connecting" onload="setInterval(mobile.MobileSetup.drawProgress, 100);"
- i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
- <iframe id="payment-form" frameborder="0"></iframe>
- <div id="system-status" class="startup">
- <div class="status-header"><h3 id="header"
- i18n-content="status_header"></h3></div>
- <div id="error-message"></div>
+<body onload="mobile.MobileSetup.loadPage();"
+ i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
+ <iframe class="hidden" id="paymentForm" frameborder="0"></iframe>
+ <div id="systemStatus" class="startup hidden">
+ <div><h3 id="statusHeader"></h3></div>
+ <div id="errorMessage"></div>
<canvas id="canvas" width="56" height="56"></canvas>
<div id="splitter"></div>
- <div id="activation-logo" class="logo"></div>
+ <div id="activationLogo" class="logo"></div>
</div>
- <div id="final-message" class="overlay">
+ <div id="finalMessage" class="overlay hidden">
<div class="box">
<div>
<div class="header"><h3 i18n-content="completed_header"></h3></div>
<div id="action" i18n-content="completed_text"></div>
</div>
- <div id="final-logo" class="logo"></div>
+ <div id="finalLogo" class="logo"></div>
</div>
</div>
<div class="testing-only">
diff --git a/chrome/browser/resources/mobile_setup.js b/chrome/browser/resources/mobile_setup.js
index f6c481d..0aa8d17 100644
--- a/chrome/browser/resources/mobile_setup.js
+++ b/chrome/browser/resources/mobile_setup.js
@@ -10,13 +10,22 @@ cr.define('mobile', function() {
cr.addSingletonGetter(MobileSetup);
+ MobileSetup.PLAN_ACTIVATION_LOADING = -1;
+ MobileSetup.PLAN_ACTIVATION_START = 0;
+ MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION = 1;
+ MobileSetup.PLAN_ACTIVATION_ACTIVATING = 2;
+ MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT = 3;
+ MobileSetup.PLAN_ACTIVATION_DONE = 4;
+ MobileSetup.PLAN_ACTIVATION_ERROR = 5;
+
+ MobileSetup.localStrings_ = new LocalStrings();
+
MobileSetup.prototype = {
// Mobile device information.
deviceInfo_: null,
- frame_name_ : '',
- local_strings_: new LocalStrings();
+ frameName_ : '',
// UI states.
- state_ : 0,
+ state_ : -1,
STATE_UNKNOWN_: "unknown",
STATE_CONNECTING_: "connecting",
STATE_ERROR_: "error",
@@ -26,21 +35,34 @@ cr.define('mobile', function() {
initialize: function(frame_name) {
self = this;
- this.frame_name_ = frame_name;
- document.addEventListener('DOMContentLoaded', function(deviceInfo) {
- chrome.send('getDeviceInfo',
- ['mobile.MobileSetup.getDeviceInfoCallback']);
- });
+ this.frameName_ = frame_name;
window.addEventListener('message', function(e) {
self.onMessageReceived_(e);
});
+ $('cheat').addEventListener('click', function(e) {
+ chrome.send('setTransactionStatus', ['OK']);
+ });
+ $(frame_name).addEventListener('load', function(e) {
+ // Flip the visibility of the payment page only after the frame is
+ // fully loaded.
+ $('statusHeader').textContent = '';
+ $('paymentForm').classList.remove('hidden');
+ $('finalMessage').classList.add('hidden');
+ $('errorMessage').classList.add('hidden');
+ $('systemStatus').classList.add('hidden');
+ });
+
+ this.changeState_(MobileSetup.PLAN_ACTIVATION_LOADING);
+ setInterval(mobile.MobileSetup.drawProgress, 100);
+ // Kick off activation process.
+ chrome.send('startActivation', []);
},
- loadPaymentFrame: function(deviceInfo) {
+ loadPaymentFrame_: function(deviceInfo) {
if (deviceInfo) {
this.deviceInfo_ = deviceInfo;
- $(this.frame_name_).contentWindow.location.href =
+ $(this.frameName_).contentWindow.location.href =
this.deviceInfo_.payment_url;
}
},
@@ -57,36 +79,59 @@ cr.define('mobile', function() {
}
},
- changeState: function(new_state, errorText) {
- if (state_ == new_state)
+ changeState_: function(deviceInfo) {
+ var new_state = deviceInfo.state;
+ if (this.state_ == new_state)
return;
- if (new_state == STATE_UNKNOWN_)
- document.body.setAttribute('state', STATE_CONNECTING_);
- else
- document.body.setAttribute('state', new_state);
+ var main = $('mainbody');
+ // Map handler state to UX.
switch(new_state) {
- case STATE_UNKNOWN_:
- case STATE_CONNECTING_:
- $('status-header').textContent =
- local_strings_.getString('connecting_header');
- $('error-message').textContent = '';
+ case MobileSetup.PLAN_ACTIVATION_LOADING:
+ case MobileSetup.PLAN_ACTIVATION_START:
+ $('statusHeader').textContent =
+ MobileSetup.localStrings_.getString('connecting_header');
+ $('errorMessage').textContent = '';
+ $('paymentForm').classList.add('hidden');
+ $('finalMessage').classList.add('hidden');
+ $('errorMessage').classList.add('hidden');
+ $('systemStatus').classList.remove('hidden');
+ case MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ case MobileSetup.PLAN_ACTIVATION_ACTIVATING:
+ $('statusHeader').textContent =
+ MobileSetup.localStrings_.getString('activating_header');
+ $('errorMessage').textContent = '';
+ $('paymentForm').classList.add('hidden');
+ $('finalMessage').classList.add('hidden');
+ $('errorMessage').classList.add('hidden');
+ $('systemStatus').classList.remove('hidden');
break;
- case STATE_ERROR_:
- $('status-header').textContent =
- local_strings_.getString('error_header');
- $('error-message').textContent = errorText;
+ case MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT:
+ this.loadPaymentFrame_(deviceInfo);
break;
- case STATE_ACTIVATING_:
- $('status-header').textContent =
- local_strings_.getString('activating_header');
- $('error-message').textContent = '';
+ case MobileSetup.PLAN_ACTIVATION_DONE:
+ $('statusHeader').textContent = '';
+ $('paymentForm').classList.add('hidden');
+ $('finalMessage').classList.remove('hidden');
+ $('errorMessage').classList.add('hidden');
+ $('systemStatus').classList.add('hidden');
+ break;
+ case MobileSetup.PLAN_ACTIVATION_ERROR:
+ $('statusHeader').textContent =
+ MobileSetup.localStrings_.getString('error_header');
+ $('errorMessage').textContent = deviceInfo.error;
+ $('paymentForm').classList.add('hidden');
+ $('finalMessage').classList.add('hidden');
+ $('errorMessage').classList.remove('hidden');
+ $('systemStatus').classList.remove('hidden');
break;
}
- state_ = new_state;
+ this.state_ = new_state;
+ $('statusHeader').textContent =
+ $('statusHeader').textContent + ' (state = ' + new_state + ')';
},
updateDeviceStatus_: function(deviceInfo) {
- this.changeState(deviceInfo.state, deviceInfo.error);
+ this.changeState_(deviceInfo);
},
sendDeviceInfo_ : function() {
@@ -97,19 +142,16 @@ cr.define('mobile', function() {
'carrier': this.deviceInfo_.carrier,
'MEID': this.deviceInfo_.MEID,
'IMEI': this.deviceInfo_.IMEI,
- 'IMSI': this.deviceInfo_.IMSI,
- 'ESN': this.deviceInfo_.ESN,
'MDN': this.deviceInfo_.MDN
}
};
- $(this.frame_name_).contentWindow.postMessage(msg,
+ $(this.frameName_).contentWindow.postMessage(msg,
this.deviceInfo_.payment_url);
}
};
MobileSetup.drawProgress = function () {
- var canvas = $('wheel');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
@@ -147,15 +189,14 @@ cr.define('mobile', function() {
}
};
- MobileSetup.getDeviceInfoCallback = function(deviceInfo) {
- MobileSetup.getInstance().loadPaymentFrame(deviceInfo);
- };
-
-
MobileSetup.deviceStateChanged = function(deviceInfo) {
MobileSetup.getInstance().updateDeviceStatus_(deviceInfo);
};
+ MobileSetup.loadPage = function() {
+ mobile.MobileSetup.getInstance().initialize('paymentForm');
+ };
+
// Export
return {
MobileSetup: MobileSetup
diff --git a/chrome/browser/resources/options/chromeos_internet_detail.html b/chrome/browser/resources/options/chromeos_internet_detail.html
index 1bfba82..d715acc 100644
--- a/chrome/browser/resources/options/chromeos_internet_detail.html
+++ b/chrome/browser/resources/options/chromeos_internet_detail.html
@@ -69,7 +69,7 @@
</div>
<div id="cellularPlanTab" class="subpages-tab-contents cellular-details">
<section>
- <table class="option-control-table">
+ <table class="option-control-table" id="details-plan-table">
<tr class="plan-loading-info">
<td colspan="2" i18n-content="planLoading" class="option-value"></td>
</tr>
diff --git a/chrome/browser/resources/options/chromeos_internet_network_element.js b/chrome/browser/resources/options/chromeos_internet_network_element.js
index 42c6fb1..79ab3b1 100644
--- a/chrome/browser/resources/options/chromeos_internet_network_element.js
+++ b/chrome/browser/resources/options/chromeos_internet_network_element.js
@@ -105,7 +105,8 @@ cr.define('options.internet', function() {
connected: network[4],
connecting: network[5],
iconURL: network[6],
- remembered: network[7]
+ remembered: network[7],
+ activation_state: network[8]
};
NetworkItem.decorate(el);
return el;
@@ -117,6 +118,18 @@ cr.define('options.internet', function() {
* @type {number}
*/
NetworkItem.MIN_WIRELESS_PASSWORD_LENGTH = 5;
+ // Cellular activation states:
+ NetworkItem.ACTIVATION_STATE_UNKNOWN = 0;
+ NetworkItem.ACTIVATION_STATE_ACTIVATED = 1;
+ NetworkItem.ACTIVATION_STATE_ACTIVATING = 2;
+ NetworkItem.ACTIVATION_STATE_NOT_ACTIVATED = 3;
+ NetworkItem.ACTIVATION_STATE_PARTIALLY_ACTIVATED = 4;
+ NetworkItem.TYPE_UNKNOWN = 0;
+ NetworkItem.TYPE_ETHERNET = 1;
+ NetworkItem.TYPE_WIFI = 2;
+ NetworkItem.TYPE_WIMAX = 3;
+ NetworkItem.TYPE_BLUETOOTH = 4;
+ NetworkItem.TYPE_CELLULAR = 5;
/**
* Decorates an element as a network item.
@@ -170,16 +183,48 @@ cr.define('options.internet', function() {
this.appendChild(spacerDiv);
var buttonsDiv = this.ownerDocument.createElement('div');
+ var self = this;
if (!this.data.remembered) {
+ var show_activate =
+ this.data.networkType == NetworkItem.TYPE_CELLULAR &&
+ this.data.activation_state !=
+ NetworkItem.ACTIVATION_STATE_ACTIVATED &&
+ this.data.activation_state !=
+ NetworkItem.ACTIVATION_STATE_ACTIVATING;
+
+ // Disconnect button if not ethernet and if cellular it should be
+ // activated.
+ if (this.data.networkType != NetworkItem.TYPE_ETHERNET &&
+ !show_activate && this.data.connected) {
+ buttonsDiv.appendChild(
+ this.createButton_('disconnect_button',
+ function(e) {
+ chrome.send('buttonClickCallback',
+ [String(self.data.networkType),
+ self.data.servicePath,
+ 'disconnect']);
+ }));
+ }
+ // Show [Activate] button for non-activated Cellular network.
+ if (show_activate) {
+ buttonsDiv.appendChild(
+ this.createButton_('activate_button',
+ function(e) {
+ chrome.send('buttonClickCallback',
+ [String(self.data.networkType),
+ self.data.servicePath,
+ 'activate']);
+ }));
+ }
if (this.data.connected) {
- // disconnect button (if not ethernet)
- if (this.data.networkType != 1)
- buttonsDiv.appendChild(this.createButton_('disconnect_button',
- 'disconnect'));
-
- // options button
- buttonsDiv.appendChild(this.createButton_('options_button',
- 'options'));
+ buttonsDiv.appendChild(
+ this.createButton_('options_button',
+ function(e) {
+ chrome.send('buttonClickCallback',
+ [String(self.data.networkType),
+ self.data.servicePath,
+ 'options']);
+ }));
}
} else {
// forget button
@@ -306,12 +351,10 @@ cr.define('options.internet', function() {
* @param {Object} name The name of the localStrings to use for the text.
* @param {Object} type The type of button.
*/
- createButton_: function(name, type) {
+ createButton_: function(name, callback) {
var buttonEl = this.ownerDocument.createElement('button');
buttonEl.textContent = localStrings.getString(name);
- buttonEl.buttonType = type;
- buttonEl.networkType = this.data.networkType;
- buttonEl.servicePath = this.data.servicePath;
+ buttonEl.addEventListener('click', callback);
return buttonEl;
}
};
diff --git a/chrome/browser/resources/options/chromeos_internet_options_page.css b/chrome/browser/resources/options/chromeos_internet_options_page.css
index 81378f3..3bf3cea 100644
--- a/chrome/browser/resources/options/chromeos_internet_options_page.css
+++ b/chrome/browser/resources/options/chromeos_internet_options_page.css
@@ -78,7 +78,7 @@
background: 0 50% no-repeat;
cursor: default;
display: table-cell;
- height: 24px;
+ height: 32px;
line-height: 100%;
max-width: 320px;
overflow: hidden;
@@ -115,12 +115,21 @@
#detailsInternetPage {
min-width: 400px;
min-height: 360px;
+ position: relative;
}
.details-button {
float: right;
}
+#details-plan-table {
+ width: 100%;
+}
+
+#planSummary {
+ width: 250px;
+}
+
html[dir='rtl'] .details-button {
float: left;
}
@@ -151,7 +160,6 @@ html[dir='rtl'] .details-button {
display: block;
}
-
#wirelessButtons[wifiEnabled] > * > #enableWifi,
#wirelessButtons:not([wifiEnabled]) > * > #disableWifi,
#wirelessButtons[cellularEnabled] > * > #enableCellular,
diff --git a/chrome/browser/resources/options/options_page.css b/chrome/browser/resources/options/options_page.css
index 8f97c64..ccca955 100644
--- a/chrome/browser/resources/options/options_page.css
+++ b/chrome/browser/resources/options/options_page.css
@@ -56,8 +56,10 @@ html[dir='rtl'] #close-overlay {
}
.overlay .button-strip {
- padding-top: 20px;
- text-align: end;
+ padding: 12px;
+ position: absolute;
+ right: 0px;
+ bottom: 0px;
}
.overlay > div {
@@ -173,7 +175,7 @@ html[hide-menu=true] #mainview {
}
#mainview-content {
- width: 550px;
+ width: 600px;
padding: 0 24px;
}
diff --git a/chrome/browser/resources/options/subpages_tab_controls.css b/chrome/browser/resources/options/subpages_tab_controls.css
index 0fc7d21..273078a 100644
--- a/chrome/browser/resources/options/subpages_tab_controls.css
+++ b/chrome/browser/resources/options/subpages_tab_controls.css
@@ -10,7 +10,6 @@ found in the LICENSE file.
left bottom,
from(white),
to(#f3f3f3));
- border-bottom: 1px solid #a0a0a0;
padding: 4px 8px;
}