Home | History | Annotate | Download | only in apps
      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