1// Copyright (c) 2011 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 "chrome/browser/importer/profile_import_process_host.h"
6
7#include "base/command_line.h"
8#include "base/message_loop.h"
9#include "base/string_number_conversions.h"
10#include "base/values.h"
11#include "chrome/browser/importer/firefox_importer_utils.h"
12#include "chrome/browser/importer/profile_import_process_client.h"
13#include "chrome/browser/importer/profile_import_process_messages.h"
14#include "chrome/common/chrome_switches.h"
15#include "grit/generated_resources.h"
16#include "ipc/ipc_switches.h"
17#include "ui/base/l10n/l10n_util.h"
18
19ProfileImportProcessHost::ProfileImportProcessHost(
20    ProfileImportProcessClient* import_process_client,
21    BrowserThread::ID thread_id)
22    : BrowserChildProcessHost(PROFILE_IMPORT_PROCESS),
23      import_process_client_(import_process_client),
24      thread_id_(thread_id) {
25}
26
27ProfileImportProcessHost::~ProfileImportProcessHost() {
28}
29
30bool ProfileImportProcessHost::StartProfileImportProcess(
31    const importer::SourceProfile& source_profile,
32    uint16 items,
33    bool import_to_bookmark_bar) {
34  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
35  if (!StartProcess())
36    return false;
37
38  // Dictionary of all localized strings that could be needed by the importer
39  // in the external process.
40  DictionaryValue localized_strings;
41  localized_strings.SetString(
42      base::IntToString(IDS_BOOKMARK_GROUP_FROM_FIREFOX),
43      l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_FIREFOX));
44  localized_strings.SetString(
45      base::IntToString(IDS_BOOKMARK_GROUP_FROM_SAFARI),
46      l10n_util::GetStringUTF8(IDS_BOOKMARK_GROUP_FROM_SAFARI));
47  localized_strings.SetString(
48      base::IntToString(IDS_IMPORT_FROM_FIREFOX),
49      l10n_util::GetStringUTF8(IDS_IMPORT_FROM_FIREFOX));
50  localized_strings.SetString(
51      base::IntToString(IDS_IMPORT_FROM_GOOGLE_TOOLBAR),
52      l10n_util::GetStringUTF8(IDS_IMPORT_FROM_GOOGLE_TOOLBAR));
53  localized_strings.SetString(
54      base::IntToString(IDS_IMPORT_FROM_SAFARI),
55      l10n_util::GetStringUTF8(IDS_IMPORT_FROM_SAFARI));
56
57  Send(new ProfileImportProcessMsg_StartImport(
58      source_profile, items, localized_strings, import_to_bookmark_bar));
59  return true;
60}
61
62bool ProfileImportProcessHost::CancelProfileImportProcess() {
63  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
64  Send(new ProfileImportProcessMsg_CancelImport());
65  return true;
66}
67
68bool ProfileImportProcessHost::ReportImportItemFinished(
69    importer::ImportItem item) {
70  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
71  Send(new ProfileImportProcessMsg_ReportImportItemFinished(item));
72  return true;
73}
74
75FilePath ProfileImportProcessHost::GetProfileImportProcessCmd() {
76  return GetChildPath(true);
77}
78
79bool ProfileImportProcessHost::StartProcess() {
80  set_name(L"profile import process");
81
82  if (!CreateChannel())
83    return false;
84
85  FilePath exe_path = GetProfileImportProcessCmd();
86  if (exe_path.empty()) {
87    NOTREACHED() << "Unable to get profile import process binary name.";
88    return false;
89  }
90
91  CommandLine* cmd_line = new CommandLine(exe_path);
92  cmd_line->AppendSwitchASCII(switches::kProcessType,
93                              switches::kProfileImportProcess);
94  cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
95
96  SetCrashReporterCommandLine(cmd_line);
97
98  const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
99  if (browser_command_line.HasSwitch(switches::kChromeFrame))
100    cmd_line->AppendSwitch(switches::kChromeFrame);
101
102#if defined(OS_MACOSX)
103  base::environment_vector env;
104  std::string dylib_path = GetFirefoxDylibPath().value();
105  if (!dylib_path.empty())
106    env.push_back(std::make_pair("DYLD_FALLBACK_LIBRARY_PATH", dylib_path));
107
108  Launch(false, env, cmd_line);
109#elif defined(OS_WIN)
110  FilePath no_exposed_directory;
111
112  Launch(no_exposed_directory, cmd_line);
113#else
114  base::environment_vector env;
115
116  Launch(false, env, cmd_line);
117#endif
118
119  return true;
120}
121
122bool ProfileImportProcessHost::OnMessageReceived(const IPC::Message& message) {
123  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
124  BrowserThread::PostTask(
125      thread_id_, FROM_HERE,
126      NewRunnableMethod(import_process_client_.get(),
127                        &ProfileImportProcessClient::OnMessageReceived,
128                        message));
129  return true;
130}
131
132void ProfileImportProcessHost::OnProcessCrashed(int exit_code) {
133  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
134  BrowserThread::PostTask(
135      thread_id_, FROM_HERE,
136      NewRunnableMethod(import_process_client_.get(),
137                        &ProfileImportProcessClient::OnProcessCrashed,
138                        exit_code));
139}
140
141bool ProfileImportProcessHost::CanShutdown() {
142  return true;
143}
144