summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/app_restore_service.cc56
-rw-r--r--apps/app_restore_service.h17
-rw-r--r--apps/app_restore_service_factory.cc2
-rw-r--r--chrome/browser/extensions/extension_prefs.cc18
-rw-r--r--chrome/browser/extensions/extension_prefs.h6
-rw-r--r--chrome/browser/extensions/platform_app_launcher.cc26
-rw-r--r--chrome/browser/extensions/shell_window_registry.h8
-rw-r--r--chrome/browser/ui/extensions/shell_window.cc1
-rw-r--r--chrome/browser/ui/extensions/shell_window.h2
9 files changed, 128 insertions, 8 deletions
diff --git a/apps/app_restore_service.cc b/apps/app_restore_service.cc
index f8932fb..a567811 100644
--- a/apps/app_restore_service.cc
+++ b/apps/app_restore_service.cc
@@ -8,9 +8,11 @@
#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
#include "chrome/browser/extensions/event_router.h"
#include "chrome/browser/extensions/extension_host.h"
+#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/platform_app_launcher.h"
+#include "chrome/browser/ui/extensions/shell_window.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_set.h"
@@ -55,6 +57,7 @@ AppRestoreService::AppRestoreService(Profile* profile)
registrar_.Add(
this, chrome::NOTIFICATION_APP_TERMINATING,
content::NotificationService::AllSources());
+ StartObservingShellWindows();
}
void AppRestoreService::HandleStartup(bool should_restore_apps) {
@@ -102,11 +105,28 @@ void AppRestoreService::Observe(int type,
// Stop listening to NOTIFICATION_EXTENSION_HOST_DESTROYED in particular
// as all extension hosts will be destroyed as a result of shutdown.
registrar_.RemoveAll();
+ // Stop listening to the ShellWindowRegistry for window closes, because
+ // all windows will be closed as a result of shutdown.
+ StopObservingShellWindows();
break;
}
}
}
+void AppRestoreService::OnShellWindowAdded(ShellWindow* shell_window) {
+ RecordIfAppHasWindows(shell_window->extension_id());
+}
+
+void AppRestoreService::OnShellWindowIconChanged(ShellWindow* shell_window) {
+}
+
+void AppRestoreService::OnShellWindowRemoved(ShellWindow* shell_window) {
+ RecordIfAppHasWindows(shell_window->extension_id());
+}
+
+void AppRestoreService::Shutdown() {
+ StopObservingShellWindows();
+}
void AppRestoreService::RecordAppStart(const std::string& extension_id) {
ExtensionPrefs* extension_prefs =
@@ -122,6 +142,26 @@ void AppRestoreService::RecordAppStop(const std::string& extension_id) {
extension_prefs, extension_id);
}
+void AppRestoreService::RecordIfAppHasWindows(
+ const std::string& id) {
+ ExtensionService* extension_service =
+ ExtensionSystem::Get(profile_)->extension_service();
+ ExtensionPrefs* extension_prefs = extension_service->extension_prefs();
+
+ // If the extension isn't running then we will already have recorded whether
+ // it had windows or not.
+ if (!extension_prefs->IsExtensionRunning(id))
+ return;
+
+ extensions::ShellWindowRegistry* shell_window_registry =
+ extensions::ShellWindowRegistry::Factory::GetForProfile(
+ profile_, false /* create */);
+ if (!shell_window_registry)
+ return;
+ bool has_windows = !shell_window_registry->GetShellWindowsForApp(id).empty();
+ extension_prefs->SetHasWindows(id, has_windows);
+}
+
void AppRestoreService::RestoreApp(
const Extension* extension,
const std::vector<SavedFileEntry>& file_entries) {
@@ -130,4 +170,20 @@ void AppRestoreService::RestoreApp(
file_entries);
}
+void AppRestoreService::StartObservingShellWindows() {
+ extensions::ShellWindowRegistry* shell_window_registry =
+ extensions::ShellWindowRegistry::Factory::GetForProfile(
+ profile_, false /* create */);
+ if (shell_window_registry)
+ shell_window_registry->AddObserver(this);
+}
+
+void AppRestoreService::StopObservingShellWindows() {
+ extensions::ShellWindowRegistry* shell_window_registry =
+ extensions::ShellWindowRegistry::Factory::GetForProfile(
+ profile_, false /* create */);
+ if (shell_window_registry)
+ shell_window_registry->RemoveObserver(this);
+}
+
} // namespace apps
diff --git a/apps/app_restore_service.h b/apps/app_restore_service.h
index f27c83c..16d0910 100644
--- a/apps/app_restore_service.h
+++ b/apps/app_restore_service.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/profiles/profile_keyed_service.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -29,7 +30,8 @@ namespace apps {
// Tracks what apps need to be restarted when the browser restarts.
class AppRestoreService : public ProfileKeyedService,
- public content::NotificationObserver {
+ public content::NotificationObserver,
+ public extensions::ShellWindowRegistry::Observer {
public:
// Returns true if apps should be restored on the current platform, given
// whether this new browser process launched due to a restart.
@@ -47,12 +49,25 @@ class AppRestoreService : public ProfileKeyedService,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // extensions::ShellWindowRegistry::Observer.
+ virtual void OnShellWindowAdded(ShellWindow* shell_window) OVERRIDE;
+ virtual void OnShellWindowIconChanged(ShellWindow* shell_window) OVERRIDE;
+ virtual void OnShellWindowRemoved(ShellWindow* shell_window) OVERRIDE;
+
+ // ProfileKeyedService.
+ virtual void Shutdown() OVERRIDE;
+
void RecordAppStart(const std::string& extension_id);
void RecordAppStop(const std::string& extension_id);
+ void RecordIfAppHasWindows(const std::string& id);
+
void RestoreApp(
const extensions::Extension* extension,
const std::vector<SavedFileEntry>& file_entries);
+ void StartObservingShellWindows();
+ void StopObservingShellWindows();
+
content::NotificationRegistrar registrar_;
Profile* profile_;
diff --git a/apps/app_restore_service_factory.cc b/apps/app_restore_service_factory.cc
index 71dd80b..091487e 100644
--- a/apps/app_restore_service_factory.cc
+++ b/apps/app_restore_service_factory.cc
@@ -5,6 +5,7 @@
#include "apps/app_restore_service_factory.h"
#include "apps/app_restore_service.h"
+#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_dependency_manager.h"
@@ -30,6 +31,7 @@ AppRestoreServiceFactory* AppRestoreServiceFactory::GetInstance() {
AppRestoreServiceFactory::AppRestoreServiceFactory()
: ProfileKeyedServiceFactory("AppRestoreService",
ProfileDependencyManager::GetInstance()) {
+ DependsOn(extensions::ShellWindowRegistry::Factory::GetInstance());
}
AppRestoreServiceFactory::~AppRestoreServiceFactory() {
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index 64ef63c..07a0a9b 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -53,6 +53,9 @@ namespace {
// Whether this extension was running when chrome last shutdown.
const char kPrefRunning[] = "running";
+// Whether this extension had windows when it was last running.
+const char kHasWindows[] = "has_windows";
+
// Where an extension was installed from. (see Manifest::Location)
const char kPrefLocation[] = "location";
@@ -1160,6 +1163,21 @@ bool ExtensionPrefs::IsExtensionRunning(const std::string& extension_id) {
return running;
}
+void ExtensionPrefs::SetHasWindows(const std::string& extension_id,
+ bool has_windows) {
+ Value* value = Value::CreateBooleanValue(has_windows);
+ UpdateExtensionPref(extension_id, kHasWindows, value);
+}
+
+bool ExtensionPrefs::HasWindows(const std::string& extension_id) {
+ const DictionaryValue* extension = GetExtensionPref(extension_id);
+ if (!extension)
+ return false;
+ bool has_windows = false;
+ extension->GetBoolean(kHasWindows, &has_windows);
+ return has_windows;
+}
+
bool ExtensionPrefs::IsIncognitoEnabled(const std::string& extension_id) {
return ReadPrefAsBooleanAndReturn(extension_id, kPrefIncognitoEnabled);
}
diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h
index 462fe6f..4ab0013 100644
--- a/chrome/browser/extensions/extension_prefs.h
+++ b/chrome/browser/extensions/extension_prefs.h
@@ -374,6 +374,12 @@ class ExtensionPrefs : public ContentSettingsStore::Observer,
// restart apps across browser restarts.
bool IsExtensionRunning(const std::string& extension_id);
+ // Set/Get whether or not the extension has windows associated with it. Used
+ // to force a launch of apps that don't handle onRestarted() on a restart. We
+ // can only safely do that if the app had windows when it was last running.
+ void SetHasWindows(const std::string& extension_id, bool has_windows);
+ bool HasWindows(const std::string& extension_id);
+
// Returns true if the user enabled this extension to be loaded in incognito
// mode.
bool IsIncognitoEnabled(const std::string& extension_id);
diff --git a/chrome/browser/extensions/platform_app_launcher.cc b/chrome/browser/extensions/platform_app_launcher.cc
index 8e22447..69f6f15 100644
--- a/chrome/browser/extensions/platform_app_launcher.cc
+++ b/chrome/browser/extensions/platform_app_launcher.cc
@@ -14,6 +14,8 @@
#include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h"
#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h"
#include "chrome/browser/extensions/api/file_system/file_system_api.h"
+#include "chrome/browser/extensions/event_names.h"
+#include "chrome/browser/extensions/event_router.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_process_manager.h"
@@ -402,9 +404,27 @@ void RestartPlatformAppWithFileEntries(
Profile* profile,
const Extension* extension,
const std::vector<SavedFileEntry>& file_entries) {
- scoped_refptr<SavedFileEntryLauncher> launcher = new SavedFileEntryLauncher(
- profile, extension, file_entries);
- launcher->Launch();
+ extensions::EventRouter* event_router =
+ ExtensionSystem::Get(profile)->event_router();
+ bool listening_to_restart = event_router->
+ ExtensionHasEventListener(extension->id(), event_names::kOnRestarted);
+
+ if (listening_to_restart) {
+ scoped_refptr<SavedFileEntryLauncher> launcher = new SavedFileEntryLauncher(
+ profile, extension, file_entries);
+ launcher->Launch();
+ return;
+ }
+
+ ExtensionPrefs* extension_prefs = ExtensionSystem::Get(profile)->
+ extension_service()->extension_prefs();
+ bool had_windows = extension_prefs->HasWindows(extension->id());
+ extension_prefs->SetHasWindows(extension->id(), false);
+ bool listening_to_launch = event_router->
+ ExtensionHasEventListener(extension->id(), event_names::kOnLaunched);
+
+ if (listening_to_launch && had_windows)
+ LaunchPlatformAppWithNoData(profile, extension);
}
} // namespace extensions
diff --git a/chrome/browser/extensions/shell_window_registry.h b/chrome/browser/extensions/shell_window_registry.h
index 062b2ad..dca2105 100644
--- a/chrome/browser/extensions/shell_window_registry.h
+++ b/chrome/browser/extensions/shell_window_registry.h
@@ -98,10 +98,6 @@ class ShellWindowRegistry : public ProfileKeyedService {
// ShellWindow::WindowType, or 0 for any window type.
static bool IsShellWindowRegisteredInAnyProfile(int window_type_mask);
- protected:
- void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached);
-
- private:
class Factory : public ProfileKeyedServiceFactory {
public:
static ShellWindowRegistry* GetForProfile(Profile* profile, bool create);
@@ -122,6 +118,10 @@ class ShellWindowRegistry : public ProfileKeyedService {
content::BrowserContext* context) const OVERRIDE;
};
+ protected:
+ void OnDevToolsStateChanged(content::DevToolsAgentHost*, bool attached);
+
+ private:
Profile* profile_;
ShellWindowSet shell_windows_;
InspectedWindowSet inspected_windows_;
diff --git a/chrome/browser/ui/extensions/shell_window.cc b/chrome/browser/ui/extensions/shell_window.cc
index bf81e1c..b4a725b 100644
--- a/chrome/browser/ui/extensions/shell_window.cc
+++ b/chrome/browser/ui/extensions/shell_window.cc
@@ -98,6 +98,7 @@ ShellWindow::ShellWindow(Profile* profile,
const extensions::Extension* extension)
: profile_(profile),
extension_(extension),
+ extension_id_(extension->id()),
window_type_(WINDOW_TYPE_DEFAULT),
image_loader_ptr_factory_(this),
fullscreen_for_window_api_(false),
diff --git a/chrome/browser/ui/extensions/shell_window.h b/chrome/browser/ui/extensions/shell_window.h
index ee83cc5..10b5a1d 100644
--- a/chrome/browser/ui/extensions/shell_window.h
+++ b/chrome/browser/ui/extensions/shell_window.h
@@ -142,6 +142,7 @@ class ShellWindow : public content::NotificationObserver,
const std::string& window_key() const { return window_key_; }
const SessionID& session_id() const { return session_id_; }
const extensions::Extension* extension() const { return extension_; }
+ const std::string& extension_id() const { return extension_id_; }
content::WebContents* web_contents() const;
WindowType window_type() const { return window_type_; }
bool window_type_is_panel() const {
@@ -274,6 +275,7 @@ class ShellWindow : public content::NotificationObserver,
Profile* profile_; // weak pointer - owned by ProfileManager.
// weak pointer - owned by ExtensionService.
const extensions::Extension* extension_;
+ const std::string extension_id_;
// Identifier that is used when saving and restoring geometry for this
// window.