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 20namespace chromeos { 21 22namespace { 23 24// How low to wait after an update is available before we force a restart. 25const int kForceRestartWaitTimeMs = 24 * 3600 * 1000; // 24 hours. 26 27} // namespace 28 29KioskAppUpdateService::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 43KioskAppUpdateService::~KioskAppUpdateService() { 44} 45 46void 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 56void 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 62void KioskAppUpdateService::Shutdown() { 63 ExtensionService* service = profile_->GetExtensionService(); 64 if (service) 65 service->RemoveUpdateObserver(this); 66} 67 68void 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 81void 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 102void KioskAppUpdateService::WillDestroyAutomaticRebootManager() { 103 automatic_reboot_manager_->RemoveObserver(this); 104 automatic_reboot_manager_ = NULL; 105} 106 107KioskAppUpdateServiceFactory::KioskAppUpdateServiceFactory() 108 : BrowserContextKeyedServiceFactory( 109 "KioskAppUpdateService", 110 BrowserContextDependencyManager::GetInstance()) { 111 DependsOn(extensions::ExtensionSystemFactory::GetInstance()); 112} 113 114KioskAppUpdateServiceFactory::~KioskAppUpdateServiceFactory() { 115} 116 117// static 118KioskAppUpdateService* 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 130KioskAppUpdateServiceFactory* KioskAppUpdateServiceFactory::GetInstance() { 131 return Singleton<KioskAppUpdateServiceFactory>::get(); 132} 133 134BrowserContextKeyedService* 135KioskAppUpdateServiceFactory::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