summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 01:18:09 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 01:18:09 +0000
commitb2e87adc76ba5044838c70bc6d97975c2ef09119 (patch)
treed0cc2418adfe38340211e50ecc7c6e813254d0ab /chrome/browser
parent68074500d44d19ffd03779c8073c9dfad118f14a (diff)
downloadchromium_src-b2e87adc76ba5044838c70bc6d97975c2ef09119.zip
chromium_src-b2e87adc76ba5044838c70bc6d97975c2ef09119.tar.gz
chromium_src-b2e87adc76ba5044838c70bc6d97975c2ef09119.tar.bz2
Refactored mobile activation engine outside of WebUI handler in order to expose its state to other layer of UI (i.e. dialog, background activation process...).
BUG=130420 TEST=manual regression test for mobile device activation Review URL: https://chromiumcodereview.appspot.com/10456045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140686 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/chromeos/cros/network_library_impl_stub.cc4
-rw-r--r--chrome/browser/chromeos/mobile/mobile_activator.cc1089
-rw-r--r--chrome/browser/chromeos/mobile/mobile_activator.h246
-rw-r--r--chrome/browser/chromeos/network_message_observer.cc18
-rw-r--r--chrome/browser/chromeos/network_message_observer.h6
-rw-r--r--chrome/browser/chromeos/offline/offline_load_page.cc2
-rw-r--r--chrome/browser/chromeos/status/network_menu.cc3
-rw-r--r--chrome/browser/resources/options2/chromeos/internet_detail.js12
-rw-r--r--chrome/browser/ui/views/ash/chrome_shell_delegate.cc8
-rw-r--r--chrome/browser/ui/views/ash/chrome_shell_delegate.h2
-rw-r--r--chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc49
-rw-r--r--chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h2
-rw-r--r--chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc1232
-rw-r--r--chrome/browser/ui/webui/options2/chromeos/internet_options_handler2.cc10
14 files changed, 1473 insertions, 1210 deletions
diff --git a/chrome/browser/chromeos/cros/network_library_impl_stub.cc b/chrome/browser/chromeos/cros/network_library_impl_stub.cc
index 660b5b5..90030b4 100644
--- a/chrome/browser/chromeos/cros/network_library_impl_stub.cc
+++ b/chrome/browser/chromeos/cros/network_library_impl_stub.cc
@@ -170,12 +170,14 @@ void NetworkLibraryImplStub::Init() {
cellular1->set_network_technology(NETWORK_TECHNOLOGY_EVDO);
AddStubNetwork(cellular1, PROFILE_NONE);
- CellularNetwork* cellular2 = new CellularNetwork("cellular2");
+ CellularNetwork* cellular2 = new CellularNetwork("/cellular2");
cellular2->set_name("Fake Cellular 2");
cellular2->set_strength(50);
cellular2->set_activation_state(ACTIVATION_STATE_NOT_ACTIVATED);
cellular2->set_network_technology(NETWORK_TECHNOLOGY_UMTS);
cellular2->set_roaming_state(ROAMING_STATE_ROAMING);
+ cellular2->set_payment_url(std::string("http://www.google.com"));
+ cellular2->set_usage_url(std::string("http://www.google.com"));
AddStubNetwork(cellular2, PROFILE_NONE);
CellularNetwork* cellular3 = new CellularNetwork("cellular3");
diff --git a/chrome/browser/chromeos/mobile/mobile_activator.cc b/chrome/browser/chromeos/mobile/mobile_activator.cc
new file mode 100644
index 0000000..ade7d3a
--- /dev/null
+++ b/chrome/browser/chromeos/mobile/mobile_activator.cc
@@ -0,0 +1,1089 @@
+// Copyright (c) 2012 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/mobile/mobile_activator.h"
+
+#include <algorithm>
+#include <map>
+#include <string>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/file_util.h"
+#include "base/json/json_reader.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/message_loop.h"
+#include "base/metrics/histogram.h"
+#include "base/observer_list_threadsafe.h"
+#include "base/string_piece.h"
+#include "base/string_util.h"
+#include "base/timer.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.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/prefs/pref_service.h"
+#include "chrome/common/pref_names.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace {
+
+// 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";
+
+// Number of times we will retry to restart the activation process in case
+// there is no connectivity in the restricted pool.
+const int kMaxActivationAttempt = 3;
+// Number of times we will retry to reconnect if connection fails.
+const int kMaxConnectionRetry = 10;
+// Number of times we will retry to reconnect and reload payment portal page.
+const int kMaxPortalReconnectCount = 5;
+// Number of times we will retry to reconnect if connection fails.
+const int kMaxConnectionRetryOTASP = 30;
+// Number of times we will retry to reconnect after payment is processed.
+const int kMaxReconnectAttemptOTASP = 30;
+// Reconnect retry delay (after payment is processed).
+const int kPostPaymentReconnectDelayMS = 30000; // 30s.
+// Connection timeout in seconds.
+const int kConnectionTimeoutSeconds = 45;
+// Reconnect delay.
+const int kReconnectDelayMS = 3000;
+// Reconnect timer delay.
+const int kReconnectTimerDelayMS = 5000;
+// Reconnect delay after previous failure.
+const int kFailedReconnectDelayMS = 10000;
+// Retry delay after failed OTASP attempt.
+const int kOTASPRetryDelay = 20000;
+
+// 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 kErrorDisabled[] = "disabled";
+const char kErrorNoDevice[] = "no_device";
+const char kFailedPaymentError[] = "failed_payment";
+const char kFailedConnectivity[] = "connectivity";
+
+} // namespace
+
+namespace chromeos {
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// CellularConfigDocument
+//
+////////////////////////////////////////////////////////////////////////////////
+CellularConfigDocument::CellularConfigDocument() {
+}
+
+CellularConfigDocument::~CellularConfigDocument() {
+}
+
+std::string CellularConfigDocument::GetErrorMessage(const std::string& code) {
+ base::AutoLock create(config_lock_);
+ ErrorMap::iterator iter = error_map_.find(code);
+ if (iter == error_map_.end())
+ return code;
+ return iter->second;
+}
+
+void CellularConfigDocument::LoadCellularConfigFile() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ // Load partner customization startup manifest if it is available.
+ FilePath config_path(kCellularConfigPath);
+ if (!file_util::PathExists(config_path))
+ return;
+
+ if (LoadFromFile(config_path)) {
+ DVLOG(1) << "Cellular config file loaded: " << kCellularConfigPath;
+ } else {
+ LOG(ERROR) << "Error loading cellular config file: " <<
+ kCellularConfigPath;
+ }
+}
+
+bool CellularConfigDocument::LoadFromFile(const FilePath& config_path) {
+ std::string config;
+ if (!file_util::ReadFileToString(config_path, &config))
+ return false;
+
+ scoped_ptr<Value> root(
+ base::JSONReader::Read(config, base::JSON_ALLOW_TRAILING_COMMAS));
+ DCHECK(root.get() != NULL);
+ if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
+ LOG(WARNING) << "Bad cellular config file";
+ return false;
+ }
+
+ DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());
+ if (!root_dict->GetString(kVersionField, &version_)) {
+ LOG(WARNING) << "Cellular config file missing version";
+ return false;
+ }
+ ErrorMap error_map;
+ 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(WARNING) << "Bad cellular config error value";
+ return false;
+ }
+ error_map.insert(ErrorMap::value_type(*keys, value));
+ }
+ SetErrorMap(error_map);
+ return true;
+}
+
+void CellularConfigDocument::SetErrorMap(
+ const ErrorMap& map) {
+ base::AutoLock create(config_lock_);
+ error_map_.clear();
+ error_map_.insert(map.begin(), map.end());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// MobileActivator
+//
+////////////////////////////////////////////////////////////////////////////////
+MobileActivator::MobileActivator()
+ : cellular_config_(new CellularConfigDocument()),
+ state_(PLAN_ACTIVATION_PAGE_LOADING),
+ reenable_wifi_(false),
+ reenable_ethernet_(false),
+ reenable_cert_check_(false),
+ evaluating_(false),
+ terminated_(true),
+ connection_retry_count_(0),
+ reconnect_wait_count_(0),
+ payment_reconnect_count_(0),
+ activation_attempt_(0) {
+}
+
+MobileActivator::~MobileActivator() {
+ TerminateActivation();
+}
+
+MobileActivator* MobileActivator::GetInstance() {
+ return Singleton<MobileActivator>::get();
+}
+
+void MobileActivator::TerminateActivation() {
+ reconnect_timer_.Stop();
+ NetworkLibrary* lib =
+ CrosLibrary::Get()->GetNetworkLibrary();
+ lib->RemoveNetworkManagerObserver(this);
+ lib->RemoveObserverForAllNetworks(this);
+ if (lib->IsLocked())
+ lib->Unlock();
+ ReEnableOtherConnections();
+ meid_.clear();
+ service_path_.clear();
+ state_ = PLAN_ACTIVATION_PAGE_LOADING;
+ reconnect_wait_count_ = 0;
+ evaluating_ = false;
+ reenable_wifi_ = false;
+ reenable_ethernet_ = false;
+ reenable_cert_check_ = false;
+ terminated_ = true;
+ cellular_config_ = NULL;
+}
+
+void MobileActivator::OnNetworkManagerChanged(NetworkLibrary* cros) {
+ if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
+ return;
+ EvaluateCellularNetwork(FindCellularNetworkByMeid(meid_, true));
+}
+
+void MobileActivator::OnNetworkChanged(NetworkLibrary* cros,
+ const Network* network) {
+ if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
+ return;
+
+ if (!network || network->type() != TYPE_CELLULAR) {
+ NOTREACHED();
+ return;
+ }
+
+ EvaluateCellularNetwork(
+ static_cast<CellularNetwork*>(const_cast<Network*>(network)));
+}
+
+void MobileActivator::AddObserver(MobileActivator::Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void MobileActivator::RemoveObserver(MobileActivator::Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+void MobileActivator::InitiateActivation(const std::string& service_path) {
+ NetworkLibrary* lib = CrosLibrary::Get()->GetNetworkLibrary();
+ CellularNetwork* network = lib->FindCellularNetworkByPath(service_path);
+ if (!network) {
+ LOG(ERROR) << "Cellular service can't be found: " << service_path;
+ return;
+ }
+
+ const chromeos::NetworkDevice* device =
+ lib->FindNetworkDeviceByPath(network->device_path());
+ if (!device) {
+ LOG(ERROR) << "Cellular device can't be found: " << network->device_path();
+ return;
+ }
+
+ terminated_ = false;
+ meid_ = device->meid();
+ service_path_ = service_path;
+ BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&CellularConfigDocument::LoadCellularConfigFile,
+ cellular_config_.get()),
+ base::Bind(&MobileActivator::ContinueActivation, AsWeakPtr()));
+}
+
+void MobileActivator::ContinueActivation() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ CellularNetwork* network = FindCellularNetworkByMeid(meid_, false);
+ if (!network || !network->SupportsActivation())
+ return;
+
+ DCHECK(!CrosLibrary::Get()->GetNetworkLibrary()->IsLocked());
+ SetupActivationProcess(network);
+
+ StartActivation();
+}
+
+void MobileActivator::OnSetTransactionStatus(bool success) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&MobileActivator::SetTransactionStatus,
+ AsWeakPtr(), success));
+}
+
+void MobileActivator::OnPortalLoaded(bool success) {
+ CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
+ if (!network) {
+ ChangeState(NULL, PLAN_ACTIVATION_ERROR,
+ GetErrorMessage(kErrorNoService));
+ return;
+ }
+ if (state_ == PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING ||
+ state_ == PLAN_ACTIVATION_SHOWING_PAYMENT) {
+ if (success) {
+ payment_reconnect_count_ = 0;
+ ChangeState(network, PLAN_ACTIVATION_SHOWING_PAYMENT, std::string());
+ } else {
+ payment_reconnect_count_++;
+ if (payment_reconnect_count_ > kMaxPortalReconnectCount) {
+ ChangeState(NULL, PLAN_ACTIVATION_ERROR,
+ GetErrorMessage(kErrorNoService));
+ return;
+ }
+ // Disconnect now, this should force reconnection and we will retry to
+ // load the frame containing payment portal again.
+ DisconnectFromNetwork(network);
+ }
+ } else {
+ NOTREACHED() << "Called paymentPortalLoad while in unexpected state: "
+ << GetStateDescription(state_);
+ }
+}
+
+CellularNetwork* MobileActivator::FindCellularNetworkByMeid(
+ const std::string& meid, bool reattach_observer) {
+ NetworkLibrary* lib = CrosLibrary::Get()->GetNetworkLibrary();
+ for (CellularNetworkVector::const_iterator it =
+ lib->cellular_networks().begin();
+ it != lib->cellular_networks().end(); ++it) {
+ const chromeos::NetworkDevice* device =
+ lib->FindNetworkDeviceByPath((*it)->device_path());
+ if (device && meid == device->meid()) {
+ CellularNetwork* network = *it;
+ // If service path has changed, reattach the event observer for this
+ // network service.
+ if (reattach_observer && service_path_ != network->service_path()) {
+ lib->RemoveObserverForAllNetworks(this);
+ lib->AddNetworkObserver(network->service_path(), this);
+ service_path_ = network->service_path();
+ }
+ return network;
+ }
+ }
+ return NULL;
+}
+
+void MobileActivator::StartActivation() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ UMA_HISTOGRAM_COUNTS("Cellular.MobileSetupStart", 1);
+ NetworkLibrary* lib =
+ CrosLibrary::Get()->GetNetworkLibrary();
+ CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
+ // Check if we can start activation process.
+ if (!network) {
+ std::string error;
+ if (!lib->cellular_available())
+ error = kErrorNoDevice;
+ else if (!lib->cellular_enabled())
+ error = kErrorDisabled;
+ else
+ error = kErrorNoService;
+ ChangeState(NULL, PLAN_ACTIVATION_ERROR, GetErrorMessage(error));
+ return;
+ }
+
+ // Start monitoring network property changes.
+ lib->AddNetworkManagerObserver(this);
+ lib->RemoveObserverForAllNetworks(this);
+ lib->AddNetworkObserver(network->service_path(), this);
+ // Try to start with OTASP immediately if we have received payment recently.
+ state_ = lib->HasRecentCellularPlanPayment() ?
+ PLAN_ACTIVATION_START_OTASP :
+ PLAN_ACTIVATION_START;
+ EvaluateCellularNetwork(network);
+}
+
+void MobileActivator::RetryOTASP() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(state_ == PLAN_ACTIVATION_DELAY_OTASP);
+ StartOTASP();
+}
+
+void MobileActivator::ContinueConnecting(int delay) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
+ if (network && network->connecting_or_connected()) {
+ EvaluateCellularNetwork(network);
+ } else {
+ ConnectToNetwork(network, delay);
+ }
+}
+
+void MobileActivator::SetTransactionStatus(bool success) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // The payment is received, try to reconnect and check the status all over
+ // again.
+ if (success && state_ == PLAN_ACTIVATION_SHOWING_PAYMENT) {
+ NetworkLibrary* lib =
+ CrosLibrary::Get()->GetNetworkLibrary();
+ lib->SignalCellularPlanPayment();
+ UMA_HISTOGRAM_COUNTS("Cellular.PaymentReceived", 1);
+ StartOTASP();
+ } else {
+ UMA_HISTOGRAM_COUNTS("Cellular.PaymentFailed", 1);
+ }
+}
+
+void MobileActivator::StartOTASP() {
+ state_ = PLAN_ACTIVATION_START_OTASP;
+ CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
+ if (network &&
+ network->connected() &&
+ network->activation_state() == ACTIVATION_STATE_ACTIVATED) {
+ CrosLibrary::Get()->GetNetworkLibrary()->
+ DisconnectFromNetwork(network);
+ } else {
+ EvaluateCellularNetwork(network);
+ }
+}
+
+void MobileActivator::ReconnectTimerFired() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Permit network connection changes only in reconnecting states.
+ if (state_ != PLAN_ACTIVATION_RECONNECTING_OTASP_TRY &&
+ state_ != PLAN_ACTIVATION_RECONNECTING &&
+ state_ != PLAN_ACTIVATION_RECONNECTING_PAYMENT &&
+ state_ != PLAN_ACTIVATION_RECONNECTING_OTASP)
+ return;
+ CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
+ if (!network) {
+ // No service, try again since this is probably just transient condition.
+ LOG(WARNING) << "Service not present at reconnect attempt.";
+ }
+ EvaluateCellularNetwork(network);
+}
+
+void MobileActivator::DisconnectFromNetwork(CellularNetwork* network) {
+ DCHECK(network);
+ LOG(INFO) << "Disconnecting from: " << network->service_path();
+ CrosLibrary::Get()->GetNetworkLibrary()->
+ DisconnectFromNetwork(network);
+ // Disconnect will force networks to be reevaluated, so
+ // we don't want to continue processing on this path anymore.
+ evaluating_ = false;
+}
+
+bool MobileActivator::NeedsReconnecting(CellularNetwork* network,
+ PlanActivationState* new_state,
+ std::string* error_description) {
+ DCHECK(network);
+ if (!network->failed() && !ConnectionTimeout())
+ return false;
+
+ // Try to reconnect again if reconnect failed, or if for some
+ // reasons we are still not connected after 45 seconds.
+ int max_retries = (state_ == PLAN_ACTIVATION_RECONNECTING_OTASP) ?
+ kMaxConnectionRetryOTASP : kMaxConnectionRetry;
+ if (connection_retry_count_ < max_retries) {
+ UMA_HISTOGRAM_COUNTS("Cellular.ConnectionRetry", 1);
+ ConnectToNetwork(network, kFailedReconnectDelayMS);
+ return true;
+ }
+ // We simply can't connect anymore after all these tries.
+ UMA_HISTOGRAM_COUNTS("Cellular.ConnectionFailed", 1);
+ *new_state = PLAN_ACTIVATION_ERROR;
+ *error_description = GetErrorMessage(kFailedConnectivity);
+ return false;
+}
+
+bool MobileActivator::ConnectToNetwork(CellularNetwork* network, int delay) {
+ if (network && network->connecting_or_connected())
+ return true;
+ // Permit network connection changes only in reconnecting states.
+ if (state_ != PLAN_ACTIVATION_RECONNECTING_OTASP_TRY &&
+ state_ != PLAN_ACTIVATION_RECONNECTING &&
+ state_ != PLAN_ACTIVATION_RECONNECTING_PAYMENT &&
+ state_ != PLAN_ACTIVATION_RECONNECTING_OTASP) return false;
+ if (network)
+ LOG(INFO) << "Connecting to: " << network->service_path();
+ connection_retry_count_++;
+ connection_start_time_ = base::Time::Now();
+ if (!network || state_ == PLAN_ACTIVATION_RECONNECTING_OTASP) {
+ LOG(WARNING) << "Delaying reconnect to "
+ << (network ? network->service_path().c_str() : "no service");
+ // If we coudn't connect during reconnection phase, try to reconnect
+ // with a delay (and try to reconnect if needed).
+ BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&MobileActivator::ContinueConnecting, AsWeakPtr(), delay),
+ base::TimeDelta::FromMilliseconds(delay));
+ return false;
+ }
+ CrosLibrary::Get()->GetNetworkLibrary()->
+ ConnectToCellularNetwork(network);
+ return true;
+}
+
+void MobileActivator::ForceReconnect(CellularNetwork* network, int delay) {
+ DCHECK(network);
+ UMA_HISTOGRAM_COUNTS("Cellular.ActivationRetry", 1);
+ // Reset reconnect metrics.
+ connection_retry_count_ = 0;
+ connection_start_time_ = base::Time();
+ // First, disconnect...
+ LOG(INFO) << "Disconnecting from " << network->service_path();
+ CrosLibrary::Get()->GetNetworkLibrary()->
+ DisconnectFromNetwork(network);
+ // Check the network state 3s after we disconnect to make sure.
+ BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&MobileActivator::ContinueConnecting, AsWeakPtr(), delay),
+ base::TimeDelta::FromMilliseconds(delay));
+}
+
+bool MobileActivator::ConnectionTimeout() {
+ return (base::Time::Now() -
+ connection_start_time_).InSeconds() > kConnectionTimeoutSeconds;
+}
+
+void MobileActivator::EvaluateCellularNetwork(CellularNetwork* network) {
+ if (terminated_)
+ return;
+
+ PlanActivationState new_state = state_;
+ if (!network) {
+ LOG(WARNING) << "Cellular service lost";
+ if (state_ == PLAN_ACTIVATION_RECONNECTING_OTASP_TRY ||
+ state_ == PLAN_ACTIVATION_RECONNECTING ||
+ state_ == PLAN_ACTIVATION_RECONNECTING_PAYMENT ||
+ state_ == PLAN_ACTIVATION_RECONNECTING_OTASP) {
+ // This might be the legit case when service is lost after activation.
+ // We need to make sure we force reconnection as soon as it shows up.
+ LOG(INFO) << "Force service reconnection";
+ connection_start_time_ = base::Time();
+ }
+ return;
+ }
+
+ // Prevent this method from being called if it is already on the stack.
+ // This might happen on some state transitions (ie. connect, disconnect).
+ if (evaluating_)
+ return;
+ evaluating_ = true;
+ std::string error_description;
+
+ LOG(WARNING) << "Cellular:\n service=" << network->GetStateString().c_str()
+ << "\n ui=" << GetStateDescription(state_)
+ << "\n activation=" << network->GetActivationStateString().c_str()
+ << "\n error=" << network->GetErrorString().c_str()
+ << "\n setvice_path=" << network->service_path().c_str();
+ switch (state_) {
+ case PLAN_ACTIVATION_START: {
+ switch (network->activation_state()) {
+ case ACTIVATION_STATE_ACTIVATED: {
+ if (network->disconnected()) {
+ new_state = PLAN_ACTIVATION_RECONNECTING;
+ } else if (network->connected()) {
+ if (network->restricted_pool()) {
+ new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
+ } else {
+ new_state = PLAN_ACTIVATION_DONE;
+ }
+ }
+ break;
+ }
+ default: {
+ if (network->disconnected() ||
+ network->state() == STATE_ACTIVATION_FAILURE) {
+ new_state = (network->activation_state() ==
+ ACTIVATION_STATE_PARTIALLY_ACTIVATED) ?
+ PLAN_ACTIVATION_TRYING_OTASP :
+ PLAN_ACTIVATION_INITIATING_ACTIVATION;
+ } else if (network->connected()) {
+ DisconnectFromNetwork(network);
+ return;
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case PLAN_ACTIVATION_START_OTASP: {
+ switch (network->activation_state()) {
+ case ACTIVATION_STATE_PARTIALLY_ACTIVATED: {
+ if (network->disconnected()) {
+ new_state = PLAN_ACTIVATION_OTASP;
+ } else if (network->connected()) {
+ DisconnectFromNetwork(network);
+ return;
+ }
+ break;
+ }
+ case ACTIVATION_STATE_ACTIVATED:
+ new_state = PLAN_ACTIVATION_RECONNECTING_OTASP;
+ break;
+ default: {
+ LOG(WARNING) << "Unexpected activation state for device "
+ << network->service_path().c_str();
+ break;
+ }
+ }
+ break;
+ }
+ case PLAN_ACTIVATION_DELAY_OTASP:
+ // Just ignore any changes until the OTASP retry timer kicks in.
+ evaluating_ = false;
+ return;
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION: {
+ switch (network->activation_state()) {
+ case ACTIVATION_STATE_ACTIVATED:
+ case ACTIVATION_STATE_PARTIALLY_ACTIVATED:
+ new_state = PLAN_ACTIVATION_START;
+ break;
+ case ACTIVATION_STATE_NOT_ACTIVATED:
+ case ACTIVATION_STATE_ACTIVATING:
+ // Wait in this state until activation state changes.
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case PLAN_ACTIVATION_OTASP:
+ case PLAN_ACTIVATION_TRYING_OTASP: {
+ switch (network->activation_state()) {
+ case ACTIVATION_STATE_ACTIVATED:
+ if (network->disconnected()) {
+ new_state = GetNextReconnectState(state_);
+ } else if (network->connected()) {
+ if (network->restricted_pool()) {
+ new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
+ } else {
+ new_state = PLAN_ACTIVATION_DONE;
+ }
+ }
+ break;
+ case ACTIVATION_STATE_PARTIALLY_ACTIVATED:
+ if (network->connected()) {
+ if (network->restricted_pool())
+ new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
+ } else {
+ new_state = GetNextReconnectState(state_);
+ }
+ break;
+ case ACTIVATION_STATE_NOT_ACTIVATED:
+ case ACTIVATION_STATE_ACTIVATING:
+ // Wait in this state until activation state changes.
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
+ case PLAN_ACTIVATION_RECONNECTING_PAYMENT:
+ case PLAN_ACTIVATION_RECONNECTING: {
+ if (network->connected()) {
+ // Make sure other networks are not interfering with our detection of
+ // restricted pool.
+ DisableOtherNetworks();
+ // Wait until the service shows up and gets activated.
+ switch (network->activation_state()) {
+ case ACTIVATION_STATE_PARTIALLY_ACTIVATED:
+ case ACTIVATION_STATE_ACTIVATED:
+ if (network->restricted_pool()) {
+ if (network->error() == ERROR_DNS_LOOKUP_FAILED) {
+ LOG(WARNING) << "No connectivity for device "
+ << network->service_path().c_str();
+ // If we are connected but there is no connectivity at all,
+ // restart the whole process again.
+ if (activation_attempt_ < kMaxActivationAttempt) {
+ activation_attempt_++;
+ LOG(WARNING) << "Reconnect attempt #"
+ << activation_attempt_;
+ ForceReconnect(network, kFailedReconnectDelayMS);
+ evaluating_ = false;
+ return;
+ } else {
+ new_state = PLAN_ACTIVATION_ERROR;
+ UMA_HISTOGRAM_COUNTS("Cellular.ActivationRetryFailure", 1);
+ error_description = GetErrorMessage(kFailedConnectivity);
+ }
+ } else {
+ // If we have already received payment, don't show the payment
+ // page again. We should try to reconnect after some
+ // time instead.
+ new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
+ }
+ } else if (network->activation_state() ==
+ ACTIVATION_STATE_ACTIVATED) {
+ new_state = PLAN_ACTIVATION_DONE;
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (NeedsReconnecting(network, &new_state, &error_description)) {
+ evaluating_ = false;
+ return;
+ }
+ break;
+ }
+ case PLAN_ACTIVATION_RECONNECTING_OTASP: {
+ if (network->connected()) {
+ // Make sure other networks are not interfering with our detection of
+ // restricted pool.
+ DisableOtherNetworks();
+ // Wait until the service shows up and gets activated.
+ switch (network->activation_state()) {
+ case ACTIVATION_STATE_PARTIALLY_ACTIVATED:
+ case ACTIVATION_STATE_ACTIVATED:
+ if (network->restricted_pool()) {
+ LOG(WARNING) << "Still no connectivity after OTASP for device "
+ << network->service_path().c_str();
+ // If we have already received payment, don't show the payment
+ // page again. We should try to reconnect after some time instead.
+ if (reconnect_wait_count_ < kMaxReconnectAttemptOTASP) {
+ reconnect_wait_count_++;
+ LOG(WARNING) << "OTASP reconnect attempt #"
+ << reconnect_wait_count_;
+ ForceReconnect(network, kPostPaymentReconnectDelayMS);
+ evaluating_ = false;
+ return;
+ } else {
+ new_state = PLAN_ACTIVATION_ERROR;
+ UMA_HISTOGRAM_COUNTS("Cellular.PostPaymentConnectFailure", 1);
+ error_description = GetErrorMessage(kFailedConnectivity);
+ }
+ } else if (network->online()) {
+ new_state = PLAN_ACTIVATION_DONE;
+ }
+ break;
+ default:
+ break;
+ }
+ } else if (NeedsReconnecting(network, &new_state, &error_description)) {
+ evaluating_ = false;
+ return;
+ }
+ break;
+ }
+ case PLAN_ACTIVATION_PAGE_LOADING:
+ break;
+ // Just ignore all signals until the site confirms payment.
+ case PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
+ case PLAN_ACTIVATION_SHOWING_PAYMENT: {
+ if (network->disconnected())
+ new_state = PLAN_ACTIVATION_RECONNECTING_PAYMENT;
+ break;
+ }
+ // Activation completed/failed, ignore network changes.
+ case PLAN_ACTIVATION_DONE:
+ case PLAN_ACTIVATION_ERROR:
+ break;
+ }
+
+ if (new_state != PLAN_ACTIVATION_ERROR &&
+ GotActivationError(network, &error_description)) {
+ // Check for this special case when we try to do activate partially
+ // activated device. If that attempt failed, try to disconnect to clear the
+ // state and reconnect again.
+ if ((network->activation_state() ==
+ ACTIVATION_STATE_PARTIALLY_ACTIVATED ||
+ network->activation_state() == ACTIVATION_STATE_ACTIVATING) &&
+ (network->error() == ERROR_NO_ERROR ||
+ network->error() == ERROR_OTASP_FAILED) &&
+ network->state() == STATE_ACTIVATION_FAILURE) {
+ LOG(WARNING) << "Activation failure detected "
+ << network->service_path().c_str();
+ switch (state_) {
+ case PLAN_ACTIVATION_OTASP:
+ case PLAN_ACTIVATION_RECONNECTING_OTASP:
+ new_state = PLAN_ACTIVATION_DELAY_OTASP;
+ break;
+ case PLAN_ACTIVATION_TRYING_OTASP:
+ new_state = PLAN_ACTIVATION_RECONNECTING_OTASP_TRY;
+ break;
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ new_state = PLAN_ACTIVATION_RECONNECTING;
+ break;
+ case PLAN_ACTIVATION_START:
+ // We are just starting, so this must be previous activation attempt
+ // failure.
+ new_state = PLAN_ACTIVATION_TRYING_OTASP;
+ break;
+ case PLAN_ACTIVATION_DELAY_OTASP:
+ case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
+ case PLAN_ACTIVATION_RECONNECTING:
+ new_state = state_;
+ break;
+ default:
+ new_state = PLAN_ACTIVATION_ERROR;
+ break;
+ }
+ } else {
+ LOG(WARNING) << "Unexpected activation failure for "
+ << network->service_path().c_str();
+ new_state = PLAN_ACTIVATION_ERROR;
+ }
+ }
+
+ if (new_state == PLAN_ACTIVATION_ERROR && !error_description.length())
+ error_description = GetErrorMessage(kErrorDefault);
+
+ ChangeState(network, new_state, error_description);
+ evaluating_ = false;
+}
+
+MobileActivator::PlanActivationState MobileActivator::GetNextReconnectState(
+ MobileActivator::PlanActivationState state) {
+ switch (state) {
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ return PLAN_ACTIVATION_RECONNECTING;
+ case PLAN_ACTIVATION_OTASP:
+ return PLAN_ACTIVATION_RECONNECTING_OTASP;
+ case PLAN_ACTIVATION_TRYING_OTASP:
+ return PLAN_ACTIVATION_RECONNECTING_OTASP_TRY;
+ default:
+ return PLAN_ACTIVATION_RECONNECTING;
+ }
+}
+
+// Debugging helper function, will take it out at the end.
+const char* MobileActivator::GetStateDescription(PlanActivationState state) {
+ switch (state) {
+ case PLAN_ACTIVATION_PAGE_LOADING:
+ return "PAGE_LOADING";
+ case PLAN_ACTIVATION_START:
+ return "ACTIVATION_START";
+ case PLAN_ACTIVATION_TRYING_OTASP:
+ return "TRYING_OTASP";
+ case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
+ return "RECONNECTING_OTASP_TRY";
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ return "INITIATING_ACTIVATION";
+ case PLAN_ACTIVATION_RECONNECTING:
+ return "RECONNECTING";
+ case PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
+ return "PAYMENT_PORTAL_LOADING";
+ case PLAN_ACTIVATION_SHOWING_PAYMENT:
+ return "SHOWING_PAYMENT";
+ case PLAN_ACTIVATION_RECONNECTING_PAYMENT:
+ return "RECONNECTING_PAYMENT";
+ case PLAN_ACTIVATION_START_OTASP:
+ return "START_OTASP";
+ case PLAN_ACTIVATION_DELAY_OTASP:
+ return "DELAY_OTASP";
+ case PLAN_ACTIVATION_OTASP:
+ return "OTASP";
+ case PLAN_ACTIVATION_RECONNECTING_OTASP:
+ return "RECONNECTING_OTASP";
+ case PLAN_ACTIVATION_DONE:
+ return "DONE";
+ case PLAN_ACTIVATION_ERROR:
+ return "ERROR";
+ }
+ return "UNKNOWN";
+}
+
+
+void MobileActivator::CompleteActivation(
+ CellularNetwork* network) {
+ // Remove observers, we are done with this page.
+ NetworkLibrary* lib = CrosLibrary::Get()->
+ GetNetworkLibrary();
+ lib->RemoveNetworkManagerObserver(this);
+ lib->RemoveObserverForAllNetworks(this);
+ if (lib->IsLocked())
+ lib->Unlock();
+ // If we have successfully activated the connection, set autoconnect flag.
+ if (network)
+ network->SetAutoConnect(true);
+ // Reactivate other types of connections if we have
+ // shut them down previously.
+ ReEnableOtherConnections();
+}
+
+bool MobileActivator::RunningActivation() const {
+ return !(state_ == PLAN_ACTIVATION_DONE ||
+ state_ == PLAN_ACTIVATION_ERROR ||
+ state_ == PLAN_ACTIVATION_PAGE_LOADING);
+}
+
+void MobileActivator::ChangeState(CellularNetwork* network,
+ PlanActivationState new_state,
+ const std::string& error_description) {
+ static bool first_time = true;
+ if (state_ == new_state && !first_time)
+ return;
+ LOG(WARNING) << "Activation state flip old = "
+ << GetStateDescription(state_)
+ << ", new = " << GetStateDescription(new_state);
+ first_time = false;
+
+ // Pick action that should happen on leaving the old state.
+ switch (state_) {
+ case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
+ case PLAN_ACTIVATION_RECONNECTING:
+ case PLAN_ACTIVATION_RECONNECTING_OTASP:
+ if (reconnect_timer_.IsRunning()) {
+ reconnect_timer_.Stop();
+ }
+ break;
+ default:
+ break;
+ }
+ state_ = new_state;
+
+ // Signal to observers layer that the state is changing.
+ FOR_EACH_OBSERVER(Observer, observers_,
+ OnActivationStateChanged(network, state_, error_description));
+
+ // Pick action that should happen on entering the new state.
+ switch (new_state) {
+ case PLAN_ACTIVATION_START:
+ break;
+ case PLAN_ACTIVATION_DELAY_OTASP: {
+ UMA_HISTOGRAM_COUNTS("Cellular.RetryOTASP", 1);
+ BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&MobileActivator::RetryOTASP, AsWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kOTASPRetryDelay));
+ break;
+ }
+ case PLAN_ACTIVATION_INITIATING_ACTIVATION:
+ case PLAN_ACTIVATION_TRYING_OTASP:
+ case PLAN_ACTIVATION_OTASP:
+ DCHECK(network);
+ LOG(WARNING) << "Activating service " << network->service_path().c_str();
+ UMA_HISTOGRAM_COUNTS("Cellular.ActivationTry", 1);
+ if (!network->StartActivation()) {
+ UMA_HISTOGRAM_COUNTS("Cellular.ActivationFailure", 1);
+ if (new_state == PLAN_ACTIVATION_OTASP) {
+ ChangeState(network, PLAN_ACTIVATION_DELAY_OTASP, std::string());
+ } else {
+ ChangeState(network, PLAN_ACTIVATION_ERROR,
+ GetErrorMessage(kFailedConnectivity));
+ }
+ }
+ break;
+ case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
+ case PLAN_ACTIVATION_RECONNECTING:
+ case PLAN_ACTIVATION_RECONNECTING_PAYMENT:
+ case PLAN_ACTIVATION_RECONNECTING_OTASP: {
+ // Start reconnect timer. This will ensure that we are not left in
+ // limbo by the network library.
+ if (!reconnect_timer_.IsRunning()) {
+ reconnect_timer_.Start(
+ FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kReconnectTimerDelayMS),
+ this, &MobileActivator::ReconnectTimerFired);
+ }
+ // Reset connection metrics and try to connect.
+ reconnect_wait_count_ = 0;
+ connection_retry_count_ = 0;
+ connection_start_time_ = base::Time::Now();
+ ConnectToNetwork(network, kReconnectDelayMS);
+ break;
+ }
+ case PLAN_ACTIVATION_PAGE_LOADING:
+ return;
+ case PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
+ case PLAN_ACTIVATION_SHOWING_PAYMENT:
+ // Fix for fix SSL for the walled gardens where cert chain verification
+ // might not work.
+ break;
+ case PLAN_ACTIVATION_DONE:
+ DCHECK(network);
+ CompleteActivation(network);
+ UMA_HISTOGRAM_COUNTS("Cellular.MobileSetupSucceeded", 1);
+ break;
+ case PLAN_ACTIVATION_ERROR:
+ CompleteActivation(NULL);
+ UMA_HISTOGRAM_COUNTS("Cellular.PlanFailed", 1);
+ break;
+ default:
+ break;
+ }
+}
+
+void MobileActivator::ReEnableOtherConnections() {
+ NetworkLibrary* lib = CrosLibrary::Get()->GetNetworkLibrary();
+ if (reenable_ethernet_) {
+ reenable_ethernet_ = false;
+ lib->EnableEthernetNetworkDevice(true);
+ }
+ if (reenable_wifi_) {
+ reenable_wifi_ = false;
+ lib->EnableWifiNetworkDevice(true);
+ }
+
+ PrefService* prefs = g_browser_process->local_state();
+ if (reenable_cert_check_) {
+ prefs->SetBoolean(prefs::kCertRevocationCheckingEnabled,
+ true);
+ reenable_cert_check_ = false;
+ }
+}
+
+void MobileActivator::SetupActivationProcess(CellularNetwork* network) {
+ if (!network)
+ return;
+
+ // Disable SSL cert checks since we will be doing this in
+ // restricted pool.
+ PrefService* prefs = g_browser_process->local_state();
+ if (!reenable_cert_check_ &&
+ prefs->GetBoolean(
+ prefs::kCertRevocationCheckingEnabled)) {
+ reenable_cert_check_ = true;
+ prefs->SetBoolean(prefs::kCertRevocationCheckingEnabled, false);
+ }
+
+ NetworkLibrary* lib = CrosLibrary::Get()->
+ GetNetworkLibrary();
+ // Disable autoconnect to cellular network.
+ network->SetAutoConnect(false);
+
+ // Prevent any other network interference.
+ DisableOtherNetworks();
+ lib->Lock();
+}
+
+void MobileActivator::DisableOtherNetworks() {
+ NetworkLibrary* lib = CrosLibrary::Get()->GetNetworkLibrary();
+ // Disable ethernet and wifi.
+ if (lib->ethernet_enabled()) {
+ reenable_ethernet_ = true;
+ lib->EnableEthernetNetworkDevice(false);
+ }
+ if (lib->wifi_enabled()) {
+ reenable_wifi_ = true;
+ lib->EnableWifiNetworkDevice(false);
+ }
+}
+
+bool MobileActivator::GotActivationError(
+ CellularNetwork* network, std::string* error) {
+ DCHECK(network);
+ bool got_error = false;
+ const char* error_code = kErrorDefault;
+
+ // This is the magic for detection of errors in during activation process.
+ if (network->state() == STATE_FAILURE &&
+ network->error() == ERROR_AAA_FAILED) {
+ if (network->activation_state() ==
+ ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
+ error_code = kErrorBadConnectionPartial;
+ } else if (network->activation_state() ==
+ ACTIVATION_STATE_ACTIVATED) {
+ if (network->roaming_state() == ROAMING_STATE_HOME) {
+ error_code = kErrorBadConnectionActivated;
+ } else if (network->roaming_state() == ROAMING_STATE_ROAMING) {
+ error_code = kErrorRoamingOnConnection;
+ }
+ }
+ got_error = true;
+ } else if (network->state() == STATE_ACTIVATION_FAILURE) {
+ if (network->error() == ERROR_NEED_EVDO) {
+ if (network->activation_state() ==
+ ACTIVATION_STATE_PARTIALLY_ACTIVATED)
+ error_code = kErrorNoEVDO;
+ } else if (network->error() == ERROR_NEED_HOME_NETWORK) {
+ if (network->activation_state() ==
+ ACTIVATION_STATE_NOT_ACTIVATED) {
+ error_code = kErrorRoamingActivation;
+ } else if (network->activation_state() ==
+ ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
+ error_code = kErrorRoamingPartiallyActivated;
+ }
+ }
+ got_error = true;
+ }
+
+ if (got_error)
+ *error = GetErrorMessage(error_code);
+
+ return got_error;
+}
+
+void MobileActivator::GetDeviceInfo(CellularNetwork* network,
+ DictionaryValue* value) {
+ DCHECK(network);
+ NetworkLibrary* cros =
+ CrosLibrary::Get()->GetNetworkLibrary();
+ if (!cros)
+ return;
+ value->SetString("carrier", network->name());
+ value->SetString("payment_url", network->payment_url());
+ if (network->using_post() && network->post_data().length())
+ value->SetString("post_data", network->post_data());
+
+ const NetworkDevice* device =
+ cros->FindNetworkDeviceByPath(network->device_path());
+ if (device) {
+ value->SetString("MEID", device->meid());
+ value->SetString("IMEI", device->imei());
+ value->SetString("MDN", device->mdn());
+ }
+}
+
+std::string MobileActivator::GetErrorMessage(const std::string& code) {
+ return cellular_config_->GetErrorMessage(code);
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/mobile/mobile_activator.h b/chrome/browser/chromeos/mobile/mobile_activator.h
new file mode 100644
index 0000000..a69a2d6
--- /dev/null
+++ b/chrome/browser/chromeos/mobile/mobile_activator.h
@@ -0,0 +1,246 @@
+// Copyright (c) 2012 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_MOBILE_MOBILE_ACTIVATOR_H_
+#define CHROME_BROWSER_CHROMEOS_MOBILE_MOBILE_ACTIVATOR_H_
+#pragma once
+
+#include <map>
+#include <string>
+
+#include "base/file_path.h"
+#include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "chrome/browser/chromeos/cros/network_library.h"
+
+namespace chromeos {
+
+// Cellular plan config document.
+class CellularConfigDocument
+ : public base::RefCountedThreadSafe<CellularConfigDocument> {
+ public:
+ CellularConfigDocument();
+ virtual ~CellularConfigDocument();
+
+ // Return error message for a given code.
+ std::string GetErrorMessage(const std::string& code);
+ void LoadCellularConfigFile();
+ const std::string& version() { return version_; }
+
+ private:
+ typedef std::map<std::string, std::string> ErrorMap;
+
+ void SetErrorMap(const ErrorMap& map);
+ bool LoadFromFile(const FilePath& config_path);
+
+ std::string version_;
+ ErrorMap error_map_;
+ base::Lock config_lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(CellularConfigDocument);
+};
+
+// This class performs mobile plan activation process.
+class MobileActivator
+ : public NetworkLibrary::NetworkManagerObserver,
+ public NetworkLibrary::NetworkObserver,
+ public base::SupportsWeakPtr<MobileActivator> {
+ public:
+ // Activation state.
+ enum PlanActivationState {
+ // Activation WebUI page is loading, activation not started.
+ PLAN_ACTIVATION_PAGE_LOADING = -1,
+ // Activation process started.
+ PLAN_ACTIVATION_START = 0,
+ // Initial over the air activation attempt.
+ PLAN_ACTIVATION_TRYING_OTASP = 1,
+ // Reconnection after the initial activation attempt.
+ PLAN_ACTIVATION_RECONNECTING_OTASP_TRY = 2,
+ // Performing pre-activation process.
+ PLAN_ACTIVATION_INITIATING_ACTIVATION = 3,
+ // Reconnecting to network.
+ PLAN_ACTIVATION_RECONNECTING = 4,
+ // Loading payment portal page.
+ PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING = 5,
+ // Showing payment portal page.
+ PLAN_ACTIVATION_SHOWING_PAYMENT = 6,
+ // Reconnecting after successful plan payment.
+ PLAN_ACTIVATION_RECONNECTING_PAYMENT = 7,
+ // Delaying activation until payment portal catches up.
+ PLAN_ACTIVATION_DELAY_OTASP = 8,
+ // Starting post-payment activation attempt.
+ PLAN_ACTIVATION_START_OTASP = 9,
+ // Attempting activation.
+ PLAN_ACTIVATION_OTASP = 10,
+ // Reconnecting after activation attempt.
+ PLAN_ACTIVATION_RECONNECTING_OTASP = 11,
+ // Finished activation.
+ PLAN_ACTIVATION_DONE = 12,
+ // Error occured during activation process.
+ PLAN_ACTIVATION_ERROR = 0xFF,
+ };
+
+ // Activation process observer.
+ class Observer {
+ public:
+ // Signals activation |state| change for given |network|.
+ virtual void OnActivationStateChanged(
+ CellularNetwork* network,
+ PlanActivationState state,
+ const std::string& error_description) = 0;
+
+ protected:
+ Observer() {}
+ virtual ~Observer() {}
+ };
+
+ static MobileActivator* GetInstance();
+
+ // Add/remove activation process observer.
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ // Activation is in process.
+ bool RunningActivation() const;
+ // Activation state.
+ PlanActivationState state() const { return state_; }
+ // Initiates activation process.
+ void InitiateActivation(const std::string& service_path);
+ // Terminates activation process if already started.
+ void TerminateActivation();
+ // Process portal load attempt status.
+ void OnPortalLoaded(bool success);
+ // Process payment transaction status.
+ void OnSetTransactionStatus(bool success);
+
+ private:
+ friend struct DefaultSingletonTraits<MobileActivator>;
+
+ MobileActivator();
+ virtual ~MobileActivator();
+
+ // NetworkLibrary::NetworkManagerObserver overrides.
+ virtual void OnNetworkManagerChanged(NetworkLibrary* obj) OVERRIDE;
+ // NetworkLibrary::NetworkObserver overrides.
+ virtual void OnNetworkChanged(NetworkLibrary* obj,
+ const Network* network) OVERRIDE;
+
+ // Continue activation after inital setup (config load).
+ void ContinueActivation();
+ // Process payment transaction results.
+ void SetTransactionStatus(bool success);
+ // Starts activation.
+ void StartActivation();
+ // Retried OTASP.
+ void RetryOTASP();
+ // Continues activation process. This method is called after we disconnect
+ // due to detected connectivity issue to kick off reconnection.
+ void ContinueConnecting(int delay);
+
+ // Sends message to host registration page with system/user info data.
+ void SendDeviceInfo();
+
+ // Callback for when |reconnect_timer_| fires.
+ void ReconnectTimerFired();
+ // Starts OTASP process.
+ void StartOTASP();
+ // Checks if we need to reconnect due to failed connection attempt.
+ bool NeedsReconnecting(CellularNetwork* network,
+ PlanActivationState* new_state,
+ std::string* error_description);
+ // Disconnect from network.
+ void DisconnectFromNetwork(CellularNetwork* network);
+ // Connects to cellular network, resets connection timer.
+ bool ConnectToNetwork(CellularNetwork* network, int delay);
+ // Forces disconnect / reconnect when we detect portal connectivity issues.
+ void ForceReconnect(CellularNetwork* network, int delay);
+ // Reports connection timeout.
+ bool ConnectionTimeout();
+ // Verify the state of cellular network and modify internal state.
+ void EvaluateCellularNetwork(CellularNetwork* network);
+ // Check the current cellular network for error conditions.
+ bool GotActivationError(CellularNetwork* network,
+ std::string* error);
+ // Sends status updates to WebUI page.
+ void UpdatePage(CellularNetwork* network,
+ const std::string& error_description);
+ // Changes internal state.
+ void ChangeState(CellularNetwork* network,
+ PlanActivationState new_state,
+ const std::string& error_description);
+ // Prepares network devices for cellular activation process.
+ void SetupActivationProcess(CellularNetwork* network);
+ // Disables ethernet and wifi newtorks since they interefere with
+ // detection of restricted pool on cellular side.
+ void DisableOtherNetworks();
+ // Resets network devices after cellular activation process.
+ // |network| should be NULL if the activation process failed.
+ void CompleteActivation(CellularNetwork* network);
+ // Control routines for handling other types of connections during
+ // cellular activation.
+ void ReEnableOtherConnections();
+ // Return error message for a given code.
+ std::string GetErrorMessage(const std::string& code);
+
+ // Converts the currently active CellularNetwork device into a JS object.
+ static void GetDeviceInfo(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 Web UI.
+ static bool EvaluateCellularDeviceState(bool* report_status,
+ std::string* state,
+ std::string* error);
+ // Finds cellular network given device |meid|, reattach network change
+ // observer if |reattach_observer| flag is set.
+ CellularNetwork* FindCellularNetworkByMeid(const std::string& meid,
+ bool reattach_observer);
+
+ // Returns next reconnection state based on the current activation phase.
+ static PlanActivationState GetNextReconnectState(PlanActivationState state);
+ static const char* GetStateDescription(PlanActivationState state);
+
+ scoped_refptr<CellularConfigDocument> cellular_config_;
+ // Internal handler state.
+ PlanActivationState state_;
+ // MEID of cellular device to activate.
+ std::string meid_;
+ // Service path of network begin activated. Please note that the path can
+ // change during the activation process even though it is still representing
+ // the same service.
+ std::string service_path_;
+ // Flags that control if wifi and ethernet connection needs to be restored
+ // after the activation of cellular network.
+ bool reenable_wifi_;
+ bool reenable_ethernet_;
+ bool reenable_cert_check_;
+ bool evaluating_;
+ // True if we think that another tab is already running activation.
+ bool already_running_;
+ // True activation process had been terminated.
+ bool terminated_;
+ // Connection retry counter.
+ int connection_retry_count_;
+ // Post payment reconnect wait counters.
+ int reconnect_wait_count_;
+ // Payment portal reload/reconnect attempt count.
+ int payment_reconnect_count_;
+ // Activation retry attempt count;
+ int activation_attempt_;
+ // Connection start time.
+ base::Time connection_start_time_;
+ // Timer that monitors reconnection timeouts.
+ base::RepeatingTimer<MobileActivator> reconnect_timer_;
+
+ ObserverList<Observer> observers_;
+
+ DISALLOW_COPY_AND_ASSIGN(MobileActivator);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_MOBILE_MOBILE_ACTIVATOR_H_
diff --git a/chrome/browser/chromeos/network_message_observer.cc b/chrome/browser/chromeos/network_message_observer.cc
index 501ddb55..e659b77 100644
--- a/chrome/browser/chromeos/network_message_observer.cc
+++ b/chrome/browser/chromeos/network_message_observer.cc
@@ -175,8 +175,9 @@ bool NetworkMessageObserver::IsApplicableBackupPlan(
return has_data && will_apply;
}
-void NetworkMessageObserver::OpenMobileSetupPage(const ListValue* args) {
- ash::Shell::GetInstance()->delegate()->OpenMobileSetup();
+void NetworkMessageObserver::OpenMobileSetupPage(
+ const std::string& service_path, const ListValue* args) {
+ ash::Shell::GetInstance()->delegate()->OpenMobileSetup(service_path);
}
void NetworkMessageObserver::OpenMoreInfoPage(const ListValue* args) {
@@ -220,11 +221,14 @@ void NetworkMessageObserver::ShowNeedsPlanNotification(
IDS_NETWORK_NO_DATA_PLAN_MESSAGE,
UTF8ToUTF16(cellular->name())),
l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE),
- base::Bind(&NetworkMessageObserver::OpenMobileSetupPage, AsWeakPtr()),
+ base::Bind(&NetworkMessageObserver::OpenMobileSetupPage,
+ AsWeakPtr(),
+ cellular->service_path()),
false, false);
}
void NetworkMessageObserver::ShowNoDataNotification(
+ const CellularNetwork* cellular,
CellularDataPlanType plan_type) {
notification_low_data_->Hide(); // Hide previous low data notification.
string16 message = plan_type == CELLULAR_DATA_PLAN_UNLIMITED ?
@@ -233,7 +237,9 @@ void NetworkMessageObserver::ShowNoDataNotification(
ASCIIToUTF16("0"));
notification_no_data_->Show(message,
l10n_util::GetStringUTF16(IDS_NETWORK_PURCHASE_MORE_MESSAGE),
- base::Bind(&NetworkMessageObserver::OpenMobileSetupPage, AsWeakPtr()),
+ base::Bind(&NetworkMessageObserver::OpenMobileSetupPage,
+ AsWeakPtr(),
+ cellular->service_path()),
false, false);
}
@@ -325,7 +331,7 @@ void NetworkMessageObserver::OnCellularDataPlanChanged(NetworkLibrary* cros) {
// If previously, we had low data, we know that a plan was near expiring.
// In that case, because the plan disappeared, we assume that it expired.
if (cellular_data_left_ == CellularNetwork::DATA_LOW) {
- ShowNoDataNotification(cellular_data_plan_type_);
+ ShowNoDataNotification(cellular, cellular_data_plan_type_);
} else if (cellular->needs_new_plan()) {
ShowNeedsPlanNotification(cellular);
}
@@ -356,7 +362,7 @@ void NetworkMessageObserver::OnCellularDataPlanChanged(NetworkLibrary* cros) {
}
if (cellular->data_left() == CellularNetwork::DATA_NONE) {
- ShowNoDataNotification(current_plan->plan_type);
+ ShowNoDataNotification(cellular, current_plan->plan_type);
} else if (cellular->data_left() == CellularNetwork::DATA_VERY_LOW) {
// Only show low data notification if we transition to very low data
// and we are on the same plan. This is so that users don't get a
diff --git a/chrome/browser/chromeos/network_message_observer.h b/chrome/browser/chromeos/network_message_observer.h
index 53264b6..e340dd1 100644
--- a/chrome/browser/chromeos/network_message_observer.h
+++ b/chrome/browser/chromeos/network_message_observer.h
@@ -35,11 +35,13 @@ class NetworkMessageObserver
static bool IsApplicableBackupPlan(const CellularDataPlan* plan,
const CellularDataPlan* other_plan);
private:
- virtual void OpenMobileSetupPage(const base::ListValue* args);
+ virtual void OpenMobileSetupPage(const std::string& service_path,
+ const base::ListValue* args);
virtual void OpenMoreInfoPage(const base::ListValue* args);
virtual void InitNewPlan(const CellularDataPlan* plan);
virtual void ShowNeedsPlanNotification(const CellularNetwork* cellular);
- virtual void ShowNoDataNotification(CellularDataPlanType plan_type);
+ virtual void ShowNoDataNotification(const CellularNetwork* cellular,
+ CellularDataPlanType plan_type);
virtual void ShowLowDataNotification(const CellularDataPlan* plan);
// NetworkLibrary::NetworkManagerObserver implementation.
diff --git a/chrome/browser/chromeos/offline/offline_load_page.cc b/chrome/browser/chromeos/offline/offline_load_page.cc
index 59bcf8e..ab9ca2d 100644
--- a/chrome/browser/chromeos/offline/offline_load_page.cc
+++ b/chrome/browser/chromeos/offline/offline_load_page.cc
@@ -188,8 +188,6 @@ void OfflineLoadPage::CommandReceived(const std::string& cmd) {
interstitial_page_->DontProceed();
} else if (command == "open_network_settings") {
ash::Shell::GetInstance()->tray_delegate()->ShowNetworkSettings();
- } else if (command == "open_activate_broadband") {
- ash::Shell::GetInstance()->delegate()->OpenMobileSetup();
} else {
LOG(WARNING) << "Unknown command:" << cmd;
}
diff --git a/chrome/browser/chromeos/status/network_menu.cc b/chrome/browser/chromeos/status/network_menu.cc
index d73691f..cd47df5 100644
--- a/chrome/browser/chromeos/status/network_menu.cc
+++ b/chrome/browser/chromeos/status/network_menu.cc
@@ -95,7 +95,8 @@ void ActivateCellular(const chromeos::CellularNetwork* cellular) {
if (!chromeos::UserManager::Get()->IsSessionStarted())
return;
- ash::Shell::GetInstance()->delegate()->OpenMobileSetup();
+ ash::Shell::GetInstance()->delegate()->OpenMobileSetup(
+ cellular->service_path());
}
// Decides whether a network should be highlighted in the UI.
diff --git a/chrome/browser/resources/options2/chromeos/internet_detail.js b/chrome/browser/resources/options2/chromeos/internet_detail.js
index da131d5..3d71534 100644
--- a/chrome/browser/resources/options2/chromeos/internet_detail.js
+++ b/chrome/browser/resources/options2/chromeos/internet_detail.js
@@ -81,16 +81,16 @@ cr.define('options.internet', function() {
initializePage: function() {
OptionsPage.prototype.initializePage.call(this);
options.internet.CellularPlanElement.decorate($('plan-list'));
- this.initializePageContents_();
- this.showNetworkDetails_();
+ var params = parseQueryParams(window.location);
+ this.initializePageContents_(params);
+ this.showNetworkDetails_(params);
},
/**
* Auto-activates the network details dialog if network information
* is included in the URL.
*/
- showNetworkDetails_: function() {
- var params = parseQueryParams(window.location);
+ showNetworkDetails_: function(params) {
var servicePath = params.servicePath;
var networkType = params.networkType;
if (!servicePath || !servicePath.length ||
@@ -103,7 +103,7 @@ cr.define('options.internet', function() {
/**
* Initializes the contents of the page.
*/
- initializePageContents_: function() {
+ initializePageContents_: function(params) {
$('details-internet-dismiss').addEventListener('click', function(event) {
DetailsInternetPage.setDetails();
});
@@ -124,7 +124,7 @@ cr.define('options.internet', function() {
});
$('buyplan-details').addEventListener('click', function(event) {
- chrome.send('buyDataPlan');
+ chrome.send('buyDataPlan', [params.servicePath]);
OptionsPage.closeOverlay();
});
diff --git a/chrome/browser/ui/views/ash/chrome_shell_delegate.cc b/chrome/browser/ui/views/ash/chrome_shell_delegate.cc
index 0d4cea9..cf68170 100644
--- a/chrome/browser/ui/views/ash/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/views/ash/chrome_shell_delegate.cc
@@ -186,16 +186,18 @@ void ChromeShellDelegate::OpenCrosh() {
#endif
}
-void ChromeShellDelegate::OpenMobileSetup() {
+void ChromeShellDelegate::OpenMobileSetup(const std::string& service_path) {
#if defined(OS_CHROMEOS)
Browser* browser = browser::FindOrCreateTabbedBrowser(
ProfileManager::GetDefaultProfileOrOffTheRecord());
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableMobileSetupDialog)) {
- MobileSetupDialog::Show();
+ MobileSetupDialog::Show(service_path);
} else {
+ std::string url(chrome::kChromeUIMobileSetupURL);
+ url.append(service_path);
browser->OpenURL(
- content::OpenURLParams(GURL(chrome::kChromeUIMobileSetupURL),
+ content::OpenURLParams(GURL(url),
content::Referrer(),
NEW_FOREGROUND_TAB,
content::PAGE_TRANSITION_LINK,
diff --git a/chrome/browser/ui/views/ash/chrome_shell_delegate.h b/chrome/browser/ui/views/ash/chrome_shell_delegate.h
index ee0de4d..8d1c9a5 100644
--- a/chrome/browser/ui/views/ash/chrome_shell_delegate.h
+++ b/chrome/browser/ui/views/ash/chrome_shell_delegate.h
@@ -42,7 +42,7 @@ class ChromeShellDelegate : public ash::ShellDelegate,
virtual void Search() OVERRIDE;
virtual void OpenFileManager() OVERRIDE;
virtual void OpenCrosh() OVERRIDE;
- virtual void OpenMobileSetup() OVERRIDE;
+ virtual void OpenMobileSetup(const std::string& service_path) OVERRIDE;
virtual void RestoreTab() OVERRIDE;
virtual void ShowKeyboardOverlay() OVERRIDE;
virtual void ShowTaskManager() OVERRIDE;
diff --git a/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc
index 4217979..12e1adf 100644
--- a/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc
+++ b/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/memory/singleton.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/chromeos/mobile/mobile_activator.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_dialogs.h"
@@ -19,15 +20,18 @@
#include "ui/views/widget/widget.h"
#include "ui/web_dialogs/web_dialog_delegate.h"
+using chromeos::CellularNetwork;
+using chromeos::MobileActivator;
using content::BrowserThread;
using content::WebContents;
using content::WebUIMessageHandler;
using ui::WebDialogDelegate;
-class MobileSetupDialogDelegate : public WebDialogDelegate {
+class MobileSetupDialogDelegate : public WebDialogDelegate,
+ public MobileActivator::Observer {
public:
static MobileSetupDialogDelegate* GetInstance();
- void ShowDialog();
+ void ShowDialog(const std::string& service_path);
protected:
friend struct DefaultSingletonTraits<MobileSetupDialogDelegate>;
@@ -45,6 +49,9 @@ class MobileSetupDialogDelegate : public WebDialogDelegate {
std::vector<WebUIMessageHandler*>* handlers) const OVERRIDE;
virtual void GetDialogSize(gfx::Size* size) const OVERRIDE;
virtual std::string GetDialogArgs() const OVERRIDE;
+ virtual void OnDialogShown(
+ content::WebUI* webui,
+ content::RenderViewHost* render_view_host) OVERRIDE;
virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE;
virtual void OnCloseContents(WebContents* source,
bool* out_close_dialog) OVERRIDE;
@@ -52,16 +59,23 @@ class MobileSetupDialogDelegate : public WebDialogDelegate {
virtual bool HandleContextMenu(
const content::ContextMenuParams& params) OVERRIDE;
+ // MobileActivator::Observer overrides.
+ virtual void OnActivationStateChanged(
+ CellularNetwork* network,
+ MobileActivator::PlanActivationState state,
+ const std::string& error_description) OVERRIDE;
+
private:
gfx::NativeWindow dialog_window_;
-
+ // Cellular network service path.
+ std::string service_path_;
DISALLOW_COPY_AND_ASSIGN(MobileSetupDialogDelegate);
};
// static
-void MobileSetupDialog::Show() {
+void MobileSetupDialog::Show(const std::string& service_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- MobileSetupDialogDelegate::GetInstance()->ShowDialog();
+ MobileSetupDialogDelegate::GetInstance()->ShowDialog(service_path);
}
// static
@@ -74,9 +88,11 @@ MobileSetupDialogDelegate::MobileSetupDialogDelegate() : dialog_window_(NULL) {
}
MobileSetupDialogDelegate::~MobileSetupDialogDelegate() {
+ MobileActivator::GetInstance()->RemoveObserver(this);
}
-void MobileSetupDialogDelegate::ShowDialog() {
+void MobileSetupDialogDelegate::ShowDialog(const std::string& service_path) {
+ service_path_ = service_path;
dialog_window_ = browser::ShowWebDialog(
NULL,
ProfileManager::GetDefaultProfileOrOffTheRecord(),
@@ -93,11 +109,13 @@ string16 MobileSetupDialogDelegate::GetDialogTitle() const {
}
GURL MobileSetupDialogDelegate::GetDialogContentURL() const {
- return GURL(chrome::kChromeUIMobileSetupURL);
+ std::string url(chrome::kChromeUIMobileSetupURL);
+ url.append(service_path_);
+ return GURL(url);
}
void MobileSetupDialogDelegate::GetWebUIMessageHandlers(
- std::vector<WebUIMessageHandler*>* handlers) const{
+ std::vector<WebUIMessageHandler*>* handlers) const {
}
void MobileSetupDialogDelegate::GetDialogSize(gfx::Size* size) const {
@@ -108,13 +126,20 @@ std::string MobileSetupDialogDelegate::GetDialogArgs() const {
return std::string();
}
+void MobileSetupDialogDelegate::OnDialogShown(
+ content::WebUI* webui, content::RenderViewHost* render_view_host) {
+ MobileActivator::GetInstance()->AddObserver(this);
+}
+
+
void MobileSetupDialogDelegate::OnDialogClosed(const std::string& json_retval) {
+ MobileActivator::GetInstance()->RemoveObserver(this);
dialog_window_ = NULL;
}
void MobileSetupDialogDelegate::OnCloseContents(WebContents* source,
bool* out_close_dialog) {
- if (!dialog_window_) {
+ if (!dialog_window_ || !MobileActivator::GetInstance()->RunningActivation()) {
*out_close_dialog = true;
return;
}
@@ -133,3 +158,9 @@ bool MobileSetupDialogDelegate::HandleContextMenu(
const content::ContextMenuParams& params) {
return true;
}
+
+void MobileSetupDialogDelegate::OnActivationStateChanged(
+ CellularNetwork* network,
+ MobileActivator::PlanActivationState state,
+ const std::string& error_description) {
+}
diff --git a/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h b/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h
index 0d39e6a..611b685 100644
--- a/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h
+++ b/chrome/browser/ui/webui/chromeos/mobile_setup_dialog.h
@@ -13,7 +13,7 @@
class MobileSetupDialog {
public:
- static void Show();
+ static void Show(const std::string& service_path);
private:
DISALLOW_COPY_AND_ASSIGN(MobileSetupDialog);
diff --git a/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc b/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
index 3158f64..952defd 100644
--- a/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/mobile_setup_ui.cc
@@ -11,7 +11,6 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/file_util.h"
-#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
@@ -19,13 +18,11 @@
#include "base/metrics/histogram.h"
#include "base/string_piece.h"
#include "base/string_util.h"
-#include "base/timer.h"
#include "base/utf_string_conversions.h"
#include "base/values.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/prefs/pref_service.h"
+#include "chrome/browser/chromeos/mobile/mobile_activator.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
@@ -47,6 +44,9 @@
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
+using chromeos::CellularNetwork;
+using chromeos::CrosLibrary;
+using chromeos::MobileActivator;
using content::BrowserThread;
using content::RenderViewHost;
using content::WebContents;
@@ -67,62 +67,6 @@ const char kJsPortalFrameLoadFailedCallback[] =
const char kJsPortalFrameLoadCompletedCallback[] =
"mobile.MobileSetup.portalFrameLoadCompleted";
-// 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 kErrorDisabled[] = "disabled";
-const char kErrorNoDevice[] = "no_device";
-const char kFailedPaymentError[] = "failed_payment";
-const char kFailedConnectivity[] = "connectivity";
-const char kErrorAlreadyRunning[] = "already_running";
-
-// 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";
-
-// Number of times we will retry to restart the activation process in case
-// there is no connectivity in the restricted pool.
-const int kMaxActivationAttempt = 3;
-// Number of times we will retry to reconnect if connection fails.
-const int kMaxConnectionRetry = 10;
-// Number of times we will retry to reconnect and reload payment portal page.
-const int kMaxPortalReconnectCount = 5;
-// Number of times we will retry to reconnect if connection fails.
-const int kMaxConnectionRetryOTASP = 30;
-// Number of times we will retry to reconnect after payment is processed.
-const int kMaxReconnectAttemptOTASP = 30;
-// Reconnect retry delay (after payment is processed).
-const int kPostPaymentReconnectDelayMS = 30000; // 30s.
-// Connection timeout in seconds.
-const int kConnectionTimeoutSeconds = 45;
-// Reconnect delay.
-const int kReconnectDelayMS = 3000;
-// Reconnect timer delay.
-const int kReconnectTimerDelayMS = 5000;
-// Reconnect delay after previous failure.
-const int kFailedReconnectDelayMS = 10000;
-// Retry delay after failed OTASP attempt.
-const int kOTASPRetryDelay = 20000;
-
-chromeos::CellularNetwork* GetCellularNetwork() {
- chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
- GetNetworkLibrary();
- if (lib->cellular_networks().begin() != lib->cellular_networks().end()) {
- return *(lib->cellular_networks().begin());
- }
- return NULL;
-}
-
} // namespace
// Observes IPC messages from the rederer and notifies JS if frame loading error
@@ -170,32 +114,9 @@ class PortalFrameLoadObserver : public content::RenderViewHostObserver {
DISALLOW_COPY_AND_ASSIGN(PortalFrameLoadObserver);
};
-class CellularConfigDocument
- : public base::RefCountedThreadSafe<CellularConfigDocument> {
- public:
- CellularConfigDocument() {}
-
- // Return error message for a given code.
- std::string GetErrorMessage(const std::string& code);
- void LoadCellularConfigFile();
- const std::string& version() { return version_; }
-
- private:
- typedef std::map<std::string, std::string> ErrorMap;
-
- void SetErrorMap(const ErrorMap& map);
- bool LoadFromFile(const FilePath& config_path);
-
- std::string version_;
- ErrorMap error_map_;
- base::Lock config_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(CellularConfigDocument);
-};
-
class MobileSetupUIHTMLSource : public ChromeURLDataManager::DataSource {
public:
- explicit MobileSetupUIHTMLSource(const std::string& service_path);
+ MobileSetupUIHTMLSource();
// Called when the network layer has requested a resource underneath
// the path we registered.
@@ -209,256 +130,66 @@ class MobileSetupUIHTMLSource : public ChromeURLDataManager::DataSource {
private:
virtual ~MobileSetupUIHTMLSource() {}
- std::string service_path_;
DISALLOW_COPY_AND_ASSIGN(MobileSetupUIHTMLSource);
};
// The handler for Javascript messages related to the "register" view.
class MobileSetupHandler
: public WebUIMessageHandler,
- public chromeos::NetworkLibrary::NetworkManagerObserver,
- public chromeos::NetworkLibrary::NetworkObserver,
+ public MobileActivator::Observer,
public base::SupportsWeakPtr<MobileSetupHandler> {
public:
- explicit MobileSetupHandler(const std::string& service_path);
+ MobileSetupHandler();
virtual ~MobileSetupHandler();
- // Init work after Attach.
- void StartActivationOnUIThread();
-
// WebUIMessageHandler implementation.
virtual void RegisterMessages() OVERRIDE;
- // NetworkLibrary::NetworkManagerObserver implementation.
- virtual void OnNetworkManagerChanged(chromeos::NetworkLibrary* obj) OVERRIDE;
- // NetworkLibrary::NetworkObserver implementation.
- virtual void OnNetworkChanged(chromeos::NetworkLibrary* obj,
- const chromeos::Network* network) OVERRIDE;
-
private:
- typedef enum PlanActivationState {
- PLAN_ACTIVATION_PAGE_LOADING = -1,
- PLAN_ACTIVATION_START = 0,
- PLAN_ACTIVATION_TRYING_OTASP = 1,
- PLAN_ACTIVATION_RECONNECTING_OTASP_TRY = 2,
- PLAN_ACTIVATION_INITIATING_ACTIVATION = 3,
- PLAN_ACTIVATION_RECONNECTING = 4,
- PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING = 5,
- PLAN_ACTIVATION_SHOWING_PAYMENT = 6,
- PLAN_ACTIVATION_RECONNECTING_PAYMENT = 7,
- PLAN_ACTIVATION_DELAY_OTASP = 8,
- PLAN_ACTIVATION_START_OTASP = 9,
- PLAN_ACTIVATION_OTASP = 10,
- PLAN_ACTIVATION_RECONNECTING_OTASP = 11,
- PLAN_ACTIVATION_DONE = 12,
- PLAN_ACTIVATION_ERROR = 0xFF,
- } PlanActivationState;
+ // Changes internal state.
+ void OnActivationStateChanged(CellularNetwork* network,
+ MobileActivator::PlanActivationState new_state,
+ const std::string& error_description);
// Handlers for JS WebUI messages.
void HandleSetTransactionStatus(const ListValue* args);
void HandleStartActivation(const ListValue* args);
void HandlePaymentPortalLoad(const ListValue* args);
- void SetTransactionStatus(const std::string& status);
- // Starts activation.
- void StartActivation();
- // Retried OTASP.
- void RetryOTASP();
- // Continues activation process. This method is called after we disconnect
- // due to detected connectivity issue to kick off reconnection.
- void ContinueConnecting(int delay);
// Sends message to host registration page with system/user info data.
void SendDeviceInfo();
- // Callback for when |reconnect_timer_| fires.
- void ReconnectTimerFired();
- // Starts OTASP process.
- void StartOTASP();
- // Checks if we need to reconnect due to failed connection attempt.
- bool NeedsReconnecting(chromeos::CellularNetwork* network,
- PlanActivationState* new_state,
- std::string* error_description);
- // Disconnect from network.
- void DisconnectFromNetwork(chromeos::CellularNetwork* network);
- // Connects to cellular network, resets connection timer.
- bool ConnectToNetwork(chromeos::CellularNetwork* network, int delay);
- // Forces disconnect / reconnect when we detect portal connectivity issues.
- void ForceReconnect(chromeos::CellularNetwork* network, int delay);
- // Reports connection timeout.
- bool ConnectionTimeout();
- // Verify the state of cellular network and modify internal state.
- void EvaluateCellularNetwork(chromeos::CellularNetwork* network);
- // Finds cellular network given device |meid|, reattach network change
- // observer if |reattach_observer| flag is set.
- chromeos::CellularNetwork* FindCellularNetworkByMeid(const std::string& meid,
- bool reattach_observer);
- // Check the current cellular network for error conditions.
- bool GotActivationError(chromeos::CellularNetwork* network,
- std::string* error);
- // Sends status updates to WebUI page.
- void UpdatePage(chromeos::CellularNetwork* network,
- const std::string& error_description);
- // Changes internal state.
- void ChangeState(chromeos::CellularNetwork* network,
- PlanActivationState new_state,
- const std::string& error_description);
- // Prepares network devices for cellular activation process.
- void SetupActivationProcess(chromeos::CellularNetwork* network);
- // Disables ethernet and wifi newtorks since they interefere with
- // detection of restricted pool on cellular side.
- void DisableOtherNetworks();
- // Resets network devices after cellular activation process.
- // |network| should be NULL if the activation process failed.
- void CompleteActivation(chromeos::CellularNetwork* network);
- // Control routines for handling other types of connections during
- // cellular activation.
- void ReEnableOtherConnections();
- // Return error message for a given code.
- std::string GetErrorMessage(const std::string& code);
-
// Converts the currently active CellularNetwork device into a JS object.
- static void GetDeviceInfo(chromeos::CellularNetwork* network,
+ static void GetDeviceInfo(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 Web UI.
- static bool EvaluateCellularDeviceState(bool* report_status,
- std::string* state,
- std::string* error);
-
- // Returns next reconnection state based on the current activation phase.
- static PlanActivationState GetNextReconnectState(PlanActivationState state);
- static const char* GetStateDescription(PlanActivationState state);
-
- scoped_refptr<CellularConfigDocument> cellular_config_;
- // Internal handler state.
- PlanActivationState state_;
- std::string meid_;
- std::string service_path_;
- // Flags that control if wifi and ethernet connection needs to be restored
- // after the activation of cellular network.
- bool reenable_wifi_;
- bool reenable_ethernet_;
- bool reenable_cert_check_;
- bool evaluating_;
- // True if we think that another tab is already running activation.
- bool already_running_;
- // Connection retry counter.
- int connection_retry_count_;
- // Post payment reconnect wait counters.
- int reconnect_wait_count_;
- // Payment portal reload/reconnect attempt count.
- int payment_reconnect_count_;
- // Activation retry attempt count;
- int activation_attempt_;
- // Connection start time.
- base::Time connection_start_time_;
- // Timer that monitors reconnection timeouts.
- base::RepeatingTimer<MobileSetupHandler> reconnect_timer_;
DISALLOW_COPY_AND_ASSIGN(MobileSetupHandler);
};
////////////////////////////////////////////////////////////////////////////////
//
-// CellularConfigDocument
-//
-////////////////////////////////////////////////////////////////////////////////
-
-std::string CellularConfigDocument::GetErrorMessage(const std::string& code) {
- base::AutoLock create(config_lock_);
- ErrorMap::iterator iter = error_map_.find(code);
- if (iter == error_map_.end())
- return code;
- return iter->second;
-}
-
-void CellularConfigDocument::LoadCellularConfigFile() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- // Load partner customization startup manifest if it is available.
- FilePath config_path(kCellularConfigPath);
- if (!file_util::PathExists(config_path))
- return;
-
- if (LoadFromFile(config_path)) {
- DVLOG(1) << "Cellular config file loaded: " << kCellularConfigPath;
- } else {
- LOG(ERROR) << "Error loading cellular config file: " <<
- kCellularConfigPath;
- }
-}
-
-bool CellularConfigDocument::LoadFromFile(const FilePath& config_path) {
- std::string config;
- if (!file_util::ReadFileToString(config_path, &config))
- return false;
-
- scoped_ptr<Value> root(
- base::JSONReader::Read(config, base::JSON_ALLOW_TRAILING_COMMAS));
- DCHECK(root.get() != NULL);
- if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
- LOG(WARNING) << "Bad cellular config file";
- return false;
- }
-
- DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());
- if (!root_dict->GetString(kVersionField, &version_)) {
- LOG(WARNING) << "Cellular config file missing version";
- return false;
- }
- ErrorMap error_map;
- 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(WARNING) << "Bad cellular config error value";
- return false;
- }
- error_map.insert(ErrorMap::value_type(*keys, value));
- }
- SetErrorMap(error_map);
- return true;
-}
-
-void CellularConfigDocument::SetErrorMap(
- const ErrorMap& map) {
- base::AutoLock create(config_lock_);
- error_map_.clear();
- error_map_.insert(map.begin(), map.end());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
// MobileSetupUIHTMLSource
//
////////////////////////////////////////////////////////////////////////////////
-MobileSetupUIHTMLSource::MobileSetupUIHTMLSource(
- const std::string& service_path)
- : DataSource(chrome::kChromeUIMobileSetupHost, MessageLoop::current()),
- service_path_(service_path) {
+MobileSetupUIHTMLSource::MobileSetupUIHTMLSource()
+ : DataSource(chrome::kChromeUIMobileSetupHost, MessageLoop::current()) {
}
void MobileSetupUIHTMLSource::StartDataRequest(const std::string& path,
bool is_incognito,
int request_id) {
- chromeos::CellularNetwork* network =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- FindCellularNetworkByPath(service_path_);
-
- // If we are activating, shutting down, or logging in, |network| may not
- // be available.
+ CellularNetwork* network = !path.size() ? NULL :
+ CrosLibrary::Get()->
+ GetNetworkLibrary()->FindCellularNetworkByPath(path);
if (!network || !network->SupportsActivation()) {
+ LOG(WARNING) << "Can't find device to activate for service path " << path;
scoped_refptr<base::RefCountedBytes> html_bytes(new base::RefCountedBytes);
SendResponse(request_id, html_bytes);
return;
}
+
+ LOG(WARNING) << "Activating mobile service " << path;
DictionaryValue strings;
strings.SetString("title", l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_TITLE));
strings.SetString("connecting_header",
@@ -497,30 +228,30 @@ void MobileSetupUIHTMLSource::StartDataRequest(const std::string& path,
// MobileSetupHandler
//
////////////////////////////////////////////////////////////////////////////////
-MobileSetupHandler::MobileSetupHandler(const std::string& service_path)
- : cellular_config_(new CellularConfigDocument()),
- state_(PLAN_ACTIVATION_PAGE_LOADING),
- service_path_(service_path),
- reenable_wifi_(false),
- reenable_ethernet_(false),
- reenable_cert_check_(false),
- evaluating_(false),
- already_running_(false),
- connection_retry_count_(0),
- reconnect_wait_count_(0),
- payment_reconnect_count_(0),
- activation_attempt_(0) {
+MobileSetupHandler::MobileSetupHandler() {
+ MobileActivator::GetInstance()->AddObserver(this);
}
MobileSetupHandler::~MobileSetupHandler() {
- reconnect_timer_.Stop();
- chromeos::NetworkLibrary* lib =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary();
- lib->RemoveNetworkManagerObserver(this);
- lib->RemoveObserverForAllNetworks(this);
- if (lib->IsLocked())
- lib->Unlock();
- ReEnableOtherConnections();
+ MobileActivator::GetInstance()->RemoveObserver(this);
+ MobileActivator::GetInstance()->TerminateActivation();
+}
+
+void MobileSetupHandler::OnActivationStateChanged(
+ CellularNetwork* network,
+ MobileActivator::PlanActivationState state,
+ const std::string& error_description) {
+ if (!web_ui())
+ return;
+
+ DictionaryValue device_dict;
+ if (network)
+ GetDeviceInfo(network, &device_dict);
+ device_dict.SetInteger("state", state);
+ if (error_description.length())
+ device_dict.SetString("error", error_description);
+ web_ui()->CallJavascriptFunction(
+ kJsDeviceStatusChangedCallback, device_dict);
}
void MobileSetupHandler::RegisterMessages() {
@@ -535,32 +266,17 @@ void MobileSetupHandler::RegisterMessages() {
base::Unretained(this)));
}
-void MobileSetupHandler::OnNetworkManagerChanged(
- chromeos::NetworkLibrary* cros) {
- if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
+void MobileSetupHandler::HandleStartActivation(const ListValue* args) {
+ if (!web_ui())
return;
- // Note that even though we get here when the service has
- // reappeared after disappearing earlier in the activation
- // process, there's no need to re-establish the NetworkObserver,
- // because the service path remains the same.
- EvaluateCellularNetwork(FindCellularNetworkByMeid(meid_, true));
-}
-void MobileSetupHandler::OnNetworkChanged(chromeos::NetworkLibrary* cros,
- const chromeos::Network* network) {
- if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
+ std::string path = web_ui()->GetWebContents()->GetURL().path();
+ if (!path.size())
return;
- DCHECK(network && network->type() == chromeos::TYPE_CELLULAR);
- EvaluateCellularNetwork(
- static_cast<chromeos::CellularNetwork*>(
- const_cast<chromeos::Network*>(network)));
-}
-void MobileSetupHandler::HandleStartActivation(const ListValue* args) {
- BrowserThread::PostTaskAndReply(BrowserThread::FILE, FROM_HERE,
- base::Bind(&CellularConfigDocument::LoadCellularConfigFile,
- cellular_config_.get()),
- base::Bind(&MobileSetupHandler::StartActivationOnUIThread, AsWeakPtr()));
+ LOG(WARNING) << "Starting activation for service " << path;
+
+ MobileActivator::GetInstance()->InitiateActivation(path.substr(1));
}
void MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) {
@@ -571,9 +287,9 @@ void MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) {
std::string status;
if (!args->GetString(0, &status))
return;
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&MobileSetupHandler::SetTransactionStatus, AsWeakPtr(),
- status));
+
+ MobileActivator::GetInstance()->OnSetTransactionStatus(
+ LowerCaseEqualsASCII(status, kJsApiResultOK));
}
void MobileSetupHandler::HandlePaymentPortalLoad(const ListValue* args) {
@@ -584,812 +300,12 @@ void MobileSetupHandler::HandlePaymentPortalLoad(const ListValue* args) {
std::string result;
if (!args->GetString(0, &result))
return;
- chromeos::CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
- if (!network) {
- ChangeState(NULL, PLAN_ACTIVATION_ERROR,
- GetErrorMessage(kErrorNoService));
- return;
- }
- if (state_ == PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING ||
- state_ == PLAN_ACTIVATION_SHOWING_PAYMENT) {
- if (LowerCaseEqualsASCII(result, kJsApiResultOK)) {
- payment_reconnect_count_ = 0;
- ChangeState(network, PLAN_ACTIVATION_SHOWING_PAYMENT, std::string());
- } else {
- payment_reconnect_count_++;
- if (payment_reconnect_count_ > kMaxPortalReconnectCount) {
- ChangeState(NULL, PLAN_ACTIVATION_ERROR,
- GetErrorMessage(kErrorNoService));
- return;
- }
- // Disconnect now, this should force reconnection and we will retry to
- // load the frame containing payment portal again.
- DisconnectFromNetwork(network);
- }
- } else {
- NOTREACHED() << "Called paymentPortalLoad while in unexpected state: "
- << GetStateDescription(state_);
- }
-}
-
-chromeos::CellularNetwork* MobileSetupHandler::FindCellularNetworkByMeid(
- const std::string& meid, bool reattach_observer) {
- chromeos::NetworkLibrary* lib =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary();
- for (chromeos::CellularNetworkVector::const_iterator it =
- lib->cellular_networks().begin();
- it != lib->cellular_networks().end(); ++it) {
- const chromeos::NetworkDevice* device =
- lib->FindNetworkDeviceByPath((*it)->device_path());
- if (device && meid == device->meid()) {
- chromeos::CellularNetwork* network = *it;
- // If service path has changed, reattach the event observer for this
- // network service.
- if (reattach_observer && service_path_ != network->service_path()) {
- lib->RemoveObserverForAllNetworks(this);
- lib->AddNetworkObserver(network->service_path(), this);
- service_path_ = network->service_path();
- }
- return network;
- }
- }
- return NULL;
-}
-
-void MobileSetupHandler::StartActivation() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- UMA_HISTOGRAM_COUNTS("Cellular.MobileSetupStart", 1);
- chromeos::NetworkLibrary* lib =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary();
- chromeos::CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
- // Check if we can start activation process.
- if (!network || already_running_) {
- std::string error;
- if (already_running_)
- error = kErrorAlreadyRunning;
- else if (!lib->cellular_available())
- error = kErrorNoDevice;
- else if (!lib->cellular_enabled())
- error = kErrorDisabled;
- else
- error = kErrorNoService;
- ChangeState(NULL, PLAN_ACTIVATION_ERROR, GetErrorMessage(error));
- return;
- }
-
- // Start monitoring network property changes.
- lib->AddNetworkManagerObserver(this);
- lib->RemoveObserverForAllNetworks(this);
- lib->AddNetworkObserver(network->service_path(), this);
- // Try to start with OTASP immediately if we have received payment recently.
- state_ = lib->HasRecentCellularPlanPayment() ?
- PLAN_ACTIVATION_START_OTASP :
- PLAN_ACTIVATION_START;
- EvaluateCellularNetwork(network);
-}
-
-void MobileSetupHandler::RetryOTASP() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(state_ == PLAN_ACTIVATION_DELAY_OTASP);
- StartOTASP();
-}
-
-void MobileSetupHandler::ContinueConnecting(int delay) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- chromeos::CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
- if (network && network->connecting_or_connected()) {
- EvaluateCellularNetwork(network);
- } else {
- ConnectToNetwork(network, delay);
- }
-}
-
-void MobileSetupHandler::SetTransactionStatus(const std::string& status) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // The payment is received, try to reconnect and check the status all over
- // again.
- if (LowerCaseEqualsASCII(status, kJsApiResultOK) &&
- state_ == PLAN_ACTIVATION_SHOWING_PAYMENT) {
- chromeos::NetworkLibrary* lib =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary();
- lib->SignalCellularPlanPayment();
- UMA_HISTOGRAM_COUNTS("Cellular.PaymentReceived", 1);
- StartOTASP();
- } else {
- UMA_HISTOGRAM_COUNTS("Cellular.PaymentFailed", 1);
- }
-}
-
-void MobileSetupHandler::StartOTASP() {
- state_ = PLAN_ACTIVATION_START_OTASP;
- chromeos::CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
- if (network &&
- network->connected() &&
- network->activation_state() == chromeos::ACTIVATION_STATE_ACTIVATED) {
- chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- DisconnectFromNetwork(network);
- } else {
- EvaluateCellularNetwork(network);
- }
-}
-
-void MobileSetupHandler::ReconnectTimerFired() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // Permit network connection changes only in reconnecting states.
- if (state_ != PLAN_ACTIVATION_RECONNECTING_OTASP_TRY &&
- state_ != PLAN_ACTIVATION_RECONNECTING &&
- state_ != PLAN_ACTIVATION_RECONNECTING_PAYMENT &&
- state_ != PLAN_ACTIVATION_RECONNECTING_OTASP)
- return;
- chromeos::CellularNetwork* network = FindCellularNetworkByMeid(meid_, true);
- if (!network) {
- // No service, try again since this is probably just transient condition.
- LOG(WARNING) << "Service not present at reconnect attempt.";
- }
- EvaluateCellularNetwork(network);
-}
-
-void MobileSetupHandler::DisconnectFromNetwork(
- chromeos::CellularNetwork* network) {
- DCHECK(network);
- LOG(INFO) << "Disconnecting from: " << network->service_path();
- chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- DisconnectFromNetwork(network);
- // Disconnect will force networks to be reevaluated, so
- // we don't want to continue processing on this path anymore.
- evaluating_ = false;
-}
-
-bool MobileSetupHandler::NeedsReconnecting(
- chromeos::CellularNetwork* network,
- PlanActivationState* new_state,
- std::string* error_description) {
- DCHECK(network);
- if (!network->failed() && !ConnectionTimeout())
- return false;
-
- // Try to reconnect again if reconnect failed, or if for some
- // reasons we are still not connected after 45 seconds.
- int max_retries = (state_ == PLAN_ACTIVATION_RECONNECTING_OTASP) ?
- kMaxConnectionRetryOTASP : kMaxConnectionRetry;
- if (connection_retry_count_ < max_retries) {
- UMA_HISTOGRAM_COUNTS("Cellular.ConnectionRetry", 1);
- ConnectToNetwork(network, kFailedReconnectDelayMS);
- return true;
- }
- // We simply can't connect anymore after all these tries.
- UMA_HISTOGRAM_COUNTS("Cellular.ConnectionFailed", 1);
- *new_state = PLAN_ACTIVATION_ERROR;
- *error_description = GetErrorMessage(kFailedConnectivity);
- return false;
-}
-
-bool MobileSetupHandler::ConnectToNetwork(
- chromeos::CellularNetwork* network,
- int delay) {
- if (network && network->connecting_or_connected())
- return true;
- // Permit network connection changes only in reconnecting states.
- if (state_ != PLAN_ACTIVATION_RECONNECTING_OTASP_TRY &&
- state_ != PLAN_ACTIVATION_RECONNECTING &&
- state_ != PLAN_ACTIVATION_RECONNECTING_PAYMENT &&
- state_ != PLAN_ACTIVATION_RECONNECTING_OTASP) return false;
- if (network)
- LOG(INFO) << "Connecting to: " << network->service_path();
- connection_retry_count_++;
- connection_start_time_ = base::Time::Now();
- if (!network) {
- LOG(WARNING) << "Connect failed."
- << (network ? network->service_path().c_str() : "no service");
- // If we coudn't connect during reconnection phase, try to reconnect
- // with a delay (and try to reconnect if needed).
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&MobileSetupHandler::ContinueConnecting, AsWeakPtr(), delay),
- base::TimeDelta::FromMilliseconds(delay));
- return false;
- }
- chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- ConnectToCellularNetwork(network);
- return true;
-}
-
-void MobileSetupHandler::ForceReconnect(
- chromeos::CellularNetwork* network,
- int delay) {
- DCHECK(network);
- UMA_HISTOGRAM_COUNTS("Cellular.ActivationRetry", 1);
- // Reset reconnect metrics.
- connection_retry_count_ = 0;
- connection_start_time_ = base::Time();
- // First, disconnect...
- LOG(INFO) << "Disconnecting from " << network->service_path();
- chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
- DisconnectFromNetwork(network);
- // Check the network state 3s after we disconnect to make sure.
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&MobileSetupHandler::ContinueConnecting, AsWeakPtr(), delay),
- base::TimeDelta::FromMilliseconds(delay));
-}
-
-bool MobileSetupHandler::ConnectionTimeout() {
- return (base::Time::Now() -
- connection_start_time_).InSeconds() > kConnectionTimeoutSeconds;
-}
-
-void MobileSetupHandler::EvaluateCellularNetwork(
- chromeos::CellularNetwork* network) {
- if (!web_ui())
- return;
-
- PlanActivationState new_state = state_;
- if (!network) {
- LOG(WARNING) << "Cellular service lost";
- if (state_ == PLAN_ACTIVATION_RECONNECTING_OTASP_TRY ||
- state_ == PLAN_ACTIVATION_RECONNECTING ||
- state_ == PLAN_ACTIVATION_RECONNECTING_PAYMENT ||
- state_ == PLAN_ACTIVATION_RECONNECTING_OTASP) {
- // This might be the legit case when service is lost after activation.
- // We need to make sure we force reconnection as soon as it shows up.
- LOG(INFO) << "Force service reconnection";
- connection_start_time_ = base::Time();
- }
- return;
- }
-
- // Prevent this method from being called if it is already on the stack.
- // This might happen on some state transitions (ie. connect, disconnect).
- if (evaluating_)
- return;
- evaluating_ = true;
- std::string error_description;
-
- LOG(WARNING) << "Cellular:\n service=" << network->GetStateString().c_str()
- << "\n ui=" << GetStateDescription(state_)
- << "\n activation=" << network->GetActivationStateString().c_str()
- << "\n error=" << network->GetErrorString().c_str()
- << "\n setvice_path=" << network->service_path().c_str();
- switch (state_) {
- case PLAN_ACTIVATION_START: {
- switch (network->activation_state()) {
- case chromeos::ACTIVATION_STATE_ACTIVATED: {
- if (network->disconnected()) {
- new_state = PLAN_ACTIVATION_RECONNECTING;
- } else if (network->connected()) {
- if (network->restricted_pool()) {
- new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
- } else {
- new_state = PLAN_ACTIVATION_DONE;
- }
- }
- break;
- }
- default: {
- if (network->disconnected() ||
- network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
- new_state = (network->activation_state() ==
- chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) ?
- PLAN_ACTIVATION_TRYING_OTASP :
- PLAN_ACTIVATION_INITIATING_ACTIVATION;
- } else if (network->connected()) {
- DisconnectFromNetwork(network);
- return;
- }
- break;
- }
- }
- break;
- }
- case PLAN_ACTIVATION_START_OTASP: {
- switch (network->activation_state()) {
- case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED: {
- if (network->disconnected()) {
- new_state = PLAN_ACTIVATION_OTASP;
- } else if (network->connected()) {
- DisconnectFromNetwork(network);
- return;
- }
- break;
- }
- case chromeos::ACTIVATION_STATE_ACTIVATED:
- new_state = PLAN_ACTIVATION_RECONNECTING_OTASP;
- break;
- default: {
- LOG(WARNING) << "Unexpected activation state for device "
- << network->service_path().c_str();
- break;
- }
- }
- break;
- }
- case PLAN_ACTIVATION_DELAY_OTASP:
- // Just ignore any changes until the OTASP retry timer kicks in.
- evaluating_ = false;
- return;
- case PLAN_ACTIVATION_INITIATING_ACTIVATION: {
- switch (network->activation_state()) {
- case chromeos::ACTIVATION_STATE_ACTIVATED:
- case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
- new_state = PLAN_ACTIVATION_START;
- break;
- case chromeos::ACTIVATION_STATE_NOT_ACTIVATED:
- case chromeos::ACTIVATION_STATE_ACTIVATING:
- // Wait in this state until activation state changes.
- break;
- default:
- break;
- }
- break;
- }
- case PLAN_ACTIVATION_OTASP:
- case PLAN_ACTIVATION_TRYING_OTASP: {
- switch (network->activation_state()) {
- case chromeos::ACTIVATION_STATE_ACTIVATED:
- if (network->disconnected()) {
- new_state = GetNextReconnectState(state_);
- } else if (network->connected()) {
- if (network->restricted_pool()) {
- new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
- } else {
- new_state = PLAN_ACTIVATION_DONE;
- }
- }
- break;
- case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
- if (network->connected()) {
- if (network->restricted_pool())
- new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
- } else {
- new_state = GetNextReconnectState(state_);
- }
- break;
- case chromeos::ACTIVATION_STATE_NOT_ACTIVATED:
- case chromeos::ACTIVATION_STATE_ACTIVATING:
- // Wait in this state until activation state changes.
- break;
- default:
- break;
- }
- break;
- }
- case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
- case PLAN_ACTIVATION_RECONNECTING_PAYMENT:
- case PLAN_ACTIVATION_RECONNECTING: {
- if (network->connected()) {
- // Make sure other networks are not interfering with our detection of
- // restricted pool.
- DisableOtherNetworks();
- // Wait until the service shows up and gets activated.
- switch (network->activation_state()) {
- case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
- case chromeos::ACTIVATION_STATE_ACTIVATED:
- if (network->restricted_pool()) {
- if (network->error() == chromeos::ERROR_DNS_LOOKUP_FAILED) {
- LOG(WARNING) << "No connectivity for device "
- << network->service_path().c_str();
- // If we are connected but there is no connectivity at all,
- // restart the whole process again.
- if (activation_attempt_ < kMaxActivationAttempt) {
- activation_attempt_++;
- LOG(WARNING) << "Reconnect attempt #"
- << activation_attempt_;
- ForceReconnect(network, kFailedReconnectDelayMS);
- evaluating_ = false;
- return;
- } else {
- new_state = PLAN_ACTIVATION_ERROR;
- UMA_HISTOGRAM_COUNTS("Cellular.ActivationRetryFailure", 1);
- error_description = GetErrorMessage(kFailedConnectivity);
- }
- } else {
- // If we have already received payment, don't show the payment
- // page again. We should try to reconnect after some
- // time instead.
- new_state = PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING;
- }
- } else if (network->activation_state() ==
- chromeos::ACTIVATION_STATE_ACTIVATED) {
- new_state = PLAN_ACTIVATION_DONE;
- }
- break;
- default:
- break;
- }
- } else if (NeedsReconnecting(network, &new_state, &error_description)) {
- evaluating_ = false;
- return;
- }
- break;
- }
- case PLAN_ACTIVATION_RECONNECTING_OTASP: {
- if (network->connected()) {
- // Make sure other networks are not interfering with our detection of
- // restricted pool.
- DisableOtherNetworks();
- // Wait until the service shows up and gets activated.
- switch (network->activation_state()) {
- case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
- case chromeos::ACTIVATION_STATE_ACTIVATED:
- if (network->restricted_pool()) {
- LOG(WARNING) << "Still no connectivity after OTASP for device "
- << network->service_path().c_str();
- // If we have already received payment, don't show the payment
- // page again. We should try to reconnect after some time instead.
- if (reconnect_wait_count_ < kMaxReconnectAttemptOTASP) {
- reconnect_wait_count_++;
- LOG(WARNING) << "OTASP reconnect attempt #"
- << reconnect_wait_count_;
- ForceReconnect(network, kPostPaymentReconnectDelayMS);
- evaluating_ = false;
- return;
- } else {
- new_state = PLAN_ACTIVATION_ERROR;
- UMA_HISTOGRAM_COUNTS("Cellular.PostPaymentConnectFailure", 1);
- error_description = GetErrorMessage(kFailedConnectivity);
- }
- } else if (network->online()) {
- new_state = PLAN_ACTIVATION_DONE;
- }
- break;
- default:
- break;
- }
- } else if (NeedsReconnecting(network, &new_state, &error_description)) {
- evaluating_ = false;
- return;
- }
- break;
- }
- case PLAN_ACTIVATION_PAGE_LOADING:
- break;
- // Just ignore all signals until the site confirms payment.
- case PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
- case PLAN_ACTIVATION_SHOWING_PAYMENT: {
- if (network->disconnected())
- new_state = PLAN_ACTIVATION_RECONNECTING_PAYMENT;
- break;
- }
- // Activation completed/failed, ignore network changes.
- case PLAN_ACTIVATION_DONE:
- case PLAN_ACTIVATION_ERROR:
- break;
- }
-
- if (new_state != PLAN_ACTIVATION_ERROR &&
- GotActivationError(network, &error_description)) {
- // Check for this special case when we try to do activate partially
- // activated device. If that attempt failed, try to disconnect to clear the
- // state and reconnect again.
- if ((network->activation_state() ==
- chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED ||
- network->activation_state() == chromeos::ACTIVATION_STATE_ACTIVATING) &&
- (network->error() == chromeos::ERROR_NO_ERROR ||
- network->error() == chromeos::ERROR_OTASP_FAILED) &&
- network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
- LOG(WARNING) << "Activation failure detected "
- << network->service_path().c_str();
- switch (state_) {
- case PLAN_ACTIVATION_OTASP:
- case PLAN_ACTIVATION_RECONNECTING_OTASP:
- new_state = PLAN_ACTIVATION_DELAY_OTASP;
- break;
- case PLAN_ACTIVATION_TRYING_OTASP:
- new_state = PLAN_ACTIVATION_RECONNECTING_OTASP_TRY;
- break;
- case PLAN_ACTIVATION_INITIATING_ACTIVATION:
- new_state = PLAN_ACTIVATION_RECONNECTING;
- break;
- case PLAN_ACTIVATION_START:
- // We are just starting, so this must be previous activation attempt
- // failure.
- new_state = PLAN_ACTIVATION_TRYING_OTASP;
- break;
- case PLAN_ACTIVATION_DELAY_OTASP:
- case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
- case PLAN_ACTIVATION_RECONNECTING:
- new_state = state_;
- break;
- default:
- new_state = PLAN_ACTIVATION_ERROR;
- break;
- }
- } else {
- LOG(WARNING) << "Unexpected activation failure for "
- << network->service_path().c_str();
- new_state = PLAN_ACTIVATION_ERROR;
- }
- }
-
- if (new_state == PLAN_ACTIVATION_ERROR && !error_description.length())
- error_description = GetErrorMessage(kErrorDefault);
- ChangeState(network, new_state, error_description);
- evaluating_ = false;
-}
-
-MobileSetupHandler::PlanActivationState
- MobileSetupHandler::GetNextReconnectState(
- MobileSetupHandler::PlanActivationState state) {
- switch (state) {
- case PLAN_ACTIVATION_INITIATING_ACTIVATION:
- return PLAN_ACTIVATION_RECONNECTING;
- case PLAN_ACTIVATION_OTASP:
- return PLAN_ACTIVATION_RECONNECTING_OTASP;
- case PLAN_ACTIVATION_TRYING_OTASP:
- return PLAN_ACTIVATION_RECONNECTING_OTASP_TRY;
- default:
- return PLAN_ACTIVATION_RECONNECTING;
- }
+ MobileActivator::GetInstance()->OnPortalLoaded(
+ LowerCaseEqualsASCII(result, kJsApiResultOK));
}
-// 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_TRYING_OTASP:
- return "TRYING_OTASP";
- case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
- return "RECONNECTING_OTASP_TRY";
- case PLAN_ACTIVATION_INITIATING_ACTIVATION:
- return "INITIATING_ACTIVATION";
- case PLAN_ACTIVATION_RECONNECTING:
- return "RECONNECTING";
- case PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
- return "PAYMENT_PORTAL_LOADING";
- case PLAN_ACTIVATION_SHOWING_PAYMENT:
- return "SHOWING_PAYMENT";
- case PLAN_ACTIVATION_RECONNECTING_PAYMENT:
- return "RECONNECTING_PAYMENT";
- case PLAN_ACTIVATION_START_OTASP:
- return "START_OTASP";
- case PLAN_ACTIVATION_DELAY_OTASP:
- return "DELAY_OTASP";
- case PLAN_ACTIVATION_OTASP:
- return "OTASP";
- case PLAN_ACTIVATION_RECONNECTING_OTASP:
- return "RECONNECTING_OTASP";
- case PLAN_ACTIVATION_DONE:
- return "DONE";
- case PLAN_ACTIVATION_ERROR:
- return "ERROR";
- }
- return "UNKNOWN";
-}
-
-
-void MobileSetupHandler::CompleteActivation(
- chromeos::CellularNetwork* network) {
- // Remove observers, we are done with this page.
- chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
- GetNetworkLibrary();
- lib->RemoveNetworkManagerObserver(this);
- lib->RemoveObserverForAllNetworks(this);
- if (lib->IsLocked())
- lib->Unlock();
- // If we have successfully activated the connection, set autoconnect flag.
- if (network)
- network->SetAutoConnect(true);
- // Reactivate other types of connections if we have
- // shut them down previously.
- ReEnableOtherConnections();
-}
-
-void MobileSetupHandler::UpdatePage(
- chromeos::CellularNetwork* network,
- const std::string& error_description) {
- DictionaryValue device_dict;
- if (network)
- GetDeviceInfo(network, &device_dict);
- device_dict.SetInteger("state", state_);
- if (error_description.length())
- device_dict.SetString("error", error_description);
- web_ui()->CallJavascriptFunction(
- kJsDeviceStatusChangedCallback, device_dict);
-}
-
-
-void MobileSetupHandler::ChangeState(chromeos::CellularNetwork* network,
- PlanActivationState new_state,
- const std::string& error_description) {
- static bool first_time = true;
- if (state_ == new_state && !first_time)
- return;
- LOG(WARNING) << "Activation state flip old = "
- << GetStateDescription(state_)
- << ", new = " << GetStateDescription(new_state);
- first_time = false;
-
- // Pick action that should happen on leaving the old state.
- switch (state_) {
- case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
- case PLAN_ACTIVATION_RECONNECTING:
- case PLAN_ACTIVATION_RECONNECTING_OTASP:
- if (reconnect_timer_.IsRunning()) {
- reconnect_timer_.Stop();
- }
- break;
- default:
- break;
- }
- state_ = new_state;
-
- // Signal to JS layer that the state is changing.
- UpdatePage(network, error_description);
-
- // Pick action that should happen on entering the new state.
- switch (new_state) {
- case PLAN_ACTIVATION_START:
- break;
- case PLAN_ACTIVATION_DELAY_OTASP: {
- UMA_HISTOGRAM_COUNTS("Cellular.RetryOTASP", 1);
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&MobileSetupHandler::RetryOTASP, AsWeakPtr()),
- base::TimeDelta::FromMilliseconds(kOTASPRetryDelay));
- break;
- }
- case PLAN_ACTIVATION_INITIATING_ACTIVATION:
- case PLAN_ACTIVATION_TRYING_OTASP:
- case PLAN_ACTIVATION_OTASP:
- DCHECK(network);
- LOG(WARNING) << "Activating service " << network->service_path().c_str();
- UMA_HISTOGRAM_COUNTS("Cellular.ActivationTry", 1);
- if (!network->StartActivation()) {
- UMA_HISTOGRAM_COUNTS("Cellular.ActivationFailure", 1);
- if (new_state == PLAN_ACTIVATION_OTASP) {
- ChangeState(network, PLAN_ACTIVATION_DELAY_OTASP, std::string());
- } else {
- ChangeState(network, PLAN_ACTIVATION_ERROR,
- GetErrorMessage(kFailedConnectivity));
- }
- }
- break;
- case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
- case PLAN_ACTIVATION_RECONNECTING:
- case PLAN_ACTIVATION_RECONNECTING_PAYMENT:
- case PLAN_ACTIVATION_RECONNECTING_OTASP: {
- // Start reconnect timer. This will ensure that we are not left in
- // limbo by the network library.
- if (!reconnect_timer_.IsRunning()) {
- reconnect_timer_.Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kReconnectTimerDelayMS),
- this, &MobileSetupHandler::ReconnectTimerFired);
- }
- // Reset connection metrics and try to connect.
- reconnect_wait_count_ = 0;
- connection_retry_count_ = 0;
- connection_start_time_ = base::Time::Now();
- ConnectToNetwork(network, kReconnectDelayMS);
- break;
- }
- case PLAN_ACTIVATION_PAGE_LOADING:
- return;
- case PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
- case PLAN_ACTIVATION_SHOWING_PAYMENT:
- // Fix for fix SSL for the walled gardens where cert chain verification
- // might not work.
- break;
- case PLAN_ACTIVATION_DONE:
- DCHECK(network);
- CompleteActivation(network);
- UMA_HISTOGRAM_COUNTS("Cellular.MobileSetupSucceeded", 1);
- break;
- case PLAN_ACTIVATION_ERROR:
- CompleteActivation(NULL);
- UMA_HISTOGRAM_COUNTS("Cellular.PlanFailed", 1);
- break;
- default:
- break;
- }
-}
-
-void MobileSetupHandler::ReEnableOtherConnections() {
- chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
- GetNetworkLibrary();
- if (reenable_ethernet_) {
- reenable_ethernet_ = false;
- lib->EnableEthernetNetworkDevice(true);
- }
- if (reenable_wifi_) {
- reenable_wifi_ = false;
- lib->EnableWifiNetworkDevice(true);
- }
-
- PrefService* prefs = g_browser_process->local_state();
- if (reenable_cert_check_) {
- prefs->SetBoolean(prefs::kCertRevocationCheckingEnabled,
- true);
- reenable_cert_check_ = false;
- }
-}
-
-void MobileSetupHandler::SetupActivationProcess(
- chromeos::CellularNetwork* network) {
- if (!network)
- return;
-
- // Disable SSL cert checks since we will be doing this in
- // restricted pool.
- PrefService* prefs = g_browser_process->local_state();
- if (!reenable_cert_check_ &&
- prefs->GetBoolean(
- prefs::kCertRevocationCheckingEnabled)) {
- reenable_cert_check_ = true;
- prefs->SetBoolean(prefs::kCertRevocationCheckingEnabled, false);
- }
-
- chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
- GetNetworkLibrary();
- // Disable autoconnect to cellular network.
- network->SetAutoConnect(false);
-
- // Prevent any other network interference.
- DisableOtherNetworks();
- lib->Lock();
-}
-
-void MobileSetupHandler::DisableOtherNetworks() {
- chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
- GetNetworkLibrary();
- // Disable ethernet and wifi.
- if (lib->ethernet_enabled()) {
- reenable_ethernet_ = true;
- lib->EnableEthernetNetworkDevice(false);
- }
- if (lib->wifi_enabled()) {
- reenable_wifi_ = true;
- lib->EnableWifiNetworkDevice(false);
- }
-}
-
-bool MobileSetupHandler::GotActivationError(
- chromeos::CellularNetwork* network, std::string* error) {
- DCHECK(network);
- bool got_error = false;
- const char* error_code = kErrorDefault;
-
- // This is the magic for detection of errors in during activation process.
- if (network->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->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;
-}
-
-void MobileSetupHandler::GetDeviceInfo(chromeos::CellularNetwork* network,
+void MobileSetupHandler::GetDeviceInfo(CellularNetwork* network,
DictionaryValue* value) {
DCHECK(network);
chromeos::NetworkLibrary* cros =
@@ -1410,39 +326,6 @@ void MobileSetupHandler::GetDeviceInfo(chromeos::CellularNetwork* network,
}
}
-std::string MobileSetupHandler::GetErrorMessage(const std::string& code) {
- return cellular_config_->GetErrorMessage(code);
-}
-
-void MobileSetupHandler::StartActivationOnUIThread() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- chromeos::NetworkLibrary* lib =
- chromeos::CrosLibrary::Get()->GetNetworkLibrary();
-
- chromeos::CellularNetwork* network =
- lib->FindCellularNetworkByPath(service_path_);
-
- if (!network || !network->SupportsActivation()) {
- LOG(ERROR) << "Cellular service can't be found: " << service_path_;
- return;
- }
-
- const chromeos::NetworkDevice* device =
- lib->FindNetworkDeviceByPath(network->device_path());
- if (!device) {
- LOG(ERROR) << "Cellular device can't be found: " << network->device_path();
- return;
- }
-
- meid_ = device->meid();
- if (!chromeos::CrosLibrary::Get()->GetNetworkLibrary()->IsLocked())
- SetupActivationProcess(network);
- else
- already_running_ = true;
-
- StartActivation();
-}
-
////////////////////////////////////////////////////////////////////////////////
//
// MobileSetupUI
@@ -1451,11 +334,8 @@ void MobileSetupHandler::StartActivationOnUIThread() {
MobileSetupUI::MobileSetupUI(content::WebUI* web_ui)
: WebUIController(web_ui) {
- chromeos::CellularNetwork* network = GetCellularNetwork();
- std::string service_path = network ? network->service_path() : std::string();
- web_ui->AddMessageHandler(new MobileSetupHandler(service_path));
- MobileSetupUIHTMLSource* html_source =
- new MobileSetupUIHTMLSource(service_path);
+ web_ui->AddMessageHandler(new MobileSetupHandler());
+ MobileSetupUIHTMLSource* html_source = new MobileSetupUIHTMLSource();
// Set up the chrome://mobilesetup/ source.
Profile* profile = Profile::FromWebUI(web_ui);
diff --git a/chrome/browser/ui/webui/options2/chromeos/internet_options_handler2.cc b/chrome/browser/ui/webui/options2/chromeos/internet_options_handler2.cc
index 983a2d7..ef11169 100644
--- a/chrome/browser/ui/webui/options2/chromeos/internet_options_handler2.cc
+++ b/chrome/browser/ui/webui/options2/chromeos/internet_options_handler2.cc
@@ -592,7 +592,13 @@ void InternetOptionsHandler::ShowMorePlanInfoCallback(const ListValue* args) {
void InternetOptionsHandler::BuyDataPlanCallback(const ListValue* args) {
if (!web_ui())
return;
- ash::Shell::GetInstance()->delegate()->OpenMobileSetup();
+
+ std::string service_path;
+ if (args->GetSize() != 1 || !args->GetString(0, &service_path)) {
+ NOTREACHED();
+ return;
+ }
+ ash::Shell::GetInstance()->delegate()->OpenMobileSetup(service_path);
}
void InternetOptionsHandler::SetApnCallback(const ListValue* args) {
@@ -1231,7 +1237,7 @@ void InternetOptionsHandler::HandleCellularButtonClick(
} else if (command == "disconnect") {
cros_->DisconnectFromNetwork(cellular);
} else if (command == "activate") {
- ash::Shell::GetInstance()->delegate()->OpenMobileSetup();
+ ash::Shell::GetInstance()->delegate()->OpenMobileSetup(service_path);
} else if (command == "options") {
PopulateDictionaryDetails(cellular);
}