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