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