summaryrefslogtreecommitdiff
path: root/apps/app_shim/extension_app_shim_handler_mac.cc
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2013-07-17 14:55:54 +0100
committerBen Murdoch <benm@google.com>2013-07-17 14:55:54 +0100
commit7dbb3d5cf0c15f500944d211057644d6a2f37371 (patch)
tree701119ba0596f51b0ab466d6472b0f98211359c5 /apps/app_shim/extension_app_shim_handler_mac.cc
parentb2ecf4836a0eb284ddac7746b1f7ba613777a739 (diff)
downloadchromium_org-7dbb3d5cf0c15f500944d211057644d6a2f37371.tar.gz
Merge from Chromium at DEPS revision r212014
This commit was generated by merge_to_master.py. Change-Id: Ie0f261e9682cd8abea1eea1e51beab83d5eea21a
Diffstat (limited to 'apps/app_shim/extension_app_shim_handler_mac.cc')
-rw-r--r--apps/app_shim/extension_app_shim_handler_mac.cc119
1 files changed, 83 insertions, 36 deletions
diff --git a/apps/app_shim/extension_app_shim_handler_mac.cc b/apps/app_shim/extension_app_shim_handler_mac.cc
index 13114e596f..2dc2d5bf51 100644
--- a/apps/app_shim/extension_app_shim_handler_mac.cc
+++ b/apps/app_shim/extension_app_shim_handler_mac.cc
@@ -10,6 +10,7 @@
#include "base/files/file_path.h"
#include "base/logging.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
@@ -21,12 +22,27 @@
#include "chrome/browser/ui/extensions/native_app_window.h"
#include "chrome/browser/ui/web_applications/web_app_ui.h"
#include "chrome/browser/web_applications/web_app_mac.h"
-#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "ui/base/cocoa/focus_window_set.h"
+namespace {
+
+void ProfileLoadedCallback(base::Callback<void(Profile*)> callback,
+ Profile* profile,
+ Profile::CreateStatus status) {
+ if (status == Profile::CREATE_STATUS_INITIALIZED) {
+ callback.Run(profile);
+ return;
+ }
+
+ // This should never get an error since it only loads existing profiles.
+ DCHECK_EQ(Profile::CREATE_STATUS_CREATED, status);
+}
+
+} // namespace
+
namespace apps {
typedef extensions::ShellWindowRegistry::ShellWindowList ShellWindowList;
@@ -45,7 +61,21 @@ Profile* ExtensionAppShimHandler::Delegate::ProfileForPath(
const base::FilePath& path) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
base::FilePath full_path = profile_manager->user_data_dir().Append(path);
- return profile_manager->GetProfile(full_path);
+ Profile* profile = profile_manager->GetProfileByPath(full_path);
+
+ // Use IsValidProfile to check if the profile has been created.
+ return profile && profile_manager->IsValidProfile(profile) ? profile : NULL;
+}
+
+void ExtensionAppShimHandler::Delegate::LoadProfileAsync(
+ const base::FilePath& path,
+ base::Callback<void(Profile*)> callback) {
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ base::FilePath full_path = profile_manager->user_data_dir().Append(path);
+ profile_manager->CreateProfileAsync(
+ full_path,
+ base::Bind(&ProfileLoadedCallback, callback),
+ string16(), string16(), false);
}
ShellWindowList ExtensionAppShimHandler::Delegate::GetWindows(
@@ -90,7 +120,8 @@ void ExtensionAppShimHandler::Delegate::MaybeTerminate() {
ExtensionAppShimHandler::ExtensionAppShimHandler()
: delegate_(new Delegate),
- browser_opened_ever_(false) {
+ browser_opened_ever_(false),
+ weak_factory_(this) {
// This is instantiated in BrowserProcessImpl::PreMainMessageLoopRun with
// AppShimHostManager. Since PROFILE_CREATED is not fired until
// ProfileManager::GetLastUsedProfile/GetLastOpenedProfiles, this should catch
@@ -107,8 +138,11 @@ ExtensionAppShimHandler::ExtensionAppShimHandler()
ExtensionAppShimHandler::~ExtensionAppShimHandler() {}
-bool ExtensionAppShimHandler::OnShimLaunch(Host* host,
+void ExtensionAppShimHandler::OnShimLaunch(Host* host,
AppShimLaunchType launch_type) {
+ const std::string& app_id = host->GetAppId();
+ DCHECK(extensions::Extension::IdIsValid(app_id));
+
const base::FilePath& profile_path = host->GetProfilePath();
DCHECK(!profile_path.empty());
@@ -117,32 +151,52 @@ bool ExtensionAppShimHandler::OnShimLaunch(Host* host,
// TODO(jackhou): Add some UI for this case and remove the LOG.
LOG(ERROR) << "Requested directory is not a known profile '"
<< profile_path.value() << "'.";
- return false;
+ host->OnAppLaunchComplete(APP_SHIM_LAUNCH_PROFILE_NOT_FOUND);
+ return;
}
Profile* profile = delegate_->ProfileForPath(profile_path);
- const std::string& app_id = host->GetAppId();
- if (!extensions::Extension::IdIsValid(app_id)) {
- LOG(ERROR) << "Bad app ID from app shim launch message.";
- return false;
+ if (profile) {
+ OnProfileLoaded(host, launch_type, profile);
+ return;
}
+ // If the profile is not loaded, this must have been a launch by the shim.
+ // Load the profile asynchronously, the host will be registered in
+ // OnProfileLoaded.
+ DCHECK_EQ(APP_SHIM_LAUNCH_NORMAL, launch_type);
+ delegate_->LoadProfileAsync(
+ profile_path,
+ base::Bind(&ExtensionAppShimHandler::OnProfileLoaded,
+ weak_factory_.GetWeakPtr(),
+ host, launch_type));
+
+ // Return now. OnAppLaunchComplete will be called when the app is activated.
+}
+
+void ExtensionAppShimHandler::OnProfileLoaded(Host* host,
+ AppShimLaunchType launch_type,
+ Profile* profile) {
+ const std::string& app_id = host->GetAppId();
// TODO(jackhou): Add some UI for this case and remove the LOG.
const extensions::Extension* extension =
delegate_->GetAppExtension(profile, app_id);
if (!extension) {
LOG(ERROR) << "Attempted to launch nonexistent app with id '"
<< app_id << "'.";
- return false;
+ host->OnAppLaunchComplete(APP_SHIM_LAUNCH_APP_NOT_FOUND);
+ return;
}
- // If the shim was launched in response to a window appearing, but the window
- // is closed by the time the shim process launched, return false to close the
- // shim.
- if (launch_type == APP_SHIM_LAUNCH_REGISTER_ONLY &&
- delegate_->GetWindows(profile, app_id).empty()) {
- return false;
+ // The first host to claim this (profile, app_id) becomes the main host.
+ // For any others, focus or relaunch the app.
+ if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) {
+ OnShimFocus(host,
+ launch_type == APP_SHIM_LAUNCH_NORMAL ?
+ APP_SHIM_FOCUS_REOPEN : APP_SHIM_FOCUS_NORMAL);
+ host->OnAppLaunchComplete(APP_SHIM_LAUNCH_DUPLICATE_HOST);
+ return;
}
// TODO(jeremya): Handle the case that launching the app fails. Probably we
@@ -151,28 +205,18 @@ bool ExtensionAppShimHandler::OnShimLaunch(Host* host,
// life within a certain window.
if (launch_type == APP_SHIM_LAUNCH_NORMAL)
delegate_->LaunchApp(profile, extension);
-
- // The first host to claim this (profile, app_id) becomes the main host.
- // For any others, focus or relaunch the app and return false.
- if (!hosts_.insert(make_pair(make_pair(profile, app_id), host)).second) {
- OnShimFocus(host,
- launch_type == APP_SHIM_LAUNCH_NORMAL ?
- APP_SHIM_FOCUS_REOPEN : APP_SHIM_FOCUS_NORMAL);
- return false;
- }
-
- return true;
+ else
+ host->OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS);
}
void ExtensionAppShimHandler::OnShimClose(Host* host) {
- DCHECK(delegate_->ProfileExistsForPath(host->GetProfilePath()));
- Profile* profile = delegate_->ProfileForPath(host->GetProfilePath());
-
- HostMap::iterator it = hosts_.find(make_pair(profile, host->GetAppId()));
- // Any hosts other than the main host will still call OnShimClose, so ignore
- // them.
- if (it != hosts_.end() && it->second == host)
- hosts_.erase(it);
+ // This might be called when shutting down. Don't try to look up the profile
+ // since profile_manager might not be around.
+ for (HostMap::iterator it = hosts_.begin(); it != hosts_.end(); ) {
+ HostMap::iterator current = it++;
+ if (current->second == host)
+ hosts_.erase(current);
+ }
}
void ExtensionAppShimHandler::OnShimFocus(Host* host,
@@ -300,8 +344,11 @@ void ExtensionAppShimHandler::OnAppActivated(Profile* profile,
if (!extension)
return;
- if (hosts_.count(make_pair(profile, app_id)))
+ HostMap::iterator it = hosts_.find(make_pair(profile, app_id));
+ if (it != hosts_.end()) {
+ it->second->OnAppLaunchComplete(APP_SHIM_LAUNCH_SUCCESS);
return;
+ }
delegate_->LaunchShim(profile, extension);
}