1 // Copyright (c) 2012 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 "apps/app_restore_service.h" 6 7 #include "apps/app_lifetime_monitor_factory.h" 8 #include "apps/app_restore_service_factory.h" 9 #include "apps/launcher.h" 10 #include "apps/saved_files_service.h" 11 #include "apps/shell_window.h" 12 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h" 14 #include "chrome/browser/extensions/extension_host.h" 15 #include "chrome/browser/extensions/extension_prefs.h" 16 #include "chrome/browser/extensions/extension_service.h" 17 #include "chrome/browser/extensions/extension_system.h" 18 #include "chrome/common/extensions/extension.h" 19 #include "chrome/common/extensions/extension_set.h" 20 21 #if defined(OS_WIN) 22 #include "win8/util/win8_util.h" 23 #endif 24 25 using extensions::Extension; 26 using extensions::ExtensionHost; 27 using extensions::ExtensionPrefs; 28 using extensions::ExtensionSystem; 29 30 namespace apps { 31 32 // static 33 bool AppRestoreService::ShouldRestoreApps(bool is_browser_restart) { 34 bool should_restore_apps = is_browser_restart; 35 #if defined(OS_CHROMEOS) 36 // Chromeos always restarts apps, even if it was a regular shutdown. 37 should_restore_apps = true; 38 #elif defined(OS_WIN) 39 // Packaged apps are not supported in Metro mode, so don't try to start them. 40 if (win8::IsSingleWindowMetroMode()) 41 should_restore_apps = false; 42 #endif 43 return should_restore_apps; 44 } 45 46 AppRestoreService::AppRestoreService(Profile* profile) 47 : profile_(profile) { 48 StartObservingAppLifetime(); 49 } 50 51 void AppRestoreService::HandleStartup(bool should_restore_apps) { 52 ExtensionService* extension_service = 53 ExtensionSystem::Get(profile_)->extension_service(); 54 const ExtensionSet* extensions = extension_service->extensions(); 55 ExtensionPrefs* extension_prefs = extension_service->extension_prefs(); 56 57 for (ExtensionSet::const_iterator it = extensions->begin(); 58 it != extensions->end(); ++it) { 59 const Extension* extension = it->get(); 60 if (extension_prefs->IsExtensionRunning(extension->id())) { 61 RecordAppStop(extension->id()); 62 // If we are not restoring apps (e.g., because it is a clean restart), and 63 // the app does not have retain permission, explicitly clear the retained 64 // entries queue. 65 if (should_restore_apps) { 66 RestoreApp(it->get()); 67 } else { 68 SavedFilesService::Get(profile_)->ClearQueueIfNoRetainPermission( 69 extension); 70 } 71 } 72 } 73 } 74 75 bool AppRestoreService::IsAppRestorable(const std::string& extension_id) { 76 return extensions::ExtensionPrefs::Get(profile_) ->IsExtensionRunning( 77 extension_id); 78 } 79 80 // static 81 AppRestoreService* AppRestoreService::Get(Profile* profile) { 82 return apps::AppRestoreServiceFactory::GetForProfile(profile); 83 } 84 85 void AppRestoreService::OnAppStart(Profile* profile, 86 const std::string& app_id) { 87 RecordAppStart(app_id); 88 } 89 90 void AppRestoreService::OnAppActivated(Profile* profile, 91 const std::string& app_id) { 92 RecordAppActiveState(app_id, true); 93 } 94 95 void AppRestoreService::OnAppDeactivated(Profile* profile, 96 const std::string& app_id) { 97 RecordAppActiveState(app_id, false); 98 } 99 100 void AppRestoreService::OnAppStop(Profile* profile, const std::string& app_id) { 101 RecordAppStop(app_id); 102 } 103 104 void AppRestoreService::OnChromeTerminating() { 105 // We want to preserve the state when the app begins terminating, so stop 106 // listening to app lifetime events. 107 StopObservingAppLifetime(); 108 } 109 110 void AppRestoreService::Shutdown() { 111 StopObservingAppLifetime(); 112 } 113 114 void AppRestoreService::RecordAppStart(const std::string& extension_id) { 115 ExtensionPrefs* extension_prefs = 116 ExtensionSystem::Get(profile_)->extension_service()->extension_prefs(); 117 extension_prefs->SetExtensionRunning(extension_id, true); 118 } 119 120 void AppRestoreService::RecordAppStop(const std::string& extension_id) { 121 ExtensionPrefs* extension_prefs = 122 ExtensionSystem::Get(profile_)->extension_service()->extension_prefs(); 123 extension_prefs->SetExtensionRunning(extension_id, false); 124 } 125 126 void AppRestoreService::RecordAppActiveState(const std::string& id, 127 bool is_active) { 128 ExtensionService* extension_service = 129 ExtensionSystem::Get(profile_)->extension_service(); 130 ExtensionPrefs* extension_prefs = extension_service->extension_prefs(); 131 132 // If the extension isn't running then we will already have recorded whether 133 // it is active or not. 134 if (!extension_prefs->IsExtensionRunning(id)) 135 return; 136 137 extension_prefs->SetIsActive(id, is_active); 138 } 139 140 void AppRestoreService::RestoreApp(const Extension* extension) { 141 RestartPlatformApp(profile_, extension); 142 } 143 144 void AppRestoreService::StartObservingAppLifetime() { 145 AppLifetimeMonitor* app_lifetime_monitor = 146 AppLifetimeMonitorFactory::GetForProfile(profile_); 147 DCHECK(app_lifetime_monitor); 148 app_lifetime_monitor->AddObserver(this); 149 } 150 151 void AppRestoreService::StopObservingAppLifetime() { 152 AppLifetimeMonitor* app_lifetime_monitor = 153 AppLifetimeMonitorFactory::GetForProfile(profile_); 154 // This might be NULL in tests. 155 if (app_lifetime_monitor) 156 app_lifetime_monitor->RemoveObserver(this); 157 } 158 159 } // namespace apps 160