diff options
author | zelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 23:15:31 +0000 |
---|---|---|
committer | zelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 23:15:31 +0000 |
commit | 9a24152e4ccc64043f01607cbecb3bee7d090ef8 (patch) | |
tree | 982d34ec2a38f1fbcffccb42fa3e362e309eea5c /chrome/browser/chromeos | |
parent | 143572308f033b06673de2d6da57bc03f1118a6a (diff) | |
download | chromium_src-9a24152e4ccc64043f01607cbecb3bee7d090ef8.zip chromium_src-9a24152e4ccc64043f01607cbecb3bee7d090ef8.tar.gz chromium_src-9a24152e4ccc64043f01607cbecb3bee7d090ef8.tar.bz2 |
Finished mobile activation UI. Notification logic need to be tested.
BUG=chromium-os:4739, chromium-os:6949
TEST=none
Review URL: http://codereview.chromium.org/3606005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62041 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos')
-rw-r--r-- | chrome/browser/chromeos/cros/network_library.cc | 18 | ||||
-rw-r--r-- | chrome/browser/chromeos/cros/network_library.h | 7 | ||||
-rw-r--r-- | chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc | 336 |
3 files changed, 320 insertions, 41 deletions
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index 1653cd2..b86f62e 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -195,6 +195,24 @@ bool CellularNetwork::StartActivation() const { void CellularNetwork::Clear() { WirelessNetwork::Clear(); + activation_state_ = ACTIVATION_STATE_UNKNOWN; + roaming_state_ = ROAMING_STATE_UNKNOWN; + network_technology_ = NETWORK_TECHNOLOGY_UNKNOWN; + operator_name_.clear(); + operator_code_.clear(); + payment_url_.clear(); + meid_.clear(); + imei_.clear(); + imsi_.clear(); + esn_.clear(); + mdn_.clear(); + min_.clear(); + model_id_.clear(); + manufacturer_.clear(); + firmware_revision_.clear(); + hardware_revision_.clear(); + last_update_.clear(); + prl_version_ = 0; } void CellularNetwork::ConfigureFromService(const ServiceInfo& service) { diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h index b147206..38411d5 100644 --- a/chrome/browser/chromeos/cros/network_library.h +++ b/chrome/browser/chromeos/cros/network_library.h @@ -23,6 +23,7 @@ class Network { const std::string& device_path() const { return device_path_; } const std::string& ip_address() const { return ip_address_; } ConnectionType type() const { return type_; } + ConnectionState connection_state() const { return state_; } bool connecting() const { return state_ == STATE_ASSOCIATION || state_ == STATE_CONFIGURATION || state_ == STATE_CARRIER; } bool connected() const { return state_ == STATE_READY; } @@ -62,7 +63,7 @@ class Network { std::string device_path_; std::string ip_address_; ConnectionType type_; - int state_; + ConnectionState state_; ConnectionError error_; }; @@ -129,8 +130,8 @@ class CellularNetwork : public WirelessNetwork { const NetworkTechnology network_technology() const { return network_technology_; } const NetworkRoamingState roaming_state() const { return roaming_state_; } - const std::string& operator_name() const { return payment_url_; } - const std::string& operator_code() const { return payment_url_; } + 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_; } const std::string& meid() const { return meid_; } const std::string& imei() const { return imei_; } diff --git a/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc b/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc index 1c11c09..405ec7e 100644 --- a/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc +++ b/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc @@ -4,18 +4,26 @@ #include "chrome/browser/chromeos/dom_ui/mobile_setup_ui.h" +#include <map> #include <string> #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/callback.h" +#include "base/file_util.h" +#include "base/json/json_reader.h" #include "base/logging.h" #include "base/string_piece.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/values.h" #include "base/weak_ptr.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chromeos/cros/cros_library.h" +#include "chrome/browser/chromeos/cros/network_library.h" +#include "chrome/browser/chromeos/cros/system_library.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/tab_contents/tab_contents.h" @@ -27,21 +35,65 @@ #include "grit/generated_resources.h" #include "grit/locale_settings.h" -#include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/cros/network_library.h" -#include "chrome/browser/chromeos/cros/system_library.h" - namespace { // Host page JS API function names. -const char kJsApiGetDeviceInfo[] = "getDeviceInfo"; +const char kJsApiCloseTab[] = "closeTab"; const char kJsApiSetTransactionStatus[] = "setTransactionStatus"; const wchar_t kJsDeviceStatusChangedHandler[] = - L"mobile.MobileSetup.onDeviceStatusChanged"; + L"handler.MobileSetup.deviceStateChanged"; + +// Collular device states that are reported to DOM UI layer. +const char kStateUnknown[] = "unknown"; +const char kStateConnecting[] = "connecting"; +const char kStateError[] = "error"; +const char kStateNeedsPayment[] = "payment"; +const char kStateActivating[] = "activating"; +const char kStateDisconnected[] = "disconnected"; +const char kStateConnected[] = "connected"; +const char kFailedPayment[] = "failed_payment"; + +// Error codes matching codes defined in the cellular config file. +const char kErrorDefault[] = "default"; +const char kErrorBadConnectionPartial[] = "bad_connection_partial"; +const char kErrorBadConnectionActivated[] = "bad_connection_activated"; +const char kErrorRoamingOnConnection[] = "roaming_connection"; +const char kErrorNoEVDO[] = "no_evdo"; +const char kErrorRoamingActivation[] = "roaming_activation"; +const char kErrorRoamingPartiallyActivated[] = "roaming_partially_activated"; +const char kErrorNoService[] = "no_service"; +const char kFailedPaymentError[] = "failed_payment"; + +// Cellular configuration file path. +const char kCellularConfigPath[] = + "/usr/share/chromeos-assets/mobile/mobile_config.json"; + +// Cellular config file field names. +const char kVersionField[] = "version"; +const char kErrorsField[] = "errors"; } // namespace +class CellularConfigDocument { + public: + CellularConfigDocument() {} + + // Return error message for a given code. + std::string GetErrorMessage(const std::string& code); + const std::string& version() { return version_; } + + bool LoadFromFile(const FilePath& config_path); + + private: + std::string version_; + std::map<std::string, std::string> error_map_; + + DISALLOW_COPY_AND_ASSIGN(CellularConfigDocument); +}; + +static std::map<std::string, std::string> error_messages_; + class MobileSetupUIHTMLSource : public ChromeURLDataManager::DataSource { public: MobileSetupUIHTMLSource(); @@ -63,32 +115,102 @@ class MobileSetupUIHTMLSource : public ChromeURLDataManager::DataSource { // The handler for Javascript messages related to the "register" view. class MobileSetupHandler : public DOMMessageHandler, + public chromeos::NetworkLibrary::Observer, public base::SupportsWeakPtr<MobileSetupHandler> { public: MobileSetupHandler(); virtual ~MobileSetupHandler(); // Init work after Attach. - void Init(); + void Init(TabContents* contents); // DOMMessageHandler implementation. virtual DOMMessageHandler* Attach(DOMUI* dom_ui); virtual void RegisterMessages(); + // NetworkLibrary::Observer implementation. + virtual void NetworkChanged(chromeos::NetworkLibrary* obj); + private: // Handlers for JS DOMUI messages. - void HandleGetDeviceInfo(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(); - // Converts device the current CelularNetork into JS object. - bool GetDeviceInfo(DictionaryValue* value); + // Converts the currently active CellularNetwork device into a JS object. + static bool GetDeviceInfo(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); + + // Return error message for a given code. + static std::string GetErrorMessage(const std::string& code); + static void LoadCellularConfig(); + static scoped_ptr<CellularConfigDocument> cellular_config_; + + TabContents* tab_contents_; DISALLOW_COPY_AND_ASSIGN(MobileSetupHandler); }; +scoped_ptr<CellularConfigDocument> MobileSetupHandler::cellular_config_; + +//////////////////////////////////////////////////////////////////////////////// +// +// CellularConfigDocument +// +//////////////////////////////////////////////////////////////////////////////// + +std::string CellularConfigDocument::GetErrorMessage(const std::string& code) { + std::map<std::string, std::string>::iterator iter = error_map_.find(code); + if (iter == error_map_.end()) + return code; + return iter->second; +} + +bool CellularConfigDocument::LoadFromFile(const FilePath& config_path) { + error_map_.clear(); + + std::string config; + if (!file_util::ReadFileToString(config_path, &config)) + return false; + + scoped_ptr<Value> root(base::JSONReader::Read(config, true)); + DCHECK(root.get() != NULL); + if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) { + LOG(INFO) << "Bad cellular config file"; + return false; + } + + DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get()); + if (!root_dict->GetString(kVersionField, &version_)) { + LOG(INFO) << "Cellular config file missing version"; + return false; + } + DictionaryValue* errors = NULL; + if (!root_dict->GetDictionary(kErrorsField, &errors)) + return false; + for (DictionaryValue::key_iterator keys = errors->begin_keys(); + keys != errors->end_keys(); + ++keys) { + std::string value; + if (!errors->GetString(*keys, &value)) { + LOG(INFO) << "Bad cellular config error value"; + error_map_.clear(); + return false; + } + + error_map_.insert(std::pair<std::string, std::string>(*keys, value)); + } + return true; +} + //////////////////////////////////////////////////////////////////////////////// // // MobileSetupUIHTMLSource @@ -104,8 +226,16 @@ void MobileSetupUIHTMLSource::StartDataRequest(const std::string& path, int request_id) { DictionaryValue strings; strings.SetString("title", l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_TITLE)); - strings.SetString("header", - l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_HEADER)); + strings.SetString("connecting_header", + l10n_util::GetStringUTF16(IDS_MOBILE_CONNECTING_HEADER)); + strings.SetString("error_header", + l10n_util::GetStringUTF16(IDS_MOBILE_ERROR_HEADER)); + strings.SetString("activating_header", + l10n_util::GetStringUTF16(IDS_MOBILE_ACTIVATING_HEADER)); + strings.SetString("completed_header", + l10n_util::GetStringUTF16(IDS_MOBILE_COMPLETED_HEADER)); + strings.SetString("completed_text", + l10n_util::GetStringUTF16(IDS_MOBILE_COMPLETED_TEXT)); SetFontAndTextDirection(&strings); static const base::StringPiece html( @@ -126,42 +256,52 @@ void MobileSetupUIHTMLSource::StartDataRequest(const std::string& path, // MobileSetupHandler // //////////////////////////////////////////////////////////////////////////////// -MobileSetupHandler::MobileSetupHandler() { +MobileSetupHandler::MobileSetupHandler() : tab_contents_(NULL) { } MobileSetupHandler::~MobileSetupHandler() { + chromeos::CrosLibrary::Get()->GetNetworkLibrary()->RemoveObserver(this); } DOMMessageHandler* MobileSetupHandler::Attach(DOMUI* dom_ui) { return DOMMessageHandler::Attach(dom_ui); } -void MobileSetupHandler::Init() { - // TODO(zelidag): Register for network change notification to make sure - // that the status of the cellular network does not flip to something we - // can't handle (disabled, suddenly activated by divine intervention...). +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(kJsApiGetDeviceInfo, - NewCallback(this, &MobileSetupHandler::HandleGetDeviceInfo)); + dom_ui_->RegisterMessageCallback(kJsApiCloseTab, + NewCallback(this, &MobileSetupHandler::HandleCloseTab)); dom_ui_->RegisterMessageCallback(kJsApiSetTransactionStatus, NewCallback(this, &MobileSetupHandler::HandleSetTransactionStatus)); } -void MobileSetupHandler::HandleGetDeviceInfo(const ListValue* args) { - const size_t kGetDeviceInfoParamCount = 1; - if (args->GetSize() != kGetDeviceInfoParamCount) +void MobileSetupHandler::NetworkChanged(chromeos::NetworkLibrary* cros) { + if (!dom_ui_) return; - - // Get change callback function name. - string16 callback_func_name; - if (!args->GetString(0, &callback_func_name)) + DictionaryValue device; + GetDeviceInfo(&device); + std::string state, error; + if (!ShouldReportDeviceState(&state, &error)) return; - DictionaryValue value; - if (GetDeviceInfo(&value)) - dom_ui_->CallJavascriptFunction(UTF16ToWide(callback_func_name), value); + device.SetString("state", state); + if (error.length()) + device.SetString("error", error); + dom_ui_->CallJavascriptFunction( + kJsDeviceStatusChangedHandler, device); +} + +void MobileSetupHandler::HandleCloseTab(const ListValue* args) { + Browser* browser = BrowserList::GetLastActive(); + if (browser) + browser->CloseTabContents(tab_contents_); } void MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) { @@ -180,17 +320,110 @@ void MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) { 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()); - if (LowerCaseEqualsASCII(status, "OK") && network.StartActivation()) { + if (LowerCaseEqualsASCII(status, "OK")) { + network.StartActivation(); + } else { DictionaryValue value; - if (GetDeviceInfo(&value)) - dom_ui_->CallJavascriptFunction(kJsDeviceStatusChangedHandler, value); + value.SetString("state", kFailedPaymentError); + dom_ui_->CallJavascriptFunction(kJsDeviceStatusChangedHandler, value); } - // TODO(zelidrag): Close the setup tab automatically when payment fails? - // Pending UX decision on this one. } +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; + } + 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 (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; + } + + // We don't report states that we don't understand to DOM UI. + *state = kStateUnknown; + return false; +} + + +bool MobileSetupHandler::CheckForActivationError( + chromeos::CellularNetwork network, std::string* error) { + 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() == + chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) { + error_code = kErrorBadConnectionPartial; + } else if (network.activation_state() == + chromeos::ACTIVATION_STATE_ACTIVATED) { + if (network.roaming_state() == chromeos::ROAMING_STATE_HOME) { + error_code = kErrorBadConnectionActivated; + } else if (network.roaming_state() == chromeos::ROAMING_STATE_ROAMING) { + error_code = kErrorRoamingOnConnection; + } + } + got_error = true; + } else if (network.connection_state() == + chromeos::STATE_ACTIVATION_FAILURE) { + 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() == + chromeos::ACTIVATION_STATE_NOT_ACTIVATED) { + error_code = kErrorRoamingActivation; + } else if (network.activation_state() == + chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) { + error_code = kErrorRoamingPartiallyActivated; + } + } + got_error = true; + } + + if (got_error) + *error = GetErrorMessage(error_code); + + return !got_error; +} bool MobileSetupHandler::GetDeviceInfo(DictionaryValue* value) { DCHECK(value); @@ -199,14 +432,13 @@ bool MobileSetupHandler::GetDeviceInfo(DictionaryValue* value) { const chromeos::CellularNetworkVector& cell_networks = network_lib->cellular_networks(); - if (!cell_networks.size()) + if (!cell_networks.size()) { return false; + } const chromeos::CellularNetwork& network = *(cell_networks.begin()); - value->SetString("carrier", UTF8ToUTF16(network.name())); value->SetString("payment_url", UTF8ToUTF16(network.payment_url())); - value->SetInteger("activation_state", network.activation_state()); value->SetString("MEID", UTF8ToUTF16(network.meid())); value->SetString("IMEI", UTF8ToUTF16(network.imei())); value->SetString("IMSI", UTF8ToUTF16(network.imsi())); @@ -215,6 +447,34 @@ bool MobileSetupHandler::GetDeviceInfo(DictionaryValue* value) { return true; } +std::string MobileSetupHandler::GetErrorMessage(const std::string& code) { + if (!cellular_config_.get()) + return ""; + return cellular_config_->GetErrorMessage(code); +} + +void MobileSetupHandler::LoadCellularConfig() { + static bool config_loaded = false; + if (config_loaded) + return; + config_loaded = true; + // Load partner customization startup manifest if it is available. + FilePath config_path(kCellularConfigPath); + if (file_util::PathExists(config_path)) { + scoped_ptr<CellularConfigDocument> config(new CellularConfigDocument()); + bool config_loaded = config->LoadFromFile(config_path); + if (config_loaded) { + LOG(INFO) << "Cellular config file loaded: " << kCellularConfigPath; + // lock + cellular_config_.reset(config.release()); + } else { + LOG(ERROR) << "Error loading cellular config file: " << + kCellularConfigPath; + } + } +} + + //////////////////////////////////////////////////////////////////////////////// // // MobileSetupUI @@ -224,7 +484,7 @@ bool MobileSetupHandler::GetDeviceInfo(DictionaryValue* value) { MobileSetupUI::MobileSetupUI(TabContents* contents) : DOMUI(contents){ MobileSetupHandler* handler = new MobileSetupHandler(); AddMessageHandler((handler)->Attach(this)); - handler->Init(); + handler->Init(contents); MobileSetupUIHTMLSource* html_source = new MobileSetupUIHTMLSource(); // Set up the chrome://mobilesetup/ source. |