1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/network_state_notifier.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/cros_library.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h"
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_type.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace chromeos {
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenNetworkStateNotifier* NetworkStateNotifier::GetInstance() {
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return Singleton<NetworkStateNotifier>::get();
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTimeDelta NetworkStateNotifier::GetOfflineDuration() {
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(oshima): make this instance method so that
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // we can mock this for ui_tests.
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // http://crbug.com/4825 .
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base::Time::Now() - GetInstance()->offline_start_time_;
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetworkStateNotifier::NetworkStateNotifier()
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      state_(RetrieveState()),
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      offline_start_time_(Time::Now()) {
37513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Note that this gets added as a NetworkManagerObserver
38513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // in browser_init.cc
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41513209b27ff55e2841eac0e4120199c23acce758Ben MurdochNetworkStateNotifier::~NetworkStateNotifier() {
42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Let the NetworkManagerObserver leak to avoid a DCHECK
43513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // failure in CommandLine::ForCurrentProcess.
44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch//  if (CrosLibrary::Get()->EnsureLoaded())
45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch//    CrosLibrary::Get()->GetNetworkLibrary()->
46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch//        RemoveNetworkManagerObserver(this);
47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
48513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
49513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid NetworkStateNotifier::OnNetworkManagerChanged(NetworkLibrary* cros) {
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(CrosLibrary::Get()->EnsureLoaded());
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Update the state 500ms later using UI thread.
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // See http://crosbug.com/4558
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostDelayedTask(
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      task_factory_.NewRunnableMethod(
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &NetworkStateNotifier::UpdateNetworkState,
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          RetrieveState()),
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      500);
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid NetworkStateNotifier::UpdateNetworkState(
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetworkStateDetails::State new_state) {
63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DVLOG(1) << "UpdateNetworkState: new=" << new_state << ", old=" << state_;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (state_ == NetworkStateDetails::CONNECTED &&
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new_state != NetworkStateDetails::CONNECTED) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    offline_start_time_ = Time::Now();
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  state_ = new_state;
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetworkStateDetails details(state_);
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::NETWORK_STATE_CHANGED,
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources(),
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Details<NetworkStateDetails>(&details));
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochNetworkStateDetails::State NetworkStateNotifier::RetrieveState() {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Running on desktop means always connected, for now.
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!CrosLibrary::Get()->EnsureLoaded())
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NetworkStateDetails::CONNECTED;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (cros->Connected()) {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NetworkStateDetails::CONNECTED;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (cros->Connecting()) {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NetworkStateDetails::CONNECTING;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NetworkStateDetails::DISCONNECTED;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace chromeos
94