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 "apps/app_lifetime_monitor.h" 6 7 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "content/public/browser/notification_details.h" 10 #include "content/public/browser/notification_service.h" 11 #include "extensions/browser/app_window/app_window.h" 12 #include "extensions/browser/extension_host.h" 13 #include "extensions/browser/notification_types.h" 14 #include "extensions/common/extension.h" 15 16 namespace apps { 17 18 using extensions::AppWindow; 19 using extensions::AppWindowRegistry; 20 using extensions::Extension; 21 using extensions::ExtensionHost; 22 23 AppLifetimeMonitor::AppLifetimeMonitor(Profile* profile) 24 : profile_(profile) { 25 registrar_.Add(this, 26 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, 27 content::NotificationService::AllSources()); 28 registrar_.Add(this, 29 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, 30 content::NotificationService::AllSources()); 31 registrar_.Add( 32 this, chrome::NOTIFICATION_APP_TERMINATING, 33 content::NotificationService::AllSources()); 34 35 AppWindowRegistry* app_window_registry = 36 AppWindowRegistry::Factory::GetForBrowserContext(profile_, 37 false /* create */); 38 DCHECK(app_window_registry); 39 app_window_registry->AddObserver(this); 40 } 41 42 AppLifetimeMonitor::~AppLifetimeMonitor() {} 43 44 void AppLifetimeMonitor::AddObserver(Observer* observer) { 45 observers_.AddObserver(observer); 46 } 47 48 void AppLifetimeMonitor::RemoveObserver(Observer* observer) { 49 observers_.RemoveObserver(observer); 50 } 51 52 void AppLifetimeMonitor::Observe(int type, 53 const content::NotificationSource& source, 54 const content::NotificationDetails& details) { 55 switch (type) { 56 case extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING: { 57 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); 58 const Extension* extension = host->extension(); 59 if (!extension || !extension->is_platform_app()) 60 return; 61 62 NotifyAppStart(extension->id()); 63 break; 64 } 65 66 case extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED: { 67 ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); 68 const Extension* extension = host->extension(); 69 if (!extension || !extension->is_platform_app()) 70 return; 71 72 NotifyAppStop(extension->id()); 73 break; 74 } 75 76 case chrome::NOTIFICATION_APP_TERMINATING: { 77 NotifyChromeTerminating(); 78 break; 79 } 80 } 81 } 82 83 void AppLifetimeMonitor::OnAppWindowRemoved(AppWindow* app_window) { 84 if (!HasVisibleAppWindows(app_window)) 85 NotifyAppDeactivated(app_window->extension_id()); 86 } 87 88 void AppLifetimeMonitor::OnAppWindowHidden(AppWindow* app_window) { 89 if (!HasVisibleAppWindows(app_window)) 90 NotifyAppDeactivated(app_window->extension_id()); 91 } 92 93 void AppLifetimeMonitor::OnAppWindowShown(AppWindow* app_window) { 94 if (app_window->window_type() != AppWindow::WINDOW_TYPE_DEFAULT) 95 return; 96 97 if (HasVisibleAppWindows(app_window)) 98 NotifyAppActivated(app_window->extension_id()); 99 } 100 101 void AppLifetimeMonitor::Shutdown() { 102 AppWindowRegistry* app_window_registry = 103 AppWindowRegistry::Factory::GetForBrowserContext(profile_, 104 false /* create */); 105 if (app_window_registry) 106 app_window_registry->RemoveObserver(this); 107 } 108 109 bool AppLifetimeMonitor::HasVisibleAppWindows(AppWindow* app_window) const { 110 AppWindowRegistry::AppWindowList windows = 111 AppWindowRegistry::Get(app_window->browser_context()) 112 ->GetAppWindowsForApp(app_window->extension_id()); 113 114 for (AppWindowRegistry::AppWindowList::const_iterator i = windows.begin(); 115 i != windows.end(); 116 ++i) { 117 if (!(*i)->is_hidden()) 118 return true; 119 } 120 return false; 121 } 122 123 void AppLifetimeMonitor::NotifyAppStart(const std::string& app_id) { 124 FOR_EACH_OBSERVER(Observer, observers_, OnAppStart(profile_, app_id)); 125 } 126 127 void AppLifetimeMonitor::NotifyAppActivated(const std::string& app_id) { 128 FOR_EACH_OBSERVER(Observer, observers_, OnAppActivated(profile_, app_id)); 129 } 130 131 void AppLifetimeMonitor::NotifyAppDeactivated(const std::string& app_id) { 132 FOR_EACH_OBSERVER(Observer, observers_, OnAppDeactivated(profile_, app_id)); 133 } 134 135 void AppLifetimeMonitor::NotifyAppStop(const std::string& app_id) { 136 FOR_EACH_OBSERVER(Observer, observers_, OnAppStop(profile_, app_id)); 137 } 138 139 void AppLifetimeMonitor::NotifyChromeTerminating() { 140 FOR_EACH_OBSERVER(Observer, observers_, OnChromeTerminating()); 141 } 142 143 } // namespace apps 144