Home | History | Annotate | Download | only in app_mode
      1 // Copyright 2013 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/app_mode/kiosk_app_update_service.h"
      6 
      7 #include "base/logging.h"
      8 #include "chrome/browser/app_mode/app_mode_utils.h"
      9 #include "chrome/browser/browser_process.h"
     10 #include "chrome/browser/browser_process_platform_part_chromeos.h"
     11 #include "chrome/browser/chromeos/system/automatic_reboot_manager.h"
     12 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
     13 #include "chrome/browser/extensions/extension_service.h"
     14 #include "chrome/browser/extensions/extension_system.h"
     15 #include "chrome/browser/extensions/extension_system_factory.h"
     16 #include "chrome/browser/lifetime/application_lifetime.h"
     17 #include "chrome/browser/profiles/profile.h"
     18 #include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
     19 
     20 namespace chromeos {
     21 
     22 namespace {
     23 
     24 // How low to wait after an update is available before we force a restart.
     25 const int kForceRestartWaitTimeMs = 24 * 3600 * 1000;  // 24 hours.
     26 
     27 }  // namespace
     28 
     29 KioskAppUpdateService::KioskAppUpdateService(
     30     Profile* profile,
     31     system::AutomaticRebootManager* automatic_reboot_manager)
     32     : profile_(profile),
     33       automatic_reboot_manager_(automatic_reboot_manager) {
     34   ExtensionService* service =
     35       extensions::ExtensionSystem::Get(profile_)->extension_service();
     36   if (service)
     37     service->AddUpdateObserver(this);
     38 
     39   if (automatic_reboot_manager_)
     40     automatic_reboot_manager_->AddObserver(this);
     41 }
     42 
     43 KioskAppUpdateService::~KioskAppUpdateService() {
     44 }
     45 
     46 void KioskAppUpdateService::StartAppUpdateRestartTimer() {
     47   if (restart_timer_.IsRunning())
     48     return;
     49 
     50   // Setup timer to force restart once the wait period expires.
     51   restart_timer_.Start(
     52       FROM_HERE, base::TimeDelta::FromMilliseconds(kForceRestartWaitTimeMs),
     53       this, &KioskAppUpdateService::ForceAppUpdateRestart);
     54 }
     55 
     56 void KioskAppUpdateService::ForceAppUpdateRestart() {
     57   // Force a chrome restart (not a logout or reboot) by closing all browsers.
     58   LOG(WARNING) << "Force closing all browsers to update kiosk app.";
     59   chrome::CloseAllBrowsers();
     60 }
     61 
     62 void KioskAppUpdateService::Shutdown() {
     63   ExtensionService* service = profile_->GetExtensionService();
     64   if (service)
     65     service->RemoveUpdateObserver(this);
     66 }
     67 
     68 void KioskAppUpdateService::OnAppUpdateAvailable(const std::string& app_id) {
     69   DCHECK(!app_id_.empty());
     70   if (app_id != app_id_)
     71     return;
     72 
     73   extensions::RuntimeEventRouter::DispatchOnRestartRequiredEvent(
     74       profile_,
     75       app_id_,
     76       extensions::api::runtime::OnRestartRequired::REASON_APP_UPDATE);
     77 
     78   StartAppUpdateRestartTimer();
     79 }
     80 
     81 void KioskAppUpdateService::OnRebootScheduled(Reason reason) {
     82   extensions::api::runtime::OnRestartRequired::Reason restart_reason =
     83       extensions::api::runtime::OnRestartRequired::REASON_NONE;
     84   switch (reason) {
     85     case REBOOT_REASON_OS_UPDATE:
     86       restart_reason =
     87           extensions::api::runtime::OnRestartRequired::REASON_OS_UPDATE;
     88       break;
     89     case REBOOT_REASON_PERIODIC:
     90       restart_reason =
     91           extensions::api::runtime::OnRestartRequired::REASON_PERIODIC;
     92       break;
     93     default:
     94       NOTREACHED() << "Unknown reboot reason=" << reason;
     95       return;
     96   }
     97 
     98   extensions::RuntimeEventRouter::DispatchOnRestartRequiredEvent(
     99       profile_, app_id_, restart_reason);
    100 }
    101 
    102 void KioskAppUpdateService::WillDestroyAutomaticRebootManager() {
    103   automatic_reboot_manager_->RemoveObserver(this);
    104   automatic_reboot_manager_ = NULL;
    105 }
    106 
    107 KioskAppUpdateServiceFactory::KioskAppUpdateServiceFactory()
    108     : BrowserContextKeyedServiceFactory(
    109         "KioskAppUpdateService",
    110         BrowserContextDependencyManager::GetInstance()) {
    111   DependsOn(extensions::ExtensionSystemFactory::GetInstance());
    112 }
    113 
    114 KioskAppUpdateServiceFactory::~KioskAppUpdateServiceFactory() {
    115 }
    116 
    117 // static
    118 KioskAppUpdateService* KioskAppUpdateServiceFactory::GetForProfile(
    119     Profile* profile) {
    120   // This should never be called unless we are running in forced app mode.
    121   DCHECK(chrome::IsRunningInForcedAppMode());
    122   if (!chrome::IsRunningInForcedAppMode())
    123     return NULL;
    124 
    125   return static_cast<KioskAppUpdateService*>(
    126       GetInstance()->GetServiceForBrowserContext(profile, true));
    127 }
    128 
    129 // static
    130 KioskAppUpdateServiceFactory* KioskAppUpdateServiceFactory::GetInstance() {
    131   return Singleton<KioskAppUpdateServiceFactory>::get();
    132 }
    133 
    134 BrowserContextKeyedService*
    135 KioskAppUpdateServiceFactory::BuildServiceInstanceFor(
    136     content::BrowserContext* context) const {
    137   return new KioskAppUpdateService(
    138       Profile::FromBrowserContext(context),
    139       g_browser_process->platform_part()->automatic_reboot_manager());
    140 }
    141 
    142 }  // namespace chromeos
    143