diff options
-rw-r--r-- | chrome/browser/browser_main.cc | 2 | ||||
-rw-r--r-- | chrome/browser/first_run.cc | 67 | ||||
-rw-r--r-- | chrome/browser/first_run.h | 11 | ||||
-rw-r--r-- | chrome/browser/importer/importer.cc | 13 | ||||
-rw-r--r-- | chrome/browser/importer/importer.h | 13 | ||||
-rw-r--r-- | chrome/browser/views/importing_progress_view.cc | 9 |
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); |