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