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 "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