172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/webui/chromeos/mobile_setup_ui.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include <algorithm>
8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <map>
9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <string>
10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/callback.h"
12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/file_util.h"
13731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/json/json_reader.h"
14513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/json/json_writer.h"
15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/weak_ptr.h"
174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/metrics/histogram.h"
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/string_piece.h"
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/string_util.h"
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/threading/thread_restrictions.h"
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/timer.h"
22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/utf_string_conversions.h"
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/values.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/browser_process.h"
25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/cros/cros_library.h"
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/cros/network_library.h"
27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/prefs/pref_service.h"
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/common/jstemplate_builder.h"
32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/common/pref_names.h"
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/common/url_constants.h"
34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "googleurl/src/gurl.h"
37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/browser_resources.h"
38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/chromium_strings.h"
39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/generated_resources.h"
40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/locale_settings.h"
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace {
45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Host page JS API function names.
47513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst char kJsApiStartActivation[] = "startActivation";
48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst char kJsApiSetTransactionStatus[] = "setTransactionStatus";
49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char kJsDeviceStatusChangedHandler[] =
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "mobile.MobileSetup.deviceStateChanged";
52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Error codes matching codes defined in the cellular config file.
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorDefault[] = "default";
55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorBadConnectionPartial[] = "bad_connection_partial";
56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorBadConnectionActivated[] = "bad_connection_activated";
57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorRoamingOnConnection[] = "roaming_connection";
58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorNoEVDO[] = "no_evdo";
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorRoamingActivation[] = "roaming_activation";
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorRoamingPartiallyActivated[] = "roaming_partially_activated";
61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorNoService[] = "no_service";
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst char kErrorDisabled[] = "disabled";
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst char kErrorNoDevice[] = "no_device";
64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kFailedPaymentError[] = "failed_payment";
65201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char kFailedConnectivity[] = "connectivity";
6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst char kErrorAlreadyRunning[] = "already_running";
67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Cellular configuration file path.
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kCellularConfigPath[] =
70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    "/usr/share/chromeos-assets/mobile/mobile_config.json";
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Cellular config file field names.
73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kVersionField[] = "version";
74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char kErrorsField[] = "errors";
75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
76201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Number of times we will retry to restart the activation process in case
77201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// there is no connectivity in the restricted pool.
78201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst int kMaxActivationAttempt = 3;
794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Number of times we will retry to reconnect if connection fails.
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kMaxConnectionRetry = 10;
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Number of times we will retry to reconnect if connection fails.
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kMaxConnectionRetryOTASP = 30;
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Number of times we will retry to reconnect after payment is processed.
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kMaxReconnectAttemptOTASP = 30;
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Reconnect retry delay (after payment is processed).
8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kPostPaymentReconnectDelayMS = 30000;   // 30s.
874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Connection timeout in seconds.
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kConnectionTimeoutSeconds = 45;
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Reconnect delay.
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kReconnectDelayMS = 3000;
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Reconnect timer delay.
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kReconnectTimerDelayMS = 5000;
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Reconnect delay after previous failure.
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kFailedReconnectDelayMS = 10000;
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Retry delay after failed OTASP attempt.
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kOTASPRetryDelay = 20000;
974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
98513209b27ff55e2841eac0e4120199c23acce758Ben Murdochchromeos::CellularNetwork* GetCellularNetwork() {
99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GetNetworkLibrary();
101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (lib->cellular_networks().begin() != lib->cellular_networks().end()) {
102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return *(lib->cellular_networks().begin());
103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return NULL;
105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchromeos::CellularNetwork* GetCellularNetwork(
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const std::string& service_path) {
109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return chromeos::CrosLibrary::Get()->
110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GetNetworkLibrary()->FindCellularNetworkByPath(service_path);
111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace
114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass CellularConfigDocument {
116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick public:
117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CellularConfigDocument() {}
118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Return error message for a given code.
120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string GetErrorMessage(const std::string& code);
121731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const std::string& version() { return version_; }
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool LoadFromFile(const FilePath& config_path);
124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick private:
126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string version_;
127731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::map<std::string, std::string> error_map_;
128731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DISALLOW_COPY_AND_ASSIGN(CellularConfigDocument);
130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick};
131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstatic std::map<std::string, std::string> error_messages_;
133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass MobileSetupUIHTMLSource : public ChromeURLDataManager::DataSource {
135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public:
136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  explicit MobileSetupUIHTMLSource(const std::string& service_path);
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Called when the network layer has requested a resource underneath
139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // the path we registered.
140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void StartDataRequest(const std::string& path,
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                bool is_incognito,
142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                int request_id);
143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual std::string GetMimeType(const std::string&) const {
144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return "text/html";
145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private:
148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual ~MobileSetupUIHTMLSource() {}
149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  std::string service_path_;
151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(MobileSetupUIHTMLSource);
152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// The handler for Javascript messages related to the "register" view.
155513209b27ff55e2841eac0e4120199c23acce758Ben Murdochclass MobileSetupHandler
15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  : public WebUIMessageHandler,
157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    public chromeos::NetworkLibrary::NetworkManagerObserver,
158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    public chromeos::NetworkLibrary::NetworkObserver,
159513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    public base::SupportsWeakPtr<MobileSetupHandler> {
160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public:
161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  explicit MobileSetupHandler(const std::string& service_path);
162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual ~MobileSetupHandler();
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Init work after Attach.
165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void Init(TabContents* contents);
166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
16772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // WebUIMessageHandler implementation.
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual WebUIMessageHandler* Attach(WebUI* web_ui);
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void RegisterMessages();
170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // NetworkLibrary::NetworkManagerObserver implementation.
172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void OnNetworkManagerChanged(chromeos::NetworkLibrary* obj);
173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // NetworkLibrary::NetworkObserver implementation.
174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void OnNetworkChanged(chromeos::NetworkLibrary* obj,
175513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                const chromeos::Network* network);
176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private:
178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  typedef enum PlanActivationState {
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_PAGE_LOADING            = -1,
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_START                   = 0,
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_TRYING_OTASP            = 1,
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_RECONNECTING_OTASP_TRY  = 2,
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_INITIATING_ACTIVATION   = 3,
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_RECONNECTING            = 4,
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_SHOWING_PAYMENT         = 5,
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_DELAY_OTASP             = 6,
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_START_OTASP             = 7,
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_OTASP                   = 8,
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_RECONNECTING_OTASP      = 9,
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_DONE                    = 10,
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PLAN_ACTIVATION_ERROR                   = 0xFF,
192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  } PlanActivationState;
193513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch   public:
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    TaskProxy(const base::WeakPtr<MobileSetupHandler>& handler, int delay)
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        : handler_(handler), delay_(delay) {
198513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
199513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    TaskProxy(const base::WeakPtr<MobileSetupHandler>& handler,
200513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch              const std::string& status)
201513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        : handler_(handler), status_(status) {
202513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
203513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    void HandleStartActivation() {
204513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (handler_)
205513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        handler_->StartActivation();
206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    void HandleSetTransactionStatus() {
208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (handler_)
209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        handler_->SetTransactionStatus(status_);
210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void ContinueConnecting() {
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (handler_)
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        handler_->ContinueConnecting(delay_);
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    void RetryOTASP() {
216201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (handler_)
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        handler_->RetryOTASP();
218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
219513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch   private:
220513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    base::WeakPtr<MobileSetupHandler> handler_;
221513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    std::string status_;
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    int delay_;
223513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    DISALLOW_COPY_AND_ASSIGN(TaskProxy);
224513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  };
225513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Handlers for JS WebUI messages.
227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  void HandleSetTransactionStatus(const ListValue* args);
228513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void HandleStartActivation(const ListValue* args);
229513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void SetTransactionStatus(const std::string& status);
230201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Schedules activation process via task proxy.
231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void InitiateActivation();
232201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Starts activation.
233513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void StartActivation();
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Retried OTASP.
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void RetryOTASP();
236201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Continues activation process. This method is called after we disconnect
237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // due to detected connectivity issue to kick off reconnection.
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void ContinueConnecting(int delay);
239bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
240bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Sends message to host registration page with system/user info data.
241bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  void SendDeviceInfo();
242bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Callback for when |reconnect_timer_| fires.
24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void ReconnectTimerFired();
24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Starts OTASP process.
24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void StartOTASP();
24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Checks if we need to reconnect due to failed connection attempt.
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool NeedsReconnecting(chromeos::CellularNetwork* network,
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                         PlanActivationState* new_state,
25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                         std::string* error_description);
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Disconnect from network.
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void DisconnectFromNetwork(chromeos::CellularNetwork* network);
2534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Connects to cellular network, resets connection timer.
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool ConnectToNetwork(chromeos::CellularNetwork* network, int delay);
255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Forces disconnect / reconnect when we detect portal connectivity issues.
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void ForceReconnect(chromeos::CellularNetwork* network, int delay);
2574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Reports connection timeout.
2584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool ConnectionTimeout();
259513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Verify the state of cellular network and modify internal state.
260513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void EvaluateCellularNetwork(chromeos::CellularNetwork* network);
261513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Check the current cellular network for error conditions.
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool GotActivationError(chromeos::CellularNetwork* network,
263513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                          std::string* error);
26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Sends status updates to WebUI page.
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void UpdatePage(chromeos::CellularNetwork* network,
2664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                  const std::string& error_description);
2674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Changes internal state.
268513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void ChangeState(chromeos::CellularNetwork* network,
269513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                   PlanActivationState new_state,
270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                   const std::string& error_description);
271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Prepares network devices for cellular activation process.
272513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void SetupActivationProcess(chromeos::CellularNetwork* network);
273201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Disables ethernet and wifi newtorks since they interefere with
274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // detection of restricted pool on cellular side.
275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void DisableOtherNetworks();
276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Resets network devices after cellular activation process.
277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // |network| should be NULL if the activation process failed.
278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void CompleteActivation(chromeos::CellularNetwork* network);
279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Control routines for handling other types of connections during
280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // cellular activation.
281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void ReEnableOtherConnections();
282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Converts the currently active CellularNetwork device into a JS object.
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static void GetDeviceInfo(chromeos::CellularNetwork* network,
285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                            DictionaryValue* value);
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static bool ShouldReportDeviceState(std::string* state, std::string* error);
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Performs activation state cellular device evaluation.
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Returns false if device activation failed. In this case |error|
29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // will contain error message to be reported to Web UI.
291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  static bool EvaluateCellularDeviceState(bool* report_status,
292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                          std::string* state,
293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                          std::string* error);
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Return error message for a given code.
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static std::string GetErrorMessage(const std::string& code);
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static void LoadCellularConfig();
298bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Returns next reconnection state based on the current activation phase.
30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  static PlanActivationState GetNextReconnectState(PlanActivationState state);
301513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  static const char* GetStateDescription(PlanActivationState state);
302513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static scoped_ptr<CellularConfigDocument> cellular_config_;
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TabContents* tab_contents_;
306513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Internal handler state.
307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  PlanActivationState state_;
308513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  std::string service_path_;
309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Flags that control if wifi and ethernet connection needs to be restored
310513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // after the activation of cellular network.
311513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool reenable_wifi_;
312513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool reenable_ethernet_;
313513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool reenable_cert_check_;
3144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool evaluating_;
31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // True if we think that another tab is already running activation.
31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool already_running_;
3174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Connection retry counter.
3184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  int connection_retry_count_;
31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Post payment reconnect wait counters.
32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int reconnect_wait_count_;
321201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Activation retry attempt count;
322201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int activation_attempt_;
3234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Connection start time.
3244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  base::Time connection_start_time_;
32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Timer that monitors reconnection timeouts.
32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::RepeatingTimer<MobileSetupHandler> reconnect_timer_;
32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
328bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(MobileSetupHandler);
329bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
330bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickscoped_ptr<CellularConfigDocument> MobileSetupHandler::cellular_config_;
332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick////////////////////////////////////////////////////////////////////////////////
334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick//
335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// CellularConfigDocument
336731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick//
337731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick////////////////////////////////////////////////////////////////////////////////
338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string CellularConfigDocument::GetErrorMessage(const std::string& code) {
340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::map<std::string, std::string>::iterator iter = error_map_.find(code);
341731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (iter == error_map_.end())
342731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return code;
343731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return iter->second;
344731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
346731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool CellularConfigDocument::LoadFromFile(const FilePath& config_path) {
347731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  error_map_.clear();
348731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
349731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string config;
35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  {
35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Reading config file causes us to do blocking IO on UI thread.
35272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Temporarily allow it until we fix http://crosbug.com/11535
35372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::ThreadRestrictions::ScopedAllowIO allow_io;
35472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!file_util::ReadFileToString(config_path, &config))
35572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
35672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_ptr<Value> root(base::JSONReader::Read(config, true));
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(root.get() != NULL);
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!root.get() || root->GetType() != Value::TYPE_DICTIONARY) {
361513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    LOG(WARNING) << "Bad cellular config file";
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return false;
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get());
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!root_dict->GetString(kVersionField, &version_)) {
367513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    LOG(WARNING) << "Cellular config file missing version";
368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return false;
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DictionaryValue* errors = NULL;
371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!root_dict->GetDictionary(kErrorsField, &errors))
372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return false;
373731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  for (DictionaryValue::key_iterator keys = errors->begin_keys();
374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick       keys != errors->end_keys();
375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick       ++keys) {
376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    std::string value;
377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!errors->GetString(*keys, &value)) {
378513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      LOG(WARNING) << "Bad cellular config error value";
379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      error_map_.clear();
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return false;
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    error_map_.insert(std::pair<std::string, std::string>(*keys, value));
384731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
385731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return true;
386731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
388bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
389bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen//
390bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// MobileSetupUIHTMLSource
391bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen//
392bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
393bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
394513209b27ff55e2841eac0e4120199c23acce758Ben MurdochMobileSetupUIHTMLSource::MobileSetupUIHTMLSource(
395513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const std::string& service_path)
396513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    : DataSource(chrome::kChromeUIMobileSetupHost, MessageLoop::current()),
397513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      service_path_(service_path) {
398bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
399bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
400bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid MobileSetupUIHTMLSource::StartDataRequest(const std::string& path,
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               bool is_incognito,
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               int request_id) {
403dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  chromeos::CellularNetwork* network = GetCellularNetwork(service_path_);
404dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(network);
405bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DictionaryValue strings;
406bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  strings.SetString("title", l10n_util::GetStringUTF16(IDS_MOBILE_SETUP_TITLE));
407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  strings.SetString("connecting_header",
408513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                    l10n_util::GetStringFUTF16(IDS_MOBILE_CONNECTING_HEADER,
409513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                        network ? UTF8ToUTF16(network->name()) : string16()));
410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  strings.SetString("error_header",
411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                    l10n_util::GetStringUTF16(IDS_MOBILE_ERROR_HEADER));
412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  strings.SetString("activating_header",
413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                    l10n_util::GetStringUTF16(IDS_MOBILE_ACTIVATING_HEADER));
414731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  strings.SetString("completed_header",
415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                    l10n_util::GetStringUTF16(IDS_MOBILE_COMPLETED_HEADER));
416201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  strings.SetString("please_wait",
417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                    l10n_util::GetStringUTF16(IDS_MOBILE_PLEASE_WAIT));
418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  strings.SetString("completed_text",
419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                    l10n_util::GetStringUTF16(IDS_MOBILE_COMPLETED_TEXT));
4204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  strings.SetString("close_button",
4214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                    l10n_util::GetStringUTF16(IDS_CLOSE));
422bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SetFontAndTextDirection(&strings);
423bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
424bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  static const base::StringPiece html(
425bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      ResourceBundle::GetSharedInstance().GetRawDataResource(
426bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          IDR_MOBILE_SETUP_PAGE_HTML));
42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
42872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
42972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      html, &strings);
430bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
431bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
432bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  html_bytes->data.resize(full_html.size());
433bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
434bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
435bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SendResponse(request_id, html_bytes);
436bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
437bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
438bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
439bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen//
440bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// MobileSetupHandler
441bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen//
442bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
443513209b27ff55e2841eac0e4120199c23acce758Ben MurdochMobileSetupHandler::MobileSetupHandler(const std::string& service_path)
444513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    : tab_contents_(NULL),
445513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      state_(PLAN_ACTIVATION_PAGE_LOADING),
446513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      service_path_(service_path),
447513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      reenable_wifi_(false),
448513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      reenable_ethernet_(false),
449513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      reenable_cert_check_(false),
4504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      evaluating_(false),
45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      already_running_(false),
452201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      connection_retry_count_(0),
45372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reconnect_wait_count_(0),
454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      activation_attempt_(0) {
455bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
456bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
457bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenMobileSetupHandler::~MobileSetupHandler() {
45872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  reconnect_timer_.Stop();
459513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  chromeos::NetworkLibrary* lib =
460513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
461513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  lib->RemoveNetworkManagerObserver(this);
462513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  lib->RemoveObserverForAllNetworks(this);
46372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (lib->IsLocked())
46472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    lib->Unlock();
465513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ReEnableOtherConnections();
466bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
467bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
46872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWebUIMessageHandler* MobileSetupHandler::Attach(WebUI* web_ui) {
46972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return WebUIMessageHandler::Attach(web_ui);
470bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
471bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
472731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid MobileSetupHandler::Init(TabContents* contents) {
473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  tab_contents_ = contents;
474731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  LoadCellularConfig();
47572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!chromeos::CrosLibrary::Get()->GetNetworkLibrary()->IsLocked())
47672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    SetupActivationProcess(GetCellularNetwork(service_path_));
47772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  else
47872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    already_running_ = true;
479bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
480bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
481bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid MobileSetupHandler::RegisterMessages() {
48272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(kJsApiStartActivation,
483513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      NewCallback(this, &MobileSetupHandler::HandleStartActivation));
48472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback(kJsApiSetTransactionStatus,
485bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewCallback(this, &MobileSetupHandler::HandleSetTransactionStatus));
486bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
487bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
488513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::OnNetworkManagerChanged(
489513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    chromeos::NetworkLibrary* cros) {
490513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
491bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
492513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Note that even though we get here when the service has
493513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // reappeared after disappearing earlier in the activation
494513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // process, there's no need to re-establish the NetworkObserver,
495513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // because the service path remains the same.
496513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  EvaluateCellularNetwork(GetCellularNetwork(service_path_));
497513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
498bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
499513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::OnNetworkChanged(chromeos::NetworkLibrary* cros,
500513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                          const chromeos::Network* network) {
501513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (state_ == PLAN_ACTIVATION_PAGE_LOADING)
502513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return;
503513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(network && network->type() == chromeos::TYPE_CELLULAR);
504dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EvaluateCellularNetwork(GetCellularNetwork(network->service_path()));
505731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
506731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
507513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::HandleStartActivation(const ListValue* args) {
508201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  InitiateActivation();
5094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  UMA_HISTOGRAM_COUNTS("Cellular.MobileSetupStart", 1);
510513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
511513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
512bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid MobileSetupHandler::HandleSetTransactionStatus(const ListValue* args) {
513bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  const size_t kSetTransactionStatusParamCount = 1;
514bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (args->GetSize() != kSetTransactionStatusParamCount)
515bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
516bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Get change callback function name.
517bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  std::string status;
518bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!args->GetString(0, &status))
519bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
520513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), status);
521513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
522513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      NewRunnableMethod(task.get(), &TaskProxy::HandleSetTransactionStatus));
523513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
524bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
525201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid MobileSetupHandler::InitiateActivation() {
52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), 0);
527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
528201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      NewRunnableMethod(task.get(), &TaskProxy::HandleStartActivation));
529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
531513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::StartActivation() {
532513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  chromeos::NetworkLibrary* lib =
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
535513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  chromeos::CellularNetwork* network = GetCellularNetwork(service_path_);
53672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check if we can start activation process.
53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!network || already_running_) {
53872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    std::string error;
53972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (already_running_)
54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error = kErrorAlreadyRunning;
54172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    else if (!lib->cellular_available())
54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error = kErrorNoDevice;
54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    else if (!lib->cellular_enabled())
54472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error = kErrorDisabled;
54572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    else
54672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      error = kErrorNoService;
54772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ChangeState(NULL, PLAN_ACTIVATION_ERROR, GetErrorMessage(error));
548bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    return;
549513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
55072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
551513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Start monitoring network property changes.
552513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  lib->AddNetworkManagerObserver(this);
553513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  lib->RemoveObserverForAllNetworks(this);
554513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  lib->AddNetworkObserver(network->service_path(), this);
55572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Try to start with OTASP immediately if we have received payment recently.
55672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  state_ = lib->HasRecentCellularPlanPayment() ?
55772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen               PLAN_ACTIVATION_START_OTASP :
55872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen               PLAN_ACTIVATION_START;
559513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  EvaluateCellularNetwork(network);
560513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
561731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
56272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MobileSetupHandler::RetryOTASP() {
56372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(state_ == PLAN_ACTIVATION_DELAY_OTASP);
56572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  StartOTASP();
56672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
56772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MobileSetupHandler::ContinueConnecting(int delay) {
569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
570201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  chromeos::CellularNetwork* network = GetCellularNetwork(service_path_);
57172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (network && network->connecting_or_connected()) {
57272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EvaluateCellularNetwork(network);
57372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
57472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ConnectToNetwork(network, delay);
57572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
576201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
577201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
578513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::SetTransactionStatus(const std::string& status) {
579513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
580513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // The payment is received, try to reconnect and check the status all over
581513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // again.
582513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (LowerCaseEqualsASCII(status, "ok") &&
583513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      state_ == PLAN_ACTIVATION_SHOWING_PAYMENT) {
58472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    chromeos::NetworkLibrary* lib =
58572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        chromeos::CrosLibrary::Get()->GetNetworkLibrary();
58672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    lib->SignalCellularPlanPayment();
5874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    UMA_HISTOGRAM_COUNTS("Cellular.PaymentReceived", 1);
58872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    StartOTASP();
5894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else {
5904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    UMA_HISTOGRAM_COUNTS("Cellular.PaymentFailed", 1);
591513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
592513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
593513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
59472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MobileSetupHandler::StartOTASP() {
59572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  state_ = PLAN_ACTIVATION_START_OTASP;
59672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  chromeos::CellularNetwork* network = GetCellularNetwork();
59772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (network &&
59872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      network->connected() &&
59972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      network->activation_state() == chromeos::ACTIVATION_STATE_ACTIVATED) {
60072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        DisconnectFromNetwork(network);
60272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
60372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EvaluateCellularNetwork(network);
60472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
60572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
60672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
60772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MobileSetupHandler::ReconnectTimerFired() {
60872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
60972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Permit network connection changes only in reconnecting states.
61072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (state_ != PLAN_ACTIVATION_RECONNECTING_OTASP_TRY &&
61172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      state_ != PLAN_ACTIVATION_RECONNECTING &&
61272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      state_ != PLAN_ACTIVATION_RECONNECTING_OTASP)
61372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
61472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  chromeos::CellularNetwork* network = GetCellularNetwork(service_path_);
61572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!network) {
61672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // No service, try again since this is probably just transient condition.
61772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    LOG(WARNING) << "Service not present at reconnect attempt.";
61872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
61972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EvaluateCellularNetwork(network);
62072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
6214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
62272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid MobileSetupHandler::DisconnectFromNetwork(
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chromeos::CellularNetwork* network) {
624dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(network);
625dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  LOG(INFO) << "Disconnecting from: " << network->service_path();
62672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DisconnectFromNetwork(network);
62872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Disconnect will force networks to be reevaluated, so
62972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // we don't want to continue processing on this path anymore.
63072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  evaluating_ = false;
63172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
63272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
633dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool MobileSetupHandler::NeedsReconnecting(
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chromeos::CellularNetwork* network,
635dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    PlanActivationState* new_state,
636dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    std::string* error_description) {
637dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(network);
63872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!network->failed() && !ConnectionTimeout())
63972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return false;
64072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
64172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Try to reconnect again if reconnect failed, or if for some
64272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // reasons we are still not connected after 45 seconds.
64372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int max_retries = (state_ == PLAN_ACTIVATION_RECONNECTING_OTASP) ?
64472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        kMaxConnectionRetryOTASP : kMaxConnectionRetry;
64572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (connection_retry_count_ < max_retries) {
64672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    UMA_HISTOGRAM_COUNTS("Cellular.ConnectionRetry", 1);
64772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ConnectToNetwork(network, kFailedReconnectDelayMS);
64872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
64972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
65072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We simply can't connect anymore after all these tries.
65172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UMA_HISTOGRAM_COUNTS("Cellular.ConnectionFailed", 1);
65272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  *new_state = PLAN_ACTIVATION_ERROR;
65372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  *error_description = GetErrorMessage(kFailedConnectivity);
65472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return false;
65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
65672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
657dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool MobileSetupHandler::ConnectToNetwork(
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chromeos::CellularNetwork* network,
659dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    int delay) {
66072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (network && network->connecting_or_connected())
66172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
66272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Permit network connection changes only in reconnecting states.
66372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (state_ != PLAN_ACTIVATION_RECONNECTING_OTASP_TRY &&
66472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      state_ != PLAN_ACTIVATION_RECONNECTING &&
66572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      state_ != PLAN_ACTIVATION_RECONNECTING_OTASP)
66672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return false;
667dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (network)
668dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG(INFO) << "Connecting to: " << network->service_path();
6694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  connection_retry_count_++;
6704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  connection_start_time_ = base::Time::Now();
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!network) {
672dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG(WARNING) << "Connect failed."
673dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                 << (network ? network->service_path().c_str() : "no service");
67472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // If we coudn't connect during reconnection phase, try to reconnect
67572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // with a delay (and try to reconnect if needed).
67672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(),
67772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                  delay);
67872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
67972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NewRunnableMethod(task.get(), &TaskProxy::ContinueConnecting),
68072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        delay);
68172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return false;
682201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ConnectToCellularNetwork(network);
68572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return true;
686201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
687201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
688dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid MobileSetupHandler::ForceReconnect(
689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chromeos::CellularNetwork* network,
690dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    int delay) {
691201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK(network);
692201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  UMA_HISTOGRAM_COUNTS("Cellular.ActivationRetry", 1);
693201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Reset reconnect metrics.
694201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  connection_retry_count_ = 0;
695201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  connection_start_time_ = base::Time();
696201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // First, disconnect...
697dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  LOG(INFO) << "Disconnecting from " << network->service_path();
6984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      DisconnectFromNetwork(network);
700201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Check the network state 3s after we disconnect to make sure.
701201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(),
70272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                delay);
703201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
70472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableMethod(task.get(), &TaskProxy::ContinueConnecting),
70572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      delay);
7064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
7074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
7084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool MobileSetupHandler::ConnectionTimeout() {
7094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  return (base::Time::Now() -
7104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            connection_start_time_).InSeconds() > kConnectionTimeoutSeconds;
7114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
7124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
713513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::EvaluateCellularNetwork(
714513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    chromeos::CellularNetwork* network) {
71572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!web_ui_)
716513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return;
717bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
718513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  PlanActivationState new_state = state_;
7194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (!network) {
720513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    LOG(WARNING) << "Cellular service lost";
72172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (state_ == PLAN_ACTIVATION_RECONNECTING_OTASP_TRY ||
72272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        state_ == PLAN_ACTIVATION_RECONNECTING ||
72372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        state_ == PLAN_ACTIVATION_RECONNECTING_OTASP) {
724201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      // This might be the legit case when service is lost after activation.
725201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      // We need to make sure we force reconnection as soon as it shows up.
726201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      LOG(INFO) << "Force service reconnection";
727201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      connection_start_time_ = base::Time();
728201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
7294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return;
730bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
7314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
7324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Prevent this method from being called if it is already on the stack.
7334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // This might happen on some state transitions (ie. connect, disconnect).
7344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (evaluating_)
7354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return;
7364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  evaluating_ = true;
737201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::string error_description;
7384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
73972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  LOG(WARNING) << "Cellular:\n  service=" << network->GetStateString().c_str()
74072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << "\n  ui=" << GetStateDescription(state_)
74172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << "\n  activation=" << network->GetActivationStateString().c_str()
74272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << "\n  connectivity="
74372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << network->GetConnectivityStateString().c_str()
74472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << "\n  error=" << network->GetErrorString().c_str()
74572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << "\n  setvice_path=" << network->service_path().c_str();
746513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  switch (state_) {
7474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    case PLAN_ACTIVATION_START: {
7484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      switch (network->activation_state()) {
7494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        case chromeos::ACTIVATION_STATE_ACTIVATED: {
7504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          if (network->failed_or_disconnected()) {
7514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            new_state = PLAN_ACTIVATION_RECONNECTING;
7524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          } else if (network->connected()) {
7534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            if (network->restricted_pool()) {
7544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
7554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            } else {
7564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              new_state = PLAN_ACTIVATION_DONE;
757513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            }
7584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          }
7594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
7604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        }
76172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        default: {
76272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          if (network->failed_or_disconnected() ||
763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
76472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            new_state = (network->activation_state() ==
76572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                         chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) ?
76672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                            PLAN_ACTIVATION_TRYING_OTASP :
76772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                            PLAN_ACTIVATION_INITIATING_ACTIVATION;
76872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          } else if (network->connected()) {
76972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            DisconnectFromNetwork(network);
77072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            return;
7714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          }
7724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
7734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        }
77472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
77572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
77672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
77772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_START_OTASP: {
77872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switch (network->activation_state()) {
77972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED: {
7804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          if (network->failed_or_disconnected()) {
78172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            new_state = PLAN_ACTIVATION_OTASP;
7824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          } else if (network->connected()) {
78372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            DisconnectFromNetwork(network);
7844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            return;
7854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          }
7864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
787513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        }
78872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case chromeos::ACTIVATION_STATE_ACTIVATED:
78972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new_state = PLAN_ACTIVATION_RECONNECTING_OTASP;
79072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          break;
79172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        default: {
79272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          LOG(WARNING) << "Unexpected activation state for device "
79372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       << network->service_path().c_str();
7944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
79572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        }
796513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      }
797513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
7984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
79972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_DELAY_OTASP:
80072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // Just ignore any changes until the OTASP retry timer kicks in.
80172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      evaluating_ = false;
80272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return;
80372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_INITIATING_ACTIVATION:
80472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_OTASP:
80572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_TRYING_OTASP: {
8064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      switch (network->activation_state()) {
8074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        case chromeos::ACTIVATION_STATE_ACTIVATED:
8084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          if (network->failed_or_disconnected()) {
80972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            new_state = GetNextReconnectState(state_);
8104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          } else if (network->connected()) {
8114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            if (network->restricted_pool()) {
8124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
8134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            } else {
8144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              new_state = PLAN_ACTIVATION_DONE;
815513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            }
8164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          }
8174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
8184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
8194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          if (network->connected()) {
8204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            if (network->restricted_pool())
821513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch              new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
8224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          } else {
82372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            new_state = GetNextReconnectState(state_);
8244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          }
8254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
8264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        case chromeos::ACTIVATION_STATE_NOT_ACTIVATED:
8274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        case chromeos::ACTIVATION_STATE_ACTIVATING:
82872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          // Wait in this state until activation state changes.
8294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
8304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        default:
8314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          break;
832513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      }
833513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
8344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
83572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
8364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    case PLAN_ACTIVATION_RECONNECTING: {
8374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      if (network->connected()) {
838201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        // Make sure other networks are not interfering with our detection of
839201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        // restricted pool.
840201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        DisableOtherNetworks();
8414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        // Wait until the service shows up and gets activated.
842513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        switch (network->activation_state()) {
843201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
844513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          case chromeos::ACTIVATION_STATE_ACTIVATED:
845201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            if (network->connectivity_state() ==
846201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                         chromeos::CONN_STATE_NONE) {
847201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              LOG(WARNING) << "No connectivity for device "
848201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                           << network->service_path().c_str();
849201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              // If we are connected but there is no connectivity at all,
850201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              // restart the whole process again.
851201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              if (activation_attempt_ < kMaxActivationAttempt) {
852201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                activation_attempt_++;
85372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                LOG(WARNING) << "Reconnect attempt #"
85472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             << activation_attempt_;
85572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                ForceReconnect(network, kFailedReconnectDelayMS);
856201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                evaluating_ = false;
857201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                return;
858201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              } else {
85972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                new_state = PLAN_ACTIVATION_ERROR;
860201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                UMA_HISTOGRAM_COUNTS("Cellular.ActivationRetryFailure", 1);
861201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                error_description = GetErrorMessage(kFailedConnectivity);
862201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch              }
863201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            } else if (network->connectivity_state() ==
86472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                           chromeos::CONN_STATE_RESTRICTED) {
86572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              // If we have already received payment, don't show the payment
86672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              // page again. We should try to reconnect after some time instead.
8674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              new_state = PLAN_ACTIVATION_SHOWING_PAYMENT;
868201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            } else if (network->activation_state() ==
869201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                           chromeos::ACTIVATION_STATE_ACTIVATED) {
8704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              new_state = PLAN_ACTIVATION_DONE;
871201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            }
872513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            break;
873513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          default:
874513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            break;
875513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        }
87672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else if (NeedsReconnecting(network, &new_state, &error_description)) {
87772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        evaluating_ = false;
87872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        return;
87972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
88072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
88172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
88272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP: {
88372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (network->connected()) {
88472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Make sure other networks are not interfering with our detection of
88572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // restricted pool.
88672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        DisableOtherNetworks();
88772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Wait until the service shows up and gets activated.
88872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        switch (network->activation_state()) {
88972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          case chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED:
89072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          case chromeos::ACTIVATION_STATE_ACTIVATED:
89172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            if (network->connectivity_state() == chromeos::CONN_STATE_NONE ||
89272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                network->connectivity_state() ==
89372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                    chromeos::CONN_STATE_RESTRICTED) {
89472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              LOG(WARNING) << "Still no connectivity after OTASP for device "
89572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                           << network->service_path().c_str();
89672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              // If we have already received payment, don't show the payment
89772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              // page again. We should try to reconnect after some time instead.
89872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              if (reconnect_wait_count_ < kMaxReconnectAttemptOTASP) {
89972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                reconnect_wait_count_++;
90072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                LOG(WARNING) << "OTASP reconnect attempt #"
90172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             << reconnect_wait_count_;
90272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                ForceReconnect(network, kPostPaymentReconnectDelayMS);
90372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                evaluating_ = false;
90472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                return;
90572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              } else {
90672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                new_state = PLAN_ACTIVATION_ERROR;
90772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                UMA_HISTOGRAM_COUNTS("Cellular.PostPaymentConnectFailure", 1);
90872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                error_description = GetErrorMessage(kFailedConnectivity);
90972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              }
91072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            } else if (network->connectivity_state() ==
91172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                           chromeos::CONN_STATE_UNRESTRICTED) {
91272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              new_state = PLAN_ACTIVATION_DONE;
91372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            }
91472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            break;
91572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          default:
91672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            break;
9174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        }
91872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else if (NeedsReconnecting(network, &new_state, &error_description)) {
91972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        evaluating_ = false;
92072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        return;
921513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      }
922513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
9234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
924513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_PAGE_LOADING:
925513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
926513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // Just ignore all signals until the site confirms payment.
927513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_SHOWING_PAYMENT:
928513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // Activation completed/failed, ignore network changes.
929513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_DONE:
930513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_ERROR:
931513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
932513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
933513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
9344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (new_state != PLAN_ACTIVATION_ERROR &&
9354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      GotActivationError(network, &error_description)) {
9364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Check for this special case when we try to do activate partially
9374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // activated device. If that attempt failed, try to disconnect to clear the
9384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // state and reconnect again.
9394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if ((network->activation_state() ==
9404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch            chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED ||
9414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        network->activation_state() == chromeos::ACTIVATION_STATE_ACTIVATING) &&
9423dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen        (network->error() == chromeos::ERROR_NO_ERROR ||
94372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            network->error() == chromeos::ERROR_OTASP_FAILED) &&
944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
94572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      LOG(WARNING) << "Activation failure detected "
94672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                   << network->service_path().c_str();
94772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      switch (state_) {
94872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_OTASP:
94972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_RECONNECTING_OTASP:
95072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new_state = PLAN_ACTIVATION_DELAY_OTASP;
95172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          break;
95272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_TRYING_OTASP:
95372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new_state = PLAN_ACTIVATION_RECONNECTING_OTASP_TRY;
95472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          break;
95572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_INITIATING_ACTIVATION:
95672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new_state = PLAN_ACTIVATION_RECONNECTING;
95772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          break;
95872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_START:
95972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          // We are just starting, so this must be previous activation attempt
96072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          // failure.
96172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new_state = PLAN_ACTIVATION_TRYING_OTASP;
96272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          break;
96372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_DELAY_OTASP:
96472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
96572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        case PLAN_ACTIVATION_RECONNECTING:
96672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new_state = state_;
96772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          break;
96872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        default:
96972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          new_state = PLAN_ACTIVATION_ERROR;
97072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          break;
97172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
9724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    } else {
97372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      LOG(WARNING) << "Unexpected activation failure for "
97472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                   << network->service_path().c_str();
9754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      new_state = PLAN_ACTIVATION_ERROR;
9764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
977513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
97872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
97972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (new_state == PLAN_ACTIVATION_ERROR && !error_description.length())
98072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    error_description = GetErrorMessage(kErrorDefault);
98172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
982513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ChangeState(network, new_state, error_description);
9834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  evaluating_ = false;
984bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
985bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
98672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMobileSetupHandler::PlanActivationState
98772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    MobileSetupHandler::GetNextReconnectState(
98872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        MobileSetupHandler::PlanActivationState state) {
98972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  switch (state) {
99072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_INITIATING_ACTIVATION:
99172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return PLAN_ACTIVATION_RECONNECTING;
99272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_OTASP:
99372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return PLAN_ACTIVATION_RECONNECTING_OTASP;
99472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_TRYING_OTASP:
99572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return PLAN_ACTIVATION_RECONNECTING_OTASP_TRY;
99672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    default:
99772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return PLAN_ACTIVATION_RECONNECTING;
99872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
99972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
100072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1001513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Debugging helper function, will take it out at the end.
1002513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst char* MobileSetupHandler::GetStateDescription(
1003513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    PlanActivationState state) {
1004513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  switch (state) {
1005513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_PAGE_LOADING:
1006513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return "PAGE_LOADING";
1007513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_START:
1008513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return "ACTIVATION_START";
100972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_TRYING_OTASP:
101072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return "TRYING_OTASP";
101172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
101272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return "RECONNECTING_OTASP_TRY";
1013513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_INITIATING_ACTIVATION:
1014513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return "INITIATING_ACTIVATION";
1015513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_RECONNECTING:
1016513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return "RECONNECTING";
1017513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_SHOWING_PAYMENT:
1018513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return "SHOWING_PAYMENT";
101972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_START_OTASP:
102072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return "START_OTASP";
102172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_DELAY_OTASP:
102272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return "DELAY_OTASP";
102372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_OTASP:
102472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return "OTASP";
102572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP:
102672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return "RECONNECTING_OTASP";
1027513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_DONE:
1028513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return "DONE";
1029513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_ERROR:
1030513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return "ERROR";
1031513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
1032513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return "UNKNOWN";
1033513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
1034513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1035513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1036513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::CompleteActivation(
1037513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    chromeos::CellularNetwork* network) {
1038513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Remove observers, we are done with this page.
1039513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
1040513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GetNetworkLibrary();
104172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  lib->RemoveNetworkManagerObserver(this);
104272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  lib->RemoveObserverForAllNetworks(this);
104372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (lib->IsLocked())
104472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    lib->Unlock();
1045513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // If we have successfully activated the connection, set autoconnect flag.
1046dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (network)
1047dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    network->SetAutoConnect(true);
1048513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Reactivate other types of connections if we have
1049513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // shut them down previously.
1050513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ReEnableOtherConnections();
1051513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
1052513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1053dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid MobileSetupHandler::UpdatePage(
1054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chromeos::CellularNetwork* network,
1055dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const std::string& error_description) {
10564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DictionaryValue device_dict;
10574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (network)
10584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    GetDeviceInfo(network, &device_dict);
10594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  device_dict.SetInteger("state", state_);
10604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (error_description.length())
10614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    device_dict.SetString("error", error_description);
106272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->CallJavascriptFunction(
10634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      kJsDeviceStatusChangedHandler, device_dict);
10644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
1065513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
106672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1067513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::ChangeState(chromeos::CellularNetwork* network,
1068513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                     PlanActivationState new_state,
1069513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                     const std::string& error_description) {
1070513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  static bool first_time = true;
1071513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (state_ == new_state && !first_time)
1072513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return;
107372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  LOG(WARNING) << "Activation state flip old = "
107472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << GetStateDescription(state_)
107572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      << ", new = " << GetStateDescription(new_state);
1076513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  first_time = false;
107772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
107872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Pick action that should happen on leaving the old state.
107972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  switch (state_) {
108072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
108172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING:
108272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP:
108372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (reconnect_timer_.IsRunning()) {
108472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reconnect_timer_.Stop();
108572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
108672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
108772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    default:
108872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
108972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
1090513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  state_ = new_state;
1091513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1092513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Signal to JS layer that the state is changing.
10934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  UpdatePage(network, error_description);
1094513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
109572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Pick action that should happen on entering the new state.
1096513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  switch (new_state) {
1097513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_START:
1098513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
109972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_DELAY_OTASP: {
110072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      UMA_HISTOGRAM_COUNTS("Cellular.RetryOTASP", 1);
110172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), 0);
110272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE,
110372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          NewRunnableMethod(task.get(), &TaskProxy::RetryOTASP),
110472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          kOTASPRetryDelay);
110572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      break;
110672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
1107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_INITIATING_ACTIVATION:
110872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_TRYING_OTASP:
110972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_OTASP:
1110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      DCHECK(network);
111172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      LOG(WARNING) << "Activating service " << network->service_path().c_str();
11124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      UMA_HISTOGRAM_COUNTS("Cellular.ActivationTry", 1);
11134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      if (!network->StartActivation()) {
11144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        UMA_HISTOGRAM_COUNTS("Cellular.ActivationFailure", 1);
111572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (new_state == PLAN_ACTIVATION_OTASP) {
111672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          ChangeState(network, PLAN_ACTIVATION_DELAY_OTASP, std::string());
111772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        } else {
111872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          ChangeState(network, PLAN_ACTIVATION_ERROR,
111972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                      GetErrorMessage(kFailedConnectivity));
112072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        }
11214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      }
1122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
112372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP_TRY:
112472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING:
112572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_RECONNECTING_OTASP: {
112672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // Start reconnect timer. This will ensure that we are not left in
112772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // limbo by the network library.
112872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (!reconnect_timer_.IsRunning()) {
112972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        reconnect_timer_.Start(
113072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            base::TimeDelta::FromMilliseconds(kReconnectTimerDelayMS),
113172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            this, &MobileSetupHandler::ReconnectTimerFired);
113272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
11334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // Reset connection metrics and try to connect.
113472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      reconnect_wait_count_ = 0;
11354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      connection_retry_count_ = 0;
11364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      connection_start_time_ = base::Time::Now();
113772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ConnectToNetwork(network, kReconnectDelayMS);
1138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
1139513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
1140513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_PAGE_LOADING:
1141513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return;
1142513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_SHOWING_PAYMENT:
1143513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // Fix for fix SSL for the walled gardens where cert chain verification
1144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // might not work.
1145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
1146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case PLAN_ACTIVATION_DONE:
1147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      DCHECK(network);
1148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      CompleteActivation(network);
11494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      UMA_HISTOGRAM_COUNTS("Cellular.MobileSetupSucceeded", 1);
1150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
115172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case PLAN_ACTIVATION_ERROR:
1152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      CompleteActivation(NULL);
11534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      UMA_HISTOGRAM_COUNTS("Cellular.PlanFailed", 1);
1154513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
1155513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    default:
1156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      break;
1157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
1158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
1159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1160513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::ReEnableOtherConnections() {
1161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
1162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GetNetworkLibrary();
1163513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (reenable_ethernet_) {
1164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    reenable_ethernet_ = false;
1165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    lib->EnableEthernetNetworkDevice(true);
1166731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1167513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (reenable_wifi_) {
1168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    reenable_wifi_ = false;
1169513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    lib->EnableWifiNetworkDevice(true);
1170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
1171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PrefService* prefs = g_browser_process->local_state();
1173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (reenable_cert_check_) {
1174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    prefs->SetBoolean(prefs::kCertRevocationCheckingEnabled,
1175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                      true);
1176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    reenable_cert_check_ = false;
1177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
1179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1180513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid MobileSetupHandler::SetupActivationProcess(
1181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    chromeos::CellularNetwork* network) {
1182513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!network)
1183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return;
1184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Disable SSL cert checks since we will be doing this in
1186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // restricted pool.
1187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PrefService* prefs = g_browser_process->local_state();
1188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (!reenable_cert_check_ &&
1189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      prefs->GetBoolean(
1190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          prefs::kCertRevocationCheckingEnabled)) {
1191513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    reenable_cert_check_ = true;
1192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    prefs->SetBoolean(prefs::kCertRevocationCheckingEnabled, false);
1193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
1196513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      GetNetworkLibrary();
1197513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Disable autoconnect to cellular network.
1198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  network->SetAutoConnect(false);
1199513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
120072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Prevent any other network interference.
1201201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DisableOtherNetworks();
120272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  lib->Lock();
1203201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1204201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid MobileSetupHandler::DisableOtherNetworks() {
1206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  chromeos::NetworkLibrary* lib = chromeos::CrosLibrary::Get()->
1207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      GetNetworkLibrary();
1208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Disable ethernet and wifi.
1209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (lib->ethernet_enabled()) {
1210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    reenable_ethernet_ = true;
1211513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    lib->EnableEthernetNetworkDevice(false);
1212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
1213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (lib->wifi_enabled()) {
1214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    reenable_wifi_ = true;
1215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    lib->EnableWifiNetworkDevice(false);
1216513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
1217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1219513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool MobileSetupHandler::GotActivationError(
1220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    chromeos::CellularNetwork* network, std::string* error) {
12214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK(network);
1222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool got_error = false;
1223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* error_code = kErrorDefault;
1224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1225513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // This is the magic for detection of errors in during activation process.
1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (network->state() == chromeos::STATE_FAILURE &&
1227201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      network->error() == chromeos::ERROR_AAA_FAILED) {
1228513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (network->activation_state() ==
1229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
1230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      error_code = kErrorBadConnectionPartial;
1231513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    } else if (network->activation_state() ==
1232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            chromeos::ACTIVATION_STATE_ACTIVATED) {
1233513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (network->roaming_state() == chromeos::ROAMING_STATE_HOME) {
1234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        error_code = kErrorBadConnectionActivated;
1235513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      } else if (network->roaming_state() == chromeos::ROAMING_STATE_ROAMING) {
1236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        error_code = kErrorRoamingOnConnection;
1237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
1238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
1239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    got_error = true;
1240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (network->state() == chromeos::STATE_ACTIVATION_FAILURE) {
1241513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (network->error() == chromeos::ERROR_NEED_EVDO) {
1242513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (network->activation_state() ==
1243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick              chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED)
1244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        error_code = kErrorNoEVDO;
1245513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    } else if (network->error() == chromeos::ERROR_NEED_HOME_NETWORK) {
1246513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      if (network->activation_state() ==
1247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick              chromeos::ACTIVATION_STATE_NOT_ACTIVATED) {
1248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        error_code = kErrorRoamingActivation;
1249513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      } else if (network->activation_state() ==
1250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                    chromeos::ACTIVATION_STATE_PARTIALLY_ACTIVATED) {
1251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        error_code = kErrorRoamingPartiallyActivated;
1252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
1253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
1254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    got_error = true;
1255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1256731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1257731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (got_error)
1258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    *error = GetErrorMessage(error_code);
1259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1260513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return got_error;
1261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1262bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid MobileSetupHandler::GetDeviceInfo(chromeos::CellularNetwork* network,
1264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                       DictionaryValue* value) {
1265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(network);
1266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  chromeos::NetworkLibrary* cros =
1267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      chromeos::CrosLibrary::Get()->GetNetworkLibrary();
1268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!cros)
1269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
1270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  value->SetString("carrier", network->name());
1271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  value->SetString("payment_url", network->payment_url());
1272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  const chromeos::NetworkDevice* device =
1273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      cros->FindNetworkDeviceByPath(network->device_path());
1274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (device) {
1275dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    value->SetString("MEID", device->meid());
1276dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    value->SetString("IMEI", device->imei());
1277dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    value->SetString("MDN", device->mdn());
1278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1279bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
1280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string MobileSetupHandler::GetErrorMessage(const std::string& code) {
1282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!cellular_config_.get())
1283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return "";
1284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return cellular_config_->GetErrorMessage(code);
1285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid MobileSetupHandler::LoadCellularConfig() {
1288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static bool config_loaded = false;
1289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (config_loaded)
1290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return;
1291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  config_loaded = true;
1292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Load partner customization startup manifest if it is available.
1293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  FilePath config_path(kCellularConfigPath);
129472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool config_exists = false;
129572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  {
129672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Reading config file causes us to do blocking IO on UI thread.
129772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Temporarily allow it until we fix http://crosbug.com/11535
129872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    base::ThreadRestrictions::ScopedAllowIO allow_io;
129972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    config_exists = file_util::PathExists(config_path);
130072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
130172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (config_exists) {
1302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    scoped_ptr<CellularConfigDocument> config(new CellularConfigDocument());
1303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool config_loaded = config->LoadFromFile(config_path);
1304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (config_loaded) {
1305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      LOG(INFO) << "Cellular config file loaded: " << kCellularConfigPath;
1306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // lock
1307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      cellular_config_.reset(config.release());
1308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    } else {
1309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      LOG(ERROR) << "Error loading cellular config file: " <<
1310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          kCellularConfigPath;
1311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
1312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
1313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
1314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1316bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
1317bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen//
1318bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// MobileSetupUI
1319bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen//
1320bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
1321bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
132272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMobileSetupUI::MobileSetupUI(TabContents* contents) : WebUI(contents) {
1323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  chromeos::CellularNetwork* network = GetCellularNetwork();
1324513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  std::string service_path = network ? network->service_path() : std::string();
1325513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  MobileSetupHandler* handler = new MobileSetupHandler(service_path);
1326bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  AddMessageHandler((handler)->Attach(this));
1327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  handler->Init(contents);
1328513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  MobileSetupUIHTMLSource* html_source =
1329513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      new MobileSetupUIHTMLSource(service_path);
1330bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
1331bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Set up the chrome://mobilesetup/ source.
133272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
1333bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
1334