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/cros/update_library.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.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
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass UpdateLibraryImpl : public UpdateLibrary {
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateLibraryImpl()
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : status_connection_(NULL) {
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (CrosLibrary::Get()->EnsureLoaded()) {
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      Init();
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ~UpdateLibraryImpl() {
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (status_connection_) {
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      DisconnectUpdateProgress(status_connection_);
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AddObserver(Observer* observer) {
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    observers_.AddObserver(observer);
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void RemoveObserver(Observer* observer) {
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    observers_.RemoveObserver(observer);
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool HasObserver(Observer* observer) {
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return observers_.HasObserver(observer);
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void RequestUpdateCheck(chromeos::UpdateCallback callback, void* user_data) {
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (CrosLibrary::Get()->EnsureLoaded())
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chromeos::RequestUpdateCheck(callback, user_data);
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool RebootAfterUpdate() {
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!CrosLibrary::Get()->EnsureLoaded())
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return false;
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return RebootIfUpdated();
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void SetReleaseTrack(const std::string& track) {
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (CrosLibrary::Get()->EnsureLoaded())
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chromeos::SetUpdateTrack(track);
58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void GetReleaseTrack(chromeos::UpdateTrackCallback callback,
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       void* user_data) {
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (CrosLibrary::Get()->EnsureLoaded())
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chromeos::RequestUpdateTrack(callback, user_data);
64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const UpdateLibrary::Status& status() const {
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return status_;
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static void ChangedHandler(void* object,
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const UpdateProgress& status) {
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    UpdateLibraryImpl* updater = static_cast<UpdateLibraryImpl*>(object);
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    updater->UpdateStatus(Status(status));
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void Init() {
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    status_connection_ = MonitorUpdateStatus(&ChangedHandler, this);
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void UpdateStatus(const Status& status) {
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Make sure we run on UI thread.
83731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
84731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::PostTask(
85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          BrowserThread::UI, FROM_HERE,
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          NewRunnableMethod(this, &UpdateLibraryImpl::UpdateStatus, status));
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return;
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    status_ = status;
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FOR_EACH_OBSERVER(Observer, observers_, UpdateStatusChanged(this));
92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // If the update is ready to install, send a notification so that Chrome
94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // can update the UI.
95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (status_.status == UPDATE_STATUS_UPDATED_NEED_REBOOT) {
96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      NotificationService::current()->Notify(
97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          NotificationType::UPGRADE_RECOMMENDED,
98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          Source<UpdateLibrary>(this),
99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          NotificationService::NoDetails());
100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ObserverList<Observer> observers_;
1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // A reference to the update api, to allow callbacks when the update
1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // status changes.
1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateStatusConnection status_connection_;
1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The latest power status.
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Status status_;
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DISALLOW_COPY_AND_ASSIGN(UpdateLibraryImpl);
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass UpdateLibraryStubImpl : public UpdateLibrary {
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateLibraryStubImpl() {}
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ~UpdateLibraryStubImpl() {}
1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void AddObserver(Observer* observer) {}
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void RemoveObserver(Observer* observer) {}
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool HasObserver(Observer* observer) { return false; }
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void RequestUpdateCheck(chromeos::UpdateCallback callback, void* user_data) {
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (callback)
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      callback(user_data, UPDATE_RESULT_FAILED, "stub update");
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool RebootAfterUpdate() { return false; }
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void SetReleaseTrack(const std::string& track) { }
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void GetReleaseTrack(chromeos::UpdateTrackCallback callback,
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       void* user_data) {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (callback)
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      callback(user_data, "beta-channel");
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const UpdateLibrary::Status& status() const {
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return status_;
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Status status_;
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DISALLOW_COPY_AND_ASSIGN(UpdateLibraryStubImpl);
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickUpdateLibrary* UpdateLibrary::GetImpl(bool stub) {
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (stub)
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return new UpdateLibraryStubImpl();
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return new UpdateLibraryImpl();
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace chromeos
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Allows InvokeLater without adding refcounting. This class is a Singleton and
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// won't be deleted until it's last InvokeLater is run.
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::UpdateLibraryImpl);
156