update_library.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chromeos/cros/update_library.h"
6
7#include "base/message_loop.h"
8#include "base/string_util.h"
9#include "chrome/browser/chromeos/cros/cros_library.h"
10#include "content/browser/browser_thread.h"
11#include "content/common/notification_service.h"
12#include "content/common/notification_type.h"
13
14namespace chromeos {
15
16class UpdateLibraryImpl : public UpdateLibrary {
17 public:
18  UpdateLibraryImpl()
19    : status_connection_(NULL) {
20    if (CrosLibrary::Get()->EnsureLoaded()) {
21      Init();
22    }
23  }
24
25  ~UpdateLibraryImpl() {
26    if (status_connection_) {
27      DisconnectUpdateProgress(status_connection_);
28    }
29  }
30
31  void AddObserver(Observer* observer) {
32    observers_.AddObserver(observer);
33  }
34
35  void RemoveObserver(Observer* observer) {
36    observers_.RemoveObserver(observer);
37  }
38
39  bool CheckForUpdate() {
40    if (!CrosLibrary::Get()->EnsureLoaded())
41      return false;
42
43    return InitiateUpdateCheck();
44  }
45
46  bool RebootAfterUpdate() {
47    if (!CrosLibrary::Get()->EnsureLoaded())
48      return false;
49
50    return RebootIfUpdated();
51  }
52
53  bool SetReleaseTrack(const std::string& track) {
54    if (!CrosLibrary::Get()->EnsureLoaded())
55      return false;
56
57    return chromeos::SetTrack(track);
58  }
59
60  std::string GetReleaseTrack() {
61    if (!CrosLibrary::Get()->EnsureLoaded())
62      return "";
63
64    return chromeos::GetTrack();
65  }
66
67  const UpdateLibrary::Status& status() const {
68    return status_;
69  }
70
71 private:
72  static void ChangedHandler(void* object,
73      const UpdateProgress& status) {
74    UpdateLibraryImpl* updater = static_cast<UpdateLibraryImpl*>(object);
75    updater->UpdateStatus(Status(status));
76  }
77
78  void Init() {
79    status_connection_ = MonitorUpdateStatus(&ChangedHandler, this);
80  }
81
82  void UpdateStatus(const Status& status) {
83    // Make sure we run on UI thread.
84    if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
85      BrowserThread::PostTask(
86          BrowserThread::UI, FROM_HERE,
87          NewRunnableMethod(this, &UpdateLibraryImpl::UpdateStatus, status));
88      return;
89    }
90
91    status_ = status;
92    FOR_EACH_OBSERVER(Observer, observers_, UpdateStatusChanged(this));
93
94    // If the update is ready to install, send a notification so that Chrome
95    // can update the UI.
96    if (status_.status == UPDATE_STATUS_UPDATED_NEED_REBOOT) {
97      NotificationService::current()->Notify(
98          NotificationType::UPGRADE_RECOMMENDED,
99          Source<UpdateLibrary>(this),
100          NotificationService::NoDetails());
101    }
102  }
103
104  ObserverList<Observer> observers_;
105
106  // A reference to the update api, to allow callbacks when the update
107  // status changes.
108  UpdateStatusConnection status_connection_;
109
110  // The latest power status.
111  Status status_;
112
113  DISALLOW_COPY_AND_ASSIGN(UpdateLibraryImpl);
114};
115
116class UpdateLibraryStubImpl : public UpdateLibrary {
117 public:
118  UpdateLibraryStubImpl() {}
119  ~UpdateLibraryStubImpl() {}
120  void AddObserver(Observer* observer) {}
121  void RemoveObserver(Observer* observer) {}
122  bool CheckForUpdate() { return false; }
123  bool RebootAfterUpdate() { return false; }
124  bool SetReleaseTrack(const std::string& track) { return false; }
125  std::string GetReleaseTrack() { return "beta-channel"; }
126  const UpdateLibrary::Status& status() const {
127    return status_;
128  }
129
130 private:
131  Status status_;
132
133  DISALLOW_COPY_AND_ASSIGN(UpdateLibraryStubImpl);
134};
135
136// static
137UpdateLibrary* UpdateLibrary::GetImpl(bool stub) {
138  if (stub)
139    return new UpdateLibraryStubImpl();
140  else
141    return new UpdateLibraryImpl();
142}
143
144}  // namespace chromeos
145
146// Allows InvokeLater without adding refcounting. This class is a Singleton and
147// won't be deleted until it's last InvokeLater is run.
148DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::UpdateLibraryImpl);
149