• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AppLifetimeMonitor(Profile * profile)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 
~AppLifetimeMonitor()42 AppLifetimeMonitor::~AppLifetimeMonitor() {}
43 
AddObserver(Observer * observer)44 void AppLifetimeMonitor::AddObserver(Observer* observer) {
45   observers_.AddObserver(observer);
46 }
47 
RemoveObserver(Observer * observer)48 void AppLifetimeMonitor::RemoveObserver(Observer* observer) {
49   observers_.RemoveObserver(observer);
50 }
51 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)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 
OnAppWindowRemoved(AppWindow * app_window)83 void AppLifetimeMonitor::OnAppWindowRemoved(AppWindow* app_window) {
84   if (!HasVisibleAppWindows(app_window))
85     NotifyAppDeactivated(app_window->extension_id());
86 }
87 
OnAppWindowHidden(AppWindow * app_window)88 void AppLifetimeMonitor::OnAppWindowHidden(AppWindow* app_window) {
89   if (!HasVisibleAppWindows(app_window))
90     NotifyAppDeactivated(app_window->extension_id());
91 }
92 
OnAppWindowShown(AppWindow * app_window)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 
Shutdown()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 
HasVisibleAppWindows(AppWindow * app_window) const109 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 
NotifyAppStart(const std::string & app_id)123 void AppLifetimeMonitor::NotifyAppStart(const std::string& app_id) {
124   FOR_EACH_OBSERVER(Observer, observers_, OnAppStart(profile_, app_id));
125 }
126 
NotifyAppActivated(const std::string & app_id)127 void AppLifetimeMonitor::NotifyAppActivated(const std::string& app_id) {
128   FOR_EACH_OBSERVER(Observer, observers_, OnAppActivated(profile_, app_id));
129 }
130 
NotifyAppDeactivated(const std::string & app_id)131 void AppLifetimeMonitor::NotifyAppDeactivated(const std::string& app_id) {
132   FOR_EACH_OBSERVER(Observer, observers_, OnAppDeactivated(profile_, app_id));
133 }
134 
NotifyAppStop(const std::string & app_id)135 void AppLifetimeMonitor::NotifyAppStop(const std::string& app_id) {
136   FOR_EACH_OBSERVER(Observer, observers_, OnAppStop(profile_, app_id));
137 }
138 
NotifyChromeTerminating()139 void AppLifetimeMonitor::NotifyChromeTerminating() {
140   FOR_EACH_OBSERVER(Observer, observers_, OnChromeTerminating());
141 }
142 
143 }  // namespace apps
144