Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2347)

Unified Diff: apps/app_shim/chrome_main_app_mode_mac.mm

Issue 585123004: Mac: Give app_shim code a nicer home (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: various cleanups Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: apps/app_shim/chrome_main_app_mode_mac.mm
diff --git a/apps/app_shim/chrome_main_app_mode_mac.mm b/apps/app_shim/chrome_main_app_mode_mac.mm
deleted file mode 100644
index 21e3fe21835e1efbebd21f8c04a52a290f62d15e..0000000000000000000000000000000000000000
--- a/apps/app_shim/chrome_main_app_mode_mac.mm
+++ /dev/null
@@ -1,693 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// On Mac, one can't make shortcuts with command-line arguments. Instead, we
-// produce small app bundles which locate the Chromium framework and load it,
-// passing the appropriate data. This is the entry point into the framework for
-// those app bundles.
-
-#import <Cocoa/Cocoa.h>
-#include <vector>
-
-#include "apps/app_shim/app_shim_messages.h"
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/mac/bundle_locations.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/launch_services_util.h"
-#include "base/mac/mac_logging.h"
-#include "base/mac/mac_util.h"
-#include "base/mac/scoped_nsautorelease_pool.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/mac/sdk_forward_declarations.h"
-#include "base/message_loop/message_loop.h"
-#include "base/path_service.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/threading/thread.h"
-#include "chrome/common/chrome_constants.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/mac/app_mode_common.h"
-#include "grit/generated_resources.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/ipc_listener.h"
-#include "ipc/ipc_message.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-
-namespace {
-
-// Timeout in seconds to wait for a reply for the initial Apple Event. Note that
-// kAEDefaultTimeout on Mac is "about one minute" according to Apple's
-// documentation, but is no longer supported for asynchronous Apple Events.
-const int kPingChromeTimeoutSeconds = 60;
-
-const app_mode::ChromeAppModeInfo* g_info;
-base::Thread* g_io_thread = NULL;
-
-} // namespace
-
-class AppShimController;
-
-// An application delegate to catch user interactions and send the appropriate
-// IPC messages to Chrome.
-@interface AppShimDelegate : NSObject<NSApplicationDelegate> {
- @private
- AppShimController* appShimController_; // Weak, initially NULL.
- BOOL terminateNow_;
- BOOL terminateRequested_;
- std::vector<base::FilePath> filesToOpenAtStartup_;
-}
-
-// The controller is initially NULL. Setting it indicates to the delegate that
-// the controller has finished initialization.
-- (void)setController:(AppShimController*)controller;
-
-// Gets files that were queued because the controller was not ready.
-// Returns whether any FilePaths were added to |out|.
-- (BOOL)getFilesToOpenAtStartup:(std::vector<base::FilePath>*)out;
-
-// If the controller is ready, this sends a FocusApp with the files to open.
-// Otherwise, this adds the files to |filesToOpenAtStartup_|.
-// Takes an array of NSString*.
-- (void)openFiles:(NSArray*)filename;
-
-// Terminate immediately. This is necessary as we override terminate: to send
-// a QuitApp message.
-- (void)terminateNow;
-
-@end
-
-// The AppShimController is responsible for communication with the main Chrome
-// process, and generally controls the lifetime of the app shim process.
-class AppShimController : public IPC::Listener {
- public:
- AppShimController();
- virtual ~AppShimController();
-
- // Called when the main Chrome process responds to the Apple Event ping that
- // was sent, or when the ping fails (if |success| is false).
- void OnPingChromeReply(bool success);
-
- // Called |kPingChromeTimeoutSeconds| after startup, to allow a timeout on the
- // ping event to be detected.
- void OnPingChromeTimeout();
-
- // Connects to Chrome and sends a LaunchApp message.
- void Init();
-
- // Create a channel from |socket_path| and send a LaunchApp message.
- void CreateChannelAndSendLaunchApp(const base::FilePath& socket_path);
-
- // Builds main menu bar items.
- void SetUpMenu();
-
- void SendSetAppHidden(bool hidden);
-
- void SendQuitApp();
-
- // Called when the app is activated, e.g. by clicking on it in the dock, by
- // dropping a file on the dock icon, or by Cmd+Tabbing to it.
- // Returns whether the message was sent.
- bool SendFocusApp(apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files);
-
- private:
- // IPC::Listener implemetation.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- virtual void OnChannelError() OVERRIDE;
-
- // If Chrome failed to launch the app, |success| will be false and the app
- // shim process should die.
- void OnLaunchAppDone(apps::AppShimLaunchResult result);
-
- // Hide this app.
- void OnHide();
-
- // Requests user attention.
- void OnRequestUserAttention();
- void OnSetUserAttention(apps::AppShimAttentionType attention_type);
-
- // Terminates the app shim process.
- void Close();
-
- base::FilePath user_data_dir_;
- scoped_ptr<IPC::ChannelProxy> channel_;
- base::scoped_nsobject<AppShimDelegate> delegate_;
- bool launch_app_done_;
- bool ping_chrome_reply_received_;
- NSInteger attention_request_id_;
-
- DISALLOW_COPY_AND_ASSIGN(AppShimController);
-};
-
-AppShimController::AppShimController()
- : delegate_([[AppShimDelegate alloc] init]),
- launch_app_done_(false),
- ping_chrome_reply_received_(false),
- attention_request_id_(0) {
- // Since AppShimController is created before the main message loop starts,
- // NSApp will not be set, so use sharedApplication.
- [[NSApplication sharedApplication] setDelegate:delegate_];
-}
-
-AppShimController::~AppShimController() {
- // Un-set the delegate since NSApplication does not retain it.
- [[NSApplication sharedApplication] setDelegate:nil];
-}
-
-void AppShimController::OnPingChromeReply(bool success) {
- ping_chrome_reply_received_ = true;
- if (!success) {
- [NSApp terminate:nil];
- return;
- }
-
- Init();
-}
-
-void AppShimController::OnPingChromeTimeout() {
- if (!ping_chrome_reply_received_)
- [NSApp terminate:nil];
-}
-
-void AppShimController::Init() {
- DCHECK(g_io_thread);
-
- SetUpMenu();
-
- // Chrome will relaunch shims when relaunching apps.
- if (base::mac::IsOSLionOrLater())
- [NSApp disableRelaunchOnLogin];
-
- // The user_data_dir for shims actually contains the app_data_path.
- // I.e. <user_data_dir>/<profile_dir>/Web Applications/_crx_extensionid/
- user_data_dir_ = g_info->user_data_dir.DirName().DirName().DirName();
- CHECK(!user_data_dir_.empty());
-
- base::FilePath symlink_path =
- user_data_dir_.Append(app_mode::kAppShimSocketSymlinkName);
-
- base::FilePath socket_path;
- if (!base::ReadSymbolicLink(symlink_path, &socket_path)) {
- // The path in the user data dir is not a symlink, try connecting directly.
- CreateChannelAndSendLaunchApp(symlink_path);
- return;
- }
-
- app_mode::VerifySocketPermissions(socket_path);
-
- CreateChannelAndSendLaunchApp(socket_path);
-}
-
-void AppShimController::CreateChannelAndSendLaunchApp(
- const base::FilePath& socket_path) {
- IPC::ChannelHandle handle(socket_path.value());
- channel_ = IPC::ChannelProxy::Create(handle,
- IPC::Channel::MODE_NAMED_CLIENT,
- this,
- g_io_thread->message_loop_proxy().get());
-
- bool launched_by_chrome =
- CommandLine::ForCurrentProcess()->HasSwitch(
- app_mode::kLaunchedByChromeProcessId);
- apps::AppShimLaunchType launch_type = launched_by_chrome ?
- apps::APP_SHIM_LAUNCH_REGISTER_ONLY : apps::APP_SHIM_LAUNCH_NORMAL;
-
- [delegate_ setController:this];
-
- std::vector<base::FilePath> files;
- [delegate_ getFilesToOpenAtStartup:&files];
-
- channel_->Send(new AppShimHostMsg_LaunchApp(
- g_info->profile_dir, g_info->app_mode_id, launch_type, files));
-}
-
-void AppShimController::SetUpMenu() {
- NSString* title = base::SysUTF16ToNSString(g_info->app_mode_name);
-
- // Create a main menu since [NSApp mainMenu] is nil.
- base::scoped_nsobject<NSMenu> main_menu([[NSMenu alloc] initWithTitle:title]);
-
- // The title of the first item is replaced by OSX with the name of the app and
- // bold styling. Create a dummy item for this and make it hidden.
- NSMenuItem* dummy_item = [main_menu addItemWithTitle:title
- action:nil
- keyEquivalent:@""];
- base::scoped_nsobject<NSMenu> dummy_submenu(
- [[NSMenu alloc] initWithTitle:title]);
- [dummy_item setSubmenu:dummy_submenu];
- [dummy_item setHidden:YES];
-
- // Construct an unbolded app menu, to match how it appears in the Chrome menu
- // bar when the app is focused.
- NSMenuItem* item = [main_menu addItemWithTitle:title
- action:nil
- keyEquivalent:@""];
- base::scoped_nsobject<NSMenu> submenu([[NSMenu alloc] initWithTitle:title]);
- [item setSubmenu:submenu];
-
- // Add a quit entry.
- NSString* quit_localized_string =
- l10n_util::GetNSStringF(IDS_EXIT_MAC, g_info->app_mode_name);
- [submenu addItemWithTitle:quit_localized_string
- action:@selector(terminate:)
- keyEquivalent:@"q"];
-
- // Add File, Edit, and Window menus. These are just here to make the
- // transition smoother, i.e. from another application to the shim then to
- // Chrome.
- [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_FILE_MENU_MAC)
- action:nil
- keyEquivalent:@""];
- [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_EDIT_MENU_MAC)
- action:nil
- keyEquivalent:@""];
- [main_menu addItemWithTitle:l10n_util::GetNSString(IDS_WINDOW_MENU_MAC)
- action:nil
- keyEquivalent:@""];
-
- [NSApp setMainMenu:main_menu];
-}
-
-void AppShimController::SendQuitApp() {
- channel_->Send(new AppShimHostMsg_QuitApp);
-}
-
-bool AppShimController::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(AppShimController, message)
- IPC_MESSAGE_HANDLER(AppShimMsg_LaunchApp_Done, OnLaunchAppDone)
- IPC_MESSAGE_HANDLER(AppShimMsg_Hide, OnHide)
- IPC_MESSAGE_HANDLER(AppShimMsg_RequestUserAttention, OnRequestUserAttention)
- IPC_MESSAGE_HANDLER(AppShimMsg_SetUserAttention, OnSetUserAttention)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- return handled;
-}
-
-void AppShimController::OnChannelError() {
- Close();
-}
-
-void AppShimController::OnLaunchAppDone(apps::AppShimLaunchResult result) {
- if (result != apps::APP_SHIM_LAUNCH_SUCCESS) {
- Close();
- return;
- }
-
- std::vector<base::FilePath> files;
- if ([delegate_ getFilesToOpenAtStartup:&files])
- SendFocusApp(apps::APP_SHIM_FOCUS_OPEN_FILES, files);
-
- launch_app_done_ = true;
-}
-
-void AppShimController::OnHide() {
- [NSApp hide:nil];
-}
-
-void AppShimController::OnRequestUserAttention() {
- OnSetUserAttention(apps::APP_SHIM_ATTENTION_INFORMATIONAL);
-}
-
-void AppShimController::OnSetUserAttention(
- apps::AppShimAttentionType attention_type) {
- switch (attention_type) {
- case apps::APP_SHIM_ATTENTION_CANCEL:
- [NSApp cancelUserAttentionRequest:attention_request_id_];
- attention_request_id_ = 0;
- break;
- case apps::APP_SHIM_ATTENTION_CRITICAL:
- attention_request_id_ = [NSApp requestUserAttention:NSCriticalRequest];
- break;
- case apps::APP_SHIM_ATTENTION_INFORMATIONAL:
- attention_request_id_ =
- [NSApp requestUserAttention:NSInformationalRequest];
- break;
- case apps::APP_SHIM_ATTENTION_NUM_TYPES:
- NOTREACHED();
- }
-}
-
-void AppShimController::Close() {
- [delegate_ terminateNow];
-}
-
-bool AppShimController::SendFocusApp(apps::AppShimFocusType focus_type,
- const std::vector<base::FilePath>& files) {
- if (launch_app_done_) {
- channel_->Send(new AppShimHostMsg_FocusApp(focus_type, files));
- return true;
- }
-
- return false;
-}
-
-void AppShimController::SendSetAppHidden(bool hidden) {
- channel_->Send(new AppShimHostMsg_SetAppHidden(hidden));
-}
-
-@implementation AppShimDelegate
-
-- (BOOL)getFilesToOpenAtStartup:(std::vector<base::FilePath>*)out {
- if (filesToOpenAtStartup_.empty())
- return NO;
-
- out->insert(out->end(),
- filesToOpenAtStartup_.begin(),
- filesToOpenAtStartup_.end());
- filesToOpenAtStartup_.clear();
- return YES;
-}
-
-- (void)setController:(AppShimController*)controller {
- appShimController_ = controller;
-}
-
-- (void)openFiles:(NSArray*)filenames {
- std::vector<base::FilePath> filePaths;
- for (NSString* filename in filenames)
- filePaths.push_back(base::mac::NSStringToFilePath(filename));
-
- // If the AppShimController is ready, try to send a FocusApp. If that fails,
- // (e.g. if launching has not finished), enqueue the files.
- if (appShimController_ &&
- appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_OPEN_FILES,
- filePaths)) {
- return;
- }
-
- filesToOpenAtStartup_.insert(filesToOpenAtStartup_.end(),
- filePaths.begin(),
- filePaths.end());
-}
-
-- (BOOL)application:(NSApplication*)app
- openFile:(NSString*)filename {
- [self openFiles:@[filename]];
- return YES;
-}
-
-- (void)application:(NSApplication*)app
- openFiles:(NSArray*)filenames {
- [self openFiles:filenames];
- [app replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
-}
-
-- (BOOL)applicationOpenUntitledFile:(NSApplication*)app {
- if (appShimController_) {
- return appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_REOPEN,
- std::vector<base::FilePath>());
- }
-
- return NO;
-}
-
-- (void)applicationWillBecomeActive:(NSNotification*)notification {
- if (appShimController_) {
- appShimController_->SendFocusApp(apps::APP_SHIM_FOCUS_NORMAL,
- std::vector<base::FilePath>());
- }
-}
-
-- (NSApplicationTerminateReply)
- applicationShouldTerminate:(NSApplication*)sender {
- if (terminateNow_ || !appShimController_)
- return NSTerminateNow;
-
- appShimController_->SendQuitApp();
- // Wait for the channel to close before terminating.
- terminateRequested_ = YES;
- return NSTerminateLater;
-}
-
-- (void)applicationWillHide:(NSNotification*)notification {
- if (appShimController_)
- appShimController_->SendSetAppHidden(true);
-}
-
-- (void)applicationWillUnhide:(NSNotification*)notification {
- if (appShimController_)
- appShimController_->SendSetAppHidden(false);
-}
-
-- (void)terminateNow {
- if (terminateRequested_) {
- [NSApp replyToApplicationShouldTerminate:NSTerminateNow];
- return;
- }
-
- terminateNow_ = YES;
- [NSApp terminate:nil];
-}
-
-@end
-
-//-----------------------------------------------------------------------------
-
-// A ReplyEventHandler is a helper class to send an Apple Event to a process
-// and call a callback when the reply returns.
-//
-// This is used to 'ping' the main Chrome process -- once Chrome has sent back
-// an Apple Event reply, it's guaranteed that it has opened the IPC channel
-// that the app shim will connect to.
-@interface ReplyEventHandler : NSObject {
- base::Callback<void(bool)> onReply_;
- AEDesc replyEvent_;
-}
-// Sends an Apple Event to the process identified by |psn|, and calls |replyFn|
-// when the reply is received. Internally this creates a ReplyEventHandler,
-// which will delete itself once the reply event has been received.
-+ (void)pingProcess:(const ProcessSerialNumber&)psn
- andCall:(base::Callback<void(bool)>)replyFn;
-@end
-
-@interface ReplyEventHandler (PrivateMethods)
-// Initialise the reply event handler. Doesn't register any handlers until
-// |-pingProcess:| is called. |replyFn| is the function to be called when the
-// Apple Event reply arrives.
-- (id)initWithCallback:(base::Callback<void(bool)>)replyFn;
-
-// Sends an Apple Event ping to the process identified by |psn| and registers
-// to listen for a reply.
-- (void)pingProcess:(const ProcessSerialNumber&)psn;
-
-// Called when a response is received from the target process for the ping sent
-// by |-pingProcess:|.
-- (void)message:(NSAppleEventDescriptor*)event
- withReply:(NSAppleEventDescriptor*)reply;
-
-// Calls |onReply_|, passing it |success| to specify whether the ping was
-// successful.
-- (void)closeWithSuccess:(bool)success;
-@end
-
-@implementation ReplyEventHandler
-+ (void)pingProcess:(const ProcessSerialNumber&)psn
- andCall:(base::Callback<void(bool)>)replyFn {
- // The object will release itself when the reply arrives, or possibly earlier
- // if an unrecoverable error occurs.
- ReplyEventHandler* handler =
- [[ReplyEventHandler alloc] initWithCallback:replyFn];
- [handler pingProcess:psn];
-}
-@end
-
-@implementation ReplyEventHandler (PrivateMethods)
-- (id)initWithCallback:(base::Callback<void(bool)>)replyFn {
- if ((self = [super init])) {
- onReply_ = replyFn;
- }
- return self;
-}
-
-- (void)pingProcess:(const ProcessSerialNumber&)psn {
- // Register the reply listener.
- NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
- [em setEventHandler:self
- andSelector:@selector(message:withReply:)
- forEventClass:'aevt'
- andEventID:'ansr'];
- // Craft the Apple Event to send.
- NSAppleEventDescriptor* target = [NSAppleEventDescriptor
- descriptorWithDescriptorType:typeProcessSerialNumber
- bytes:&psn
- length:sizeof(psn)];
- NSAppleEventDescriptor* initial_event =
- [NSAppleEventDescriptor
- appleEventWithEventClass:app_mode::kAEChromeAppClass
- eventID:app_mode::kAEChromeAppPing
- targetDescriptor:target
- returnID:kAutoGenerateReturnID
- transactionID:kAnyTransactionID];
-
- // Note that AESendMessage effectively ignores kAEDefaultTimeout, because this
- // call does not pass kAEWantReceipt (which is deprecated and unsupported on
- // Mac). Instead, rely on OnPingChromeTimeout().
- OSStatus status = AESendMessage(
- [initial_event aeDesc], &replyEvent_, kAEQueueReply, kAEDefaultTimeout);
- if (status != noErr) {
- OSSTATUS_LOG(ERROR, status) << "AESendMessage";
- [self closeWithSuccess:false];
- }
-}
-
-- (void)message:(NSAppleEventDescriptor*)event
- withReply:(NSAppleEventDescriptor*)reply {
- [self closeWithSuccess:true];
-}
-
-- (void)closeWithSuccess:(bool)success {
- onReply_.Run(success);
- NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
- [em removeEventHandlerForEventClass:'aevt' andEventID:'ansr'];
- [self release];
-}
-@end
-
-//-----------------------------------------------------------------------------
-
-extern "C" {
-
-// |ChromeAppModeStart()| is the point of entry into the framework from the app
-// mode loader.
-__attribute__((visibility("default")))
-int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info);
-
-} // extern "C"
-
-int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info) {
- CommandLine::Init(info->argc, info->argv);
-
- base::mac::ScopedNSAutoreleasePool scoped_pool;
- base::AtExitManager exit_manager;
- chrome::RegisterPathProvider();
-
- if (info->major_version < app_mode::kCurrentChromeAppModeInfoMajorVersion) {
- RAW_LOG(ERROR, "App Mode Loader too old.");
- return 1;
- }
- if (info->major_version > app_mode::kCurrentChromeAppModeInfoMajorVersion) {
- RAW_LOG(ERROR, "Browser Framework too old to load App Shortcut.");
- return 1;
- }
-
- g_info = info;
-
- // Set bundle paths. This loads the bundles.
- base::mac::SetOverrideOuterBundlePath(g_info->chrome_outer_bundle_path);
- base::mac::SetOverrideFrameworkBundlePath(
- g_info->chrome_versioned_path.Append(chrome::kFrameworkName));
-
- // Calculate the preferred locale used by Chrome.
- // We can't use l10n_util::OverrideLocaleWithCocoaLocale() because it calls
- // [base::mac::OuterBundle() preferredLocalizations] which gets localizations
- // from the bundle of the running app (i.e. it is equivalent to
- // [[NSBundle mainBundle] preferredLocalizations]) instead of the target
- // bundle.
- NSArray* preferred_languages = [NSLocale preferredLanguages];
- NSArray* supported_languages = [base::mac::OuterBundle() localizations];
- std::string preferred_localization;
- for (NSString* language in preferred_languages) {
- if ([supported_languages containsObject:language]) {
- preferred_localization = base::SysNSStringToUTF8(language);
- break;
- }
- }
- std::string locale = l10n_util::NormalizeLocale(
- l10n_util::GetApplicationLocale(preferred_localization));
-
- // Load localized strings.
- ui::ResourceBundle::InitSharedInstanceWithLocale(
- locale, NULL, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
-
- // Launch the IO thread.
- base::Thread::Options io_thread_options;
- io_thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
- base::Thread *io_thread = new base::Thread("CrAppShimIO");
- io_thread->StartWithOptions(io_thread_options);
- g_io_thread = io_thread;
-
- // Find already running instances of Chrome.
- pid_t pid = -1;
- std::string chrome_process_id = CommandLine::ForCurrentProcess()->
- GetSwitchValueASCII(app_mode::kLaunchedByChromeProcessId);
- if (!chrome_process_id.empty()) {
- if (!base::StringToInt(chrome_process_id, &pid))
- LOG(FATAL) << "Invalid PID: " << chrome_process_id;
- } else {
- NSString* chrome_bundle_id = [base::mac::OuterBundle() bundleIdentifier];
- NSArray* existing_chrome = [NSRunningApplication
- runningApplicationsWithBundleIdentifier:chrome_bundle_id];
- if ([existing_chrome count] > 0)
- pid = [[existing_chrome objectAtIndex:0] processIdentifier];
- }
-
- AppShimController controller;
- base::MessageLoopForUI main_message_loop;
- main_message_loop.set_thread_name("MainThread");
- base::PlatformThread::SetName("CrAppShimMain");
-
- // In tests, launching Chrome does nothing, and we won't get a ping response,
- // so just assume the socket exists.
- if (pid == -1 &&
- !CommandLine::ForCurrentProcess()->HasSwitch(
- app_mode::kLaunchedForTest)) {
- // Launch Chrome if it isn't already running.
- ProcessSerialNumber psn;
- CommandLine command_line(CommandLine::NO_PROGRAM);
- command_line.AppendSwitch(switches::kSilentLaunch);
-
- // If the shim is the app launcher, pass --show-app-list when starting a new
- // Chrome process to inform startup codepaths and load the correct profile.
- if (info->app_mode_id == app_mode::kAppListModeId) {
- command_line.AppendSwitch(switches::kShowAppList);
- } else {
- command_line.AppendSwitchPath(switches::kProfileDirectory,
- info->profile_dir);
- }
-
- bool success =
- base::mac::OpenApplicationWithPath(base::mac::OuterBundlePath(),
- command_line,
- kLSLaunchDefaults,
- &psn);
- if (!success)
- return 1;
-
- base::Callback<void(bool)> on_ping_chrome_reply =
- base::Bind(&AppShimController::OnPingChromeReply,
- base::Unretained(&controller));
-
- // This code abuses the fact that Apple Events sent before the process is
- // fully initialized don't receive a reply until its run loop starts. Once
- // the reply is received, Chrome will have opened its IPC port, guaranteed.
- [ReplyEventHandler pingProcess:psn
- andCall:on_ping_chrome_reply];
-
- main_message_loop.PostDelayedTask(
- FROM_HERE,
- base::Bind(&AppShimController::OnPingChromeTimeout,
- base::Unretained(&controller)),
- base::TimeDelta::FromSeconds(kPingChromeTimeoutSeconds));
- } else {
- // Chrome already running. Proceed to init. This could still fail if Chrome
- // is still starting up or shutting down, but the process will exit quickly,
- // which is preferable to waiting for the Apple Event to timeout after one
- // minute.
- main_message_loop.PostTask(
- FROM_HERE,
- base::Bind(&AppShimController::Init,
- base::Unretained(&controller)));
- }
-
- main_message_loop.Run();
- return 0;
-}
« no previous file with comments | « apps/app_shim/app_shim_quit_interactive_uitest_mac.mm ('k') | apps/app_shim/extension_app_shim_handler_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698