summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_main.cc2
-rw-r--r--chrome/browser/first_run.cc67
-rw-r--r--chrome/browser/first_run.h11
-rw-r--r--chrome/browser/importer/importer.cc13
-rw-r--r--chrome/browser/importer/importer.h13
-rw-r--r--chrome/browser/views/importing_progress_view.cc9
6 files changed, 93 insertions, 22 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index 6e39b7c..0da4522 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -433,7 +433,7 @@ int BrowserMain(CommandLine &parsed_command_line, int show_command,
// Importing other browser settings is done in a browser-like process
// that exits when this task has finished.
if (parsed_command_line.HasSwitch(switches::kImport))
- return FirstRun::ImportWithUI(profile, parsed_command_line);
+ return FirstRun::ImportNow(profile, parsed_command_line);
// When another process is running, use it instead of starting us.
if (message_window.NotifyOtherProcess(show_command))
diff --git a/chrome/browser/first_run.cc b/chrome/browser/first_run.cc
index b4b750e..ad3376c 100644
--- a/chrome/browser/first_run.cc
+++ b/chrome/browser/first_run.cc
@@ -26,6 +26,7 @@
#include "chrome/browser/views/first_run_view.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/json_value_serializer.h"
#include "chrome/common/pref_service.h"
#include "chrome/installer/util/shell_util.h"
#include "chrome/views/accelerator_handler.h"
@@ -131,6 +132,18 @@ bool FirstRun::CreateSentinel() {
return true;
}
+DictionaryValue* ReadJSONPrefs(const std::wstring& file) {
+ JSONFileValueSerializer json(file);
+ Value* root;
+ if (!json.Deserialize(&root))
+ return NULL;
+ if (!root->IsType(Value::TYPE_DICTIONARY)) {
+ delete root;
+ return NULL;
+ }
+ return static_cast<DictionaryValue*>(root);
+}
+
FirstRun::MasterPrefResult FirstRun::ProcessMasterPreferences(
const std::wstring& user_data_dir,
const std::wstring& master_prefs_path) {
@@ -142,8 +155,6 @@ FirstRun::MasterPrefResult FirstRun::ProcessMasterPreferences(
if (!PathService::Get(base::DIR_EXE, &master_path))
return MASTER_PROFILE_ERROR;
file_util::AppendToPath(&master_path, kDefaultMasterPrefs);
- if (!file_util::PathExists(master_path))
- return MASTER_PROFILE_NOT_FOUND;
master_prefs = master_path;
} else {
master_prefs = master_prefs_path;
@@ -153,13 +164,26 @@ FirstRun::MasterPrefResult FirstRun::ProcessMasterPreferences(
if (user_prefs.empty())
return MASTER_PROFILE_ERROR;
+ scoped_ptr<DictionaryValue> json_root(ReadJSONPrefs(master_prefs));
+ if (!json_root.get())
+ return MASTER_PROFILE_ERROR;
+
+ bool skip_first_run_ui = false;
+ json_root->GetBoolean(L"skip_first_run_ui", &skip_first_run_ui);
+
// The master prefs are regular prefs so we can just copy the file
// to the default place and they just work.
if (!file_util::CopyFile(master_prefs, user_prefs))
return MASTER_PROFILE_ERROR;
- // TODO (cpu): Process the 'distribution' dictionary and return the
- // appropriate values.
+ if (!skip_first_run_ui)
+ return MASTER_PROFILE_DO_FIRST_RUN_UI;
+
+ // Automatically import search provider. This launches the importer
+ // process and blocks until done or until it fails. The second parameter
+ // in zero means to use the default browser.
+ FirstRun::ImportSettings(NULL, 0, SEARCH_ENGINES, NULL);
+
return MASTER_PROFILE_NO_FIRST_RUN_UI;
}
@@ -285,13 +309,14 @@ class HungImporterMonitor : public WorkerThreadTicker::Callback {
DISALLOW_EVIL_CONSTRUCTORS(HungImporterMonitor);
};
-// This class is used by FirstRun::ImportWithUI to get notified of the outcome
-// of the import operation. It differs from ImportProcessRunner in that this
+// This class is used by FirstRun::ImportNow to get notified of the outcome of
+// the import operation. It differs from ImportProcessRunner in that this
// class executes in the context of importing child process.
// The values that it handles are meant to be used as the process exit code.
class FirstRunImportObserver : public ImportObserver {
public:
- FirstRunImportObserver() : import_result_(ResultCodes::NORMAL_EXIT) {
+ FirstRunImportObserver()
+ : loop_running_(false), import_result_(ResultCodes::NORMAL_EXIT) {
}
int import_result() const {
return import_result_;
@@ -304,11 +329,19 @@ class FirstRunImportObserver : public ImportObserver {
import_result_ = ResultCodes::NORMAL_EXIT;
Finish();
}
+
+ void RunLoop() {
+ loop_running_ = true;
+ MessageLoop::current()->Run();
+ }
+
private:
void Finish() {
- MessageLoop::current()->Quit();
+ if (loop_running_)
+ MessageLoop::current()->Quit();
}
+ bool loop_running_;
int import_result_;
DISALLOW_EVIL_CONSTRUCTORS(FirstRunImportObserver);
};
@@ -357,7 +390,8 @@ bool FirstRun::ImportSettings(Profile* profile, int browser,
// Activate the importer monitor. It awakes periodically in another thread
// and checks that the importer UI is still pumping messages.
- HungImporterMonitor hang_monitor(parent_window, import_process);
+ if (parent_window)
+ HungImporterMonitor hang_monitor(parent_window, import_process);
// We block inside the import_runner ctor, pumping messages until the
// importer process ends. This can happen either by completing the import
@@ -366,11 +400,13 @@ bool FirstRun::ImportSettings(Profile* profile, int browser,
// Import process finished. Reload the prefs, because importer may set
// the pref value.
- profile->GetPrefs()->ReloadPersistentPrefs();
+ if (profile)
+ profile->GetPrefs()->ReloadPersistentPrefs();
+
return (import_runner.exit_code() == ResultCodes::NORMAL_EXIT);
}
-int FirstRun::ImportWithUI(Profile* profile, const CommandLine& cmdline) {
+int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) {
std::wstring import_info = cmdline.GetSwitchValue(switches::kImport);
if (import_info.empty()) {
NOTREACHED();
@@ -386,6 +422,13 @@ int FirstRun::ImportWithUI(Profile* profile, const CommandLine& cmdline) {
}
scoped_refptr<ImporterHost> importer_host = new ImporterHost();
FirstRunImportObserver observer;
+
+ // If there is no parent window, we run in headless mode which amounts
+ // to having the windows hidden and if there is user action required the
+ // import is automatically canceled.
+ if (!parent_window)
+ importer_host->set_headless();
+
StartImportingWithUI(
parent_window,
items_to_import,
@@ -394,7 +437,7 @@ int FirstRun::ImportWithUI(Profile* profile, const CommandLine& cmdline) {
profile,
&observer,
true);
- MessageLoop::current()->Run();
+ observer.RunLoop();
return observer.import_result();
}
diff --git a/chrome/browser/first_run.h b/chrome/browser/first_run.h
index dc75760..81f576a 100644
--- a/chrome/browser/first_run.h
+++ b/chrome/browser/first_run.h
@@ -39,17 +39,20 @@ class FirstRun {
// browser process that just does the import with the import progress UI.
static bool ImportSettings(Profile* profile, int browser,
int items_to_import, HWND parent_window);
- // Import browser items with a progress UI. The browser and the items to
+ // Import browser items in this process. The browser and the items to
// import are encoded int the command line. This function is paired with
- // FirstRun::ImportSettings().
- static int ImportWithUI(Profile* profile, const CommandLine& cmdline);
+ // FirstRun::ImportSettings(). This function might or might not show
+ // a visible UI depending on the cmdline parameters.
+ static int ImportNow(Profile* profile, const CommandLine& cmdline);
// These are the possible results of calling ProcessMasterPreferences.
+ // Some of the results can be combined, so they are bit flags.
enum MasterPrefResult {
MASTER_PROFILE_NOT_FOUND = 0,
MASTER_PROFILE_ERROR = 1,
MASTER_PROFILE_SHOW_EULA = 2,
- MASTER_PROFILE_NO_FIRST_RUN_UI = 4
+ MASTER_PROFILE_NO_FIRST_RUN_UI = 4,
+ MASTER_PROFILE_DO_FIRST_RUN_UI = 8
};
// The master preferences is a JSON file with the same entries as the
diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc
index 4c600d9..e1cbd13 100644
--- a/chrome/browser/importer/importer.cc
+++ b/chrome/browser/importer/importer.cc
@@ -308,7 +308,8 @@ ImporterHost::ImporterHost()
file_loop_(g_browser_process->file_thread()->message_loop()),
waiting_for_bookmarkbar_model_(false),
waiting_for_template_url_model_(false),
- is_source_readable_(true) {
+ is_source_readable_(true),
+ headless_(false) {
DetectSourceProfiles();
}
@@ -319,7 +320,8 @@ ImporterHost::ImporterHost(MessageLoop* file_loop)
file_loop_(file_loop),
waiting_for_bookmarkbar_model_(false),
waiting_for_template_url_model_(false),
- is_source_readable_(true) {
+ is_source_readable_(true),
+ headless_(false) {
DetectSourceProfiles();
}
@@ -346,8 +348,11 @@ void ImporterHost::Observe(NotificationType type,
}
void ImporterHost::ShowWarningDialog() {
- views::Window::CreateChromeWindow(GetActiveWindow(), gfx::Rect(),
- new ImporterLockView(this))->Show();
+ if (headless_)
+ OnLockViewEnd(false);
+ else
+ views::Window::CreateChromeWindow(GetActiveWindow(), gfx::Rect(),
+ new ImporterLockView(this))->Show();
}
void ImporterHost::OnLockViewEnd(bool is_continue) {
diff --git a/chrome/browser/importer/importer.h b/chrome/browser/importer/importer.h
index 494cf1c..3d83ca0 100644
--- a/chrome/browser/importer/importer.h
+++ b/chrome/browser/importer/importer.h
@@ -164,6 +164,16 @@ class ImporterHost : public base::RefCounted<ImporterHost>,
// Cancel
void Cancel();
+ // When in headless mode, the importer will not show the warning dialog and
+ // the outcome is as if the user had canceled the import operation.
+ void set_headless() {
+ headless_ = true;
+ }
+
+ bool is_headless() const {
+ return headless_;
+ }
+
// An interface which an object can implement to be notified of events during
// the import process.
class Observer {
@@ -241,6 +251,9 @@ class ImporterHost : public base::RefCounted<ImporterHost>,
// True if source profile is readable.
bool is_source_readable_;
+ // True if UI is not to be shown.
+ bool headless_;
+
// Firefox profile lock.
scoped_ptr<FirefoxProfileLock> firefox_lock_;
diff --git a/chrome/browser/views/importing_progress_view.cc b/chrome/browser/views/importing_progress_view.cc
index 203cea2..3d759ef 100644
--- a/chrome/browser/views/importing_progress_view.cc
+++ b/chrome/browser/views/importing_progress_view.cc
@@ -278,7 +278,14 @@ void StartImportingWithUI(HWND parent_window,
DCHECK(items != 0);
ImportingProgressView* v = new ImportingProgressView(
source_profile.description, items, coordinator, observer, parent_window);
- views::Window::CreateChromeWindow(parent_window, gfx::Rect(), v)->Show();
+ views::Window* window =
+ views::Window::CreateChromeWindow(parent_window, gfx::Rect(), v);
+
+ // In headless mode it means that we don't show the progress window, but it
+ // still need it to exist. No user interaction will be required.
+ if (!coordinator->is_headless())
+ window->Show();
+
coordinator->StartImportSettings(source_profile, items,
new ProfileWriter(target_profile),
first_run);