diff options
author | benwells@chromium.org <benwells@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 07:15:50 +0000 |
---|---|---|
committer | benwells@chromium.org <benwells@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 07:15:50 +0000 |
commit | 7aadf69a4bbc972a89bd03929c0f054b885708e4 (patch) | |
tree | 95dec7bd5b3cb9caeac1fcbb5ebfa22be3e080c9 /apps | |
parent | 4e53cb3b926bde438d2175dcb006dd534e5becab (diff) | |
download | chromium_src-7aadf69a4bbc972a89bd03929c0f054b885708e4.zip chromium_src-7aadf69a4bbc972a89bd03929c0f054b885708e4.tar.gz chromium_src-7aadf69a4bbc972a89bd03929c0f054b885708e4.tar.bz2 |
Don't send onLaunched to apps with only hidden windows when they reload.
This also stops apps with only hidden windows getting sent the
onLaunched if they don't listen to onRestarted and the system is
restarted.
BUG=268755
Review URL: https://codereview.chromium.org/270273002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270614 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_lifetime_monitor.cc | 39 | ||||
-rw-r--r-- | apps/app_lifetime_monitor.h | 5 | ||||
-rw-r--r-- | apps/app_load_service.cc | 10 | ||||
-rw-r--r-- | apps/app_load_service.h | 1 | ||||
-rw-r--r-- | apps/app_restore_service_browsertest.cc | 54 | ||||
-rw-r--r-- | apps/app_window.cc | 16 | ||||
-rw-r--r-- | apps/app_window.h | 9 |
7 files changed, 105 insertions, 29 deletions
diff --git a/apps/app_lifetime_monitor.cc b/apps/app_lifetime_monitor.cc index 83a3c56..0d258c6 100644 --- a/apps/app_lifetime_monitor.cc +++ b/apps/app_lifetime_monitor.cc @@ -77,25 +77,24 @@ void AppLifetimeMonitor::Observe(int type, } } -void AppLifetimeMonitor::OnAppWindowAdded(AppWindow* app_window) { +void AppLifetimeMonitor::OnAppWindowRemoved(AppWindow* app_window) { + if (!HasVisibleAppWindows(app_window)) + NotifyAppDeactivated(app_window->extension_id()); +} + +void AppLifetimeMonitor::OnAppWindowHidden(AppWindow* app_window) { + if (!HasVisibleAppWindows(app_window)) + NotifyAppDeactivated(app_window->extension_id()); +} + +void AppLifetimeMonitor::OnAppWindowShown(AppWindow* app_window) { if (app_window->window_type() != AppWindow::WINDOW_TYPE_DEFAULT) return; - AppWindowRegistry::AppWindowList windows = - AppWindowRegistry::Get(app_window->browser_context()) - ->GetAppWindowsForApp(app_window->extension_id()); - if (windows.size() == 1) + if (HasVisibleAppWindows(app_window)) NotifyAppActivated(app_window->extension_id()); } -void AppLifetimeMonitor::OnAppWindowRemoved(AppWindow* app_window) { - AppWindowRegistry::AppWindowList windows = - AppWindowRegistry::Get(app_window->browser_context()) - ->GetAppWindowsForApp(app_window->extension_id()); - if (windows.empty()) - NotifyAppDeactivated(app_window->extension_id()); -} - void AppLifetimeMonitor::Shutdown() { AppWindowRegistry* app_window_registry = AppWindowRegistry::Factory::GetForBrowserContext(profile_, @@ -104,6 +103,20 @@ void AppLifetimeMonitor::Shutdown() { app_window_registry->RemoveObserver(this); } +bool AppLifetimeMonitor::HasVisibleAppWindows(AppWindow* app_window) const { + AppWindowRegistry::AppWindowList windows = + AppWindowRegistry::Get(app_window->browser_context()) + ->GetAppWindowsForApp(app_window->extension_id()); + + for (AppWindowRegistry::AppWindowList::const_iterator i = windows.begin(); + i != windows.end(); + ++i) { + if (!(*i)->is_hidden()) + return true; + } + return false; +} + void AppLifetimeMonitor::NotifyAppStart(const std::string& app_id) { FOR_EACH_OBSERVER(Observer, observers_, OnAppStart(profile_, app_id)); } diff --git a/apps/app_lifetime_monitor.h b/apps/app_lifetime_monitor.h index a9fed9c..9e4aa56 100644 --- a/apps/app_lifetime_monitor.h +++ b/apps/app_lifetime_monitor.h @@ -62,12 +62,15 @@ class AppLifetimeMonitor : public KeyedService, const content::NotificationDetails& details) OVERRIDE; // AppWindowRegistry::Observer overrides: - virtual void OnAppWindowAdded(AppWindow* app_window) OVERRIDE; virtual void OnAppWindowRemoved(AppWindow* app_window) OVERRIDE; + virtual void OnAppWindowHidden(apps::AppWindow* app_window) OVERRIDE; + virtual void OnAppWindowShown(apps::AppWindow* app_window) OVERRIDE; // KeyedService overrides: virtual void Shutdown() OVERRIDE; + bool HasVisibleAppWindows(apps::AppWindow* app_window) const; + void NotifyAppStart(const std::string& app_id); void NotifyAppActivated(const std::string& app_id); void NotifyAppDeactivated(const std::string& app_id); diff --git a/apps/app_load_service.cc b/apps/app_load_service.cc index cfcef3e..8d816f5 100644 --- a/apps/app_load_service.cc +++ b/apps/app_load_service.cc @@ -115,8 +115,10 @@ void AppLoadService::Observe(int type, if (!unload_info->extension->is_platform_app()) break; + extensions::ExtensionPrefs* extension_prefs = + extensions::ExtensionPrefs::Get(profile_); if (WasUnloadedForReload(*unload_info) && - HasAppWindows(unload_info->extension->id()) && + extension_prefs->IsActive(unload_info->extension->id()) && !HasPostReloadAction(unload_info->extension->id())) { post_reload_actions_[unload_info->extension->id()].action_type = LAUNCH; } @@ -127,12 +129,6 @@ void AppLoadService::Observe(int type, } } -bool AppLoadService::HasAppWindows(const std::string& extension_id) { - return !AppWindowRegistry::Get(profile_) - ->GetAppWindowsForApp(extension_id) - .empty(); -} - bool AppLoadService::WasUnloadedForReload( const extensions::UnloadedExtensionInfo& unload_info) { if (unload_info.reason == extensions::UnloadedExtensionInfo::REASON_DISABLE) { diff --git a/apps/app_load_service.h b/apps/app_load_service.h index 2ccd3e0..c79915d 100644 --- a/apps/app_load_service.h +++ b/apps/app_load_service.h @@ -64,7 +64,6 @@ class AppLoadService : public KeyedService, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; - bool HasAppWindows(const std::string& extension_id); bool WasUnloadedForReload( const extensions::UnloadedExtensionInfo& unload_info); bool HasPostReloadAction(const std::string& extension_id); diff --git a/apps/app_restore_service_browsertest.cc b/apps/app_restore_service_browsertest.cc index 833cee5..1ba87e3 100644 --- a/apps/app_restore_service_browsertest.cc +++ b/apps/app_restore_service_browsertest.cc @@ -55,6 +55,60 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, RunningAppsAreRecorded) { restart_listener.WaitUntilSatisfied(); } +// Tests that apps are recorded in the preferences as active when and only when +// they have visible windows. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ActiveAppsAreRecorded) { + ExtensionTestMessageListener ready_listener("ready", true); + const Extension* extension = + LoadExtension(test_data_dir_.AppendASCII("platform_apps/active_test")); + ASSERT_TRUE(extension); + ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(browser()->profile()); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + + // Open a visible window and check the app is marked active. + ready_listener.Reply("create"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ASSERT_TRUE(extension_prefs->IsActive(extension->id())); + + // Close the window, then open a minimized window and check the app is active. + ready_listener.Reply("closeLastWindow"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ready_listener.Reply("createMinimized"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ASSERT_TRUE(extension_prefs->IsActive(extension->id())); + + // Close the window, then open a hidden window and check the app is not + // marked active. + ready_listener.Reply("closeLastWindow"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ready_listener.Reply("createHidden"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ASSERT_FALSE(extension_prefs->IsActive(extension->id())); + + // Open another window and check the app is marked active. + ready_listener.Reply("create"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ASSERT_TRUE(extension_prefs->IsActive(extension->id())); + + // Close the visible window and check the app has been marked inactive. + ready_listener.Reply("closeLastWindow"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ASSERT_FALSE(extension_prefs->IsActive(extension->id())); + + // Close the last window and exit. + ready_listener.Reply("closeLastWindow"); + ready_listener.Reset(); + ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); + ready_listener.Reply("exit"); +} + IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, FileAccessIsSavedToPrefs) { content::WindowedNotificationObserver extension_suspended( chrome::NOTIFICATION_EXTENSION_HOST_DESTROYED, diff --git a/apps/app_window.cc b/apps/app_window.cc index a48f79d..2071892 100644 --- a/apps/app_window.cc +++ b/apps/app_window.cc @@ -238,6 +238,7 @@ AppWindow::AppWindow(BrowserContext* context, fullscreen_types_(FULLSCREEN_TYPE_NONE), show_on_first_paint_(false), first_paint_complete_(false), + is_hidden_(false), cached_always_on_top_(false) { extensions::ExtensionsBrowserClient* client = extensions::ExtensionsBrowserClient::Get(); @@ -279,6 +280,11 @@ void AppWindow::Init(const GURL& url, native_app_window_.reset(delegate_->CreateNativeAppWindow(this, new_params)); + // Prevent the browser process from shutting down while this window exists. + AppsClient::Get()->IncrementKeepAliveCount(); + UpdateExtensionAppIcon(); + AppWindowRegistry::Get(browser_context_)->AddAppWindow(this); + if (new_params.hidden) { // Although the window starts hidden by default, calling Hide() here // notifies observers of the window being hidden. @@ -330,13 +336,6 @@ void AppWindow::Init(const GURL& url, initial_bounds.Inset(frame_insets); apps::ResizeWebContents(web_contents, initial_bounds.size()); } - - // Prevent the browser process from shutting down while this window is open. - AppsClient::Get()->IncrementKeepAliveCount(); - - UpdateExtensionAppIcon(); - - AppWindowRegistry::Get(browser_context_)->AddAppWindow(this); } AppWindow::~AppWindow() { @@ -678,6 +677,8 @@ void AppWindow::SetContentSizeConstraints(const gfx::Size& min_size, } void AppWindow::Show(ShowType show_type) { + is_hidden_ = false; + if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableAppsShowOnFirstPaint)) { show_on_first_paint_ = true; @@ -704,6 +705,7 @@ void AppWindow::Hide() { // there was a non-empty paint. It should have no effect in a non-racy // scenario where the application is hiding then showing a window: the second // show will not be delayed. + is_hidden_ = true; show_on_first_paint_ = false; GetBaseWindow()->Hide(); AppWindowRegistry::Get(browser_context_)->AppWindowHidden(this); diff --git a/apps/app_window.h b/apps/app_window.h index 3fd5757..9b922c8 100644 --- a/apps/app_window.h +++ b/apps/app_window.h @@ -262,6 +262,7 @@ class AppWindow : public content::NotificationObserver, const GURL& app_icon_url() const { return app_icon_url_; } const gfx::Image& badge_icon() const { return badge_icon_; } const GURL& badge_icon_url() const { return badge_icon_url_; } + bool is_hidden() const { return is_hidden_; } const extensions::Extension* GetExtension() const; NativeAppWindow* GetBaseWindow(); @@ -518,6 +519,14 @@ class AppWindow : public content::NotificationObserver, // The first visually non-empty paint has completed. bool first_paint_complete_; + // Whether the window is hidden or not. Hidden in this context means actively + // by the chrome.app.window API, not in an operating system context. For + // example windows which are minimized are not hidden, and windows which are + // part of a hidden app on OS X are not hidden. Windows which were created + // with the |hidden| flag set to true, or which have been programmatically + // hidden, are considered hidden. + bool is_hidden_; + // Whether the delayed Show() call was for an active or inactive window. ShowType delayed_show_type_; |