| Index: chrome/browser/first_run/first_run_win.cc
|
| diff --git a/chrome/browser/first_run/first_run_win.cc b/chrome/browser/first_run/first_run_win.cc
|
| index fd0849ae6d7c1c5ed9ec827fc383b3ae2c412774..7aa0e5da07637b860368551b1e610f15a193e283 100644
|
| --- a/chrome/browser/first_run/first_run_win.cc
|
| +++ b/chrome/browser/first_run/first_run_win.cc
|
| @@ -4,57 +4,32 @@
|
|
|
| #include "chrome/browser/first_run/first_run.h"
|
|
|
| -#include <windows.h>
|
| #include <shellapi.h>
|
| -#include <shlobj.h>
|
|
|
| +#include "base/base_paths.h"
|
| #include "base/callback.h"
|
| -#include "base/environment.h"
|
| #include "base/file_util.h"
|
| #include "base/files/file_path.h"
|
| #include "base/path_service.h"
|
| #include "base/prefs/pref_service.h"
|
| +#include "base/process.h"
|
| #include "base/process_util.h"
|
| -#include "base/stringprintf.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_split.h"
|
| #include "base/threading/sequenced_worker_pool.h"
|
| #include "base/time.h"
|
| -#include "base/utf_string_conversions.h"
|
| #include "base/win/metro.h"
|
| -#include "base/win/object_watcher.h"
|
| -#include "base/win/windows_version.h"
|
| -#include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/first_run/first_run_internal.h"
|
| -#include "chrome/browser/importer/importer_host.h"
|
| -#include "chrome/browser/importer/importer_list.h"
|
| -#include "chrome/browser/process_singleton.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/shell_integration.h"
|
| #include "chrome/common/chrome_constants.h"
|
| #include "chrome/common/chrome_paths.h"
|
| -#include "chrome/common/chrome_result_codes.h"
|
| #include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/pref_names.h"
|
| -#include "chrome/common/worker_thread_ticker.h"
|
| -#include "chrome/installer/util/browser_distribution.h"
|
| #include "chrome/installer/util/google_update_settings.h"
|
| #include "chrome/installer/util/install_util.h"
|
| #include "chrome/installer/util/master_preferences.h"
|
| #include "chrome/installer/util/master_preferences_constants.h"
|
| -#include "chrome/installer/util/shell_util.h"
|
| #include "chrome/installer/util/util_constants.h"
|
| #include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/notification_service.h"
|
| -#include "content/public/browser/user_metrics.h"
|
| #include "google_update/google_update_idl.h"
|
| -#include "grit/chromium_strings.h"
|
| -#include "grit/generated_resources.h"
|
| #include "grit/locale_settings.h"
|
| -#include "grit/theme_resources.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/base/layout.h"
|
| -#include "ui/base/ui_base_switches.h"
|
| #include "ui/base/win/shell.h"
|
|
|
| namespace {
|
| @@ -172,226 +147,6 @@ bool CreateEULASentinel() {
|
| file_util::WriteFile(eula_sentinel, "", 0) != -1);
|
| }
|
|
|
| -// This class is used by first_run::ImportSettings to determine when the import
|
| -// process has ended and what was the result of the operation as reported by
|
| -// the process exit code. This class executes in the context of the main chrome
|
| -// process.
|
| -class ImportProcessRunner : public base::win::ObjectWatcher::Delegate {
|
| - public:
|
| - // The constructor takes the importer process to watch and then it does a
|
| - // message loop blocking wait until the process ends. This object now owns
|
| - // the import_process handle.
|
| - explicit ImportProcessRunner(base::ProcessHandle import_process)
|
| - : import_process_(import_process),
|
| - exit_code_(content::RESULT_CODE_NORMAL_EXIT) {
|
| - watcher_.StartWatching(import_process, this);
|
| - MessageLoop::current()->Run();
|
| - }
|
| - virtual ~ImportProcessRunner() {
|
| - ::CloseHandle(import_process_);
|
| - }
|
| - // Returns the child process exit code. There are 2 expected values:
|
| - // NORMAL_EXIT, or IMPORTER_HUNG.
|
| - int exit_code() const { return exit_code_; }
|
| -
|
| - // The child process has terminated. Find the exit code and quit the loop.
|
| - virtual void OnObjectSignaled(HANDLE object) OVERRIDE {
|
| - DCHECK(object == import_process_);
|
| - if (!::GetExitCodeProcess(import_process_, &exit_code_)) {
|
| - NOTREACHED();
|
| - }
|
| - MessageLoop::current()->Quit();
|
| - }
|
| -
|
| - private:
|
| - base::win::ObjectWatcher watcher_;
|
| - base::ProcessHandle import_process_;
|
| - DWORD exit_code_;
|
| -};
|
| -
|
| -// Check every 3 seconds if the importer UI has hung.
|
| -const int kPollHangFrequency = 3000;
|
| -
|
| -// This class specializes on finding hung 'owned' windows. Unfortunately, the
|
| -// HungWindowDetector class cannot be used here because it assumes child
|
| -// windows and not owned top-level windows.
|
| -// This code is executed in the context of the main browser process and will
|
| -// terminate the importer process if it is hung.
|
| -class HungImporterMonitor : public WorkerThreadTicker::Callback {
|
| - public:
|
| - // The ctor takes the owner popup window and the process handle of the
|
| - // process to kill in case the popup or its owned active popup become
|
| - // unresponsive.
|
| - HungImporterMonitor(HWND owner_window, base::ProcessHandle import_process)
|
| - : owner_window_(owner_window),
|
| - import_process_(import_process),
|
| - ticker_(kPollHangFrequency) {
|
| - ticker_.RegisterTickHandler(this);
|
| - ticker_.Start();
|
| - }
|
| - virtual ~HungImporterMonitor() {
|
| - ticker_.Stop();
|
| - ticker_.UnregisterTickHandler(this);
|
| - }
|
| -
|
| - private:
|
| - virtual void OnTick() OVERRIDE {
|
| - if (!import_process_)
|
| - return;
|
| - // We find the top active popup that we own, this will be either the
|
| - // owner_window_ itself or the dialog window of the other process. In
|
| - // both cases it is worth hung testing because both windows share the
|
| - // same message queue and at some point the other window could be gone
|
| - // while the other process still not pumping messages.
|
| - HWND active_window = ::GetLastActivePopup(owner_window_);
|
| - if (::IsHungAppWindow(active_window) || ::IsHungAppWindow(owner_window_)) {
|
| - ::TerminateProcess(import_process_, chrome::RESULT_CODE_IMPORTER_HUNG);
|
| - import_process_ = NULL;
|
| - }
|
| - }
|
| -
|
| - HWND owner_window_;
|
| - base::ProcessHandle import_process_;
|
| - WorkerThreadTicker ticker_;
|
| - DISALLOW_COPY_AND_ASSIGN(HungImporterMonitor);
|
| -};
|
| -
|
| -std::string EncodeImportParams(int importer_type,
|
| - int options,
|
| - bool skip_first_run_ui) {
|
| - return base::StringPrintf("%d@%d@%d", importer_type, options,
|
| - skip_first_run_ui ? 1 : 0);
|
| -}
|
| -
|
| -bool DecodeImportParams(const std::string& encoded,
|
| - int* importer_type,
|
| - int* options,
|
| - bool* skip_first_run_ui) {
|
| - std::vector<std::string> parts;
|
| - base::SplitString(encoded, '@', &parts);
|
| - int skip_first_run_ui_int;
|
| - if ((parts.size() != 3) || !base::StringToInt(parts[0], importer_type) ||
|
| - !base::StringToInt(parts[1], options) ||
|
| - !base::StringToInt(parts[2], &skip_first_run_ui_int))
|
| - return false;
|
| - *skip_first_run_ui = !!skip_first_run_ui_int;
|
| - return true;
|
| -}
|
| -
|
| -#if !defined(USE_AURA)
|
| -// Imports browser items in this process. The browser and the items to
|
| -// import are encoded in the command line.
|
| -int ImportFromBrowser(Profile* profile,
|
| - const CommandLine& cmdline) {
|
| - std::string import_info = cmdline.GetSwitchValueASCII(switches::kImport);
|
| - if (import_info.empty()) {
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| - int importer_type = 0;
|
| - int items_to_import = 0;
|
| - bool skip_first_run_ui = false;
|
| - if (!DecodeImportParams(import_info, &importer_type, &items_to_import,
|
| - &skip_first_run_ui)) {
|
| - NOTREACHED();
|
| - return false;
|
| - }
|
| -
|
| - // Deletes itself.
|
| - ImporterHost* importer_host = new ImporterHost;
|
| -
|
| - scoped_refptr<ImporterList> importer_list(new ImporterList(NULL));
|
| - importer_list->DetectSourceProfilesHack();
|
| -
|
| - // If |skip_first_run_ui|, we run in headless mode. This means that if
|
| - // there is user action required the import is automatically canceled.
|
| - if (skip_first_run_ui)
|
| - importer_host->set_headless();
|
| -
|
| - first_run::internal::ImportEndedObserver observer;
|
| - importer_host->SetObserver(&observer);
|
| - importer_host->StartImportSettings(
|
| - importer_list->GetSourceProfileForImporterType(importer_type), profile,
|
| - static_cast<uint16>(items_to_import), new ProfileWriter(profile));
|
| - // If the import process has not errored out, block on it.
|
| - if (!observer.ended()) {
|
| - observer.set_should_quit_message_loop();
|
| - MessageLoop::current()->Run();
|
| - }
|
| - // TODO(gab): This method will be go away as part of http://crbug.com/219419/,
|
| - // so it is fine to hardcode |RESULT_CODE_NORMAL_EXIT| here for now.
|
| - return content::RESULT_CODE_NORMAL_EXIT;
|
| -}
|
| -#endif // !defined(USE_AURA)
|
| -
|
| -bool ImportSettingsWin(Profile* profile,
|
| - int importer_type,
|
| - int items_to_import,
|
| - const base::FilePath& import_bookmarks_path,
|
| - bool skip_first_run_ui) {
|
| - if (!items_to_import && import_bookmarks_path.empty()) {
|
| - return true;
|
| - }
|
| -
|
| - const CommandLine& cmdline = *CommandLine::ForCurrentProcess();
|
| - base::FilePath chrome_exe(cmdline.GetProgram());
|
| - // |chrome_exe| cannot be a relative path as chrome.exe already changed its
|
| - // CWD in LoadChromeWithDirectory(), making the relative path used on the
|
| - // command-line invalid. The base name is sufficient given chrome.exe is in
|
| - // the CWD.
|
| - if (!chrome_exe.IsAbsolute())
|
| - chrome_exe = chrome_exe.BaseName();
|
| - CommandLine import_cmd(chrome_exe);
|
| -
|
| - const char* kSwitchNames[] = {
|
| - switches::kUserDataDir,
|
| - switches::kChromeFrame,
|
| - switches::kCountry,
|
| - };
|
| - import_cmd.CopySwitchesFrom(cmdline, kSwitchNames, arraysize(kSwitchNames));
|
| -
|
| - // Allow tests to introduce additional switches.
|
| - import_cmd.AppendArguments(first_run::GetExtraArgumentsForImportProcess(),
|
| - false);
|
| -
|
| - // Since ImportSettings is called before the local state is stored on disk
|
| - // we pass the language as an argument. GetApplicationLocale checks the
|
| - // current command line as fallback.
|
| - import_cmd.AppendSwitchASCII(switches::kLang,
|
| - g_browser_process->GetApplicationLocale());
|
| -
|
| - if (items_to_import) {
|
| - import_cmd.AppendSwitchASCII(switches::kImport,
|
| - EncodeImportParams(importer_type, items_to_import, skip_first_run_ui));
|
| - }
|
| -
|
| - if (!import_bookmarks_path.empty()) {
|
| - import_cmd.AppendSwitchPath(switches::kImportFromFile,
|
| - import_bookmarks_path);
|
| - }
|
| -
|
| - // The importer doesn't need to do any background networking tasks so disable
|
| - // them.
|
| - import_cmd.CommandLine::AppendSwitch(switches::kDisableBackgroundNetworking);
|
| -
|
| - // Time to launch the process that is going to do the import.
|
| - base::ProcessHandle import_process;
|
| - if (!base::LaunchProcess(import_cmd, base::LaunchOptions(), &import_process))
|
| - return false;
|
| -
|
| - // We block inside the import_runner ctor, pumping messages until the
|
| - // importer process ends. This can happen either by completing the import
|
| - // or by hang_monitor killing it.
|
| - ImportProcessRunner import_runner(import_process);
|
| -
|
| - // Import process finished. Reload the prefs, because importer may set
|
| - // the pref value.
|
| - if (profile)
|
| - profile->GetPrefs()->ReloadPersistentPrefs();
|
| -
|
| - return (import_runner.exit_code() == content::RESULT_CODE_NORMAL_EXIT);
|
| -}
|
| -
|
| } // namespace
|
|
|
| namespace first_run {
|
| @@ -415,59 +170,10 @@ void DoPostImportPlatformSpecificTasks(Profile* /* profile */) {
|
| }
|
| }
|
|
|
| -bool ImportSettings(Profile* profile,
|
| - ImporterHost* importer_host,
|
| - scoped_refptr<ImporterList> importer_list,
|
| - int items_to_import) {
|
| - return ImportSettingsWin(
|
| - profile,
|
| - importer_list->GetSourceProfileAt(0).importer_type,
|
| - items_to_import,
|
| - base::FilePath(),
|
| - false);
|
| -}
|
| -
|
| bool GetFirstRunSentinelFilePath(base::FilePath* path) {
|
| return GetSentinelFilePath(chrome::kFirstRunSentinel, path);
|
| }
|
|
|
| -void SetImportPreferencesAndLaunchImport(
|
| - MasterPrefs* out_prefs,
|
| - installer::MasterPreferences* install_prefs) {
|
| - std::string import_bookmarks_path;
|
| - install_prefs->GetString(
|
| - installer::master_preferences::kDistroImportBookmarksFromFilePref,
|
| - &import_bookmarks_path);
|
| -
|
| - if (!IsOrganicFirstRun()) {
|
| - // If search engines aren't explicitly imported, don't import.
|
| - if (!(out_prefs->do_import_items & importer::SEARCH_ENGINES)) {
|
| - out_prefs->dont_import_items |= importer::SEARCH_ENGINES;
|
| - }
|
| - // If home page isn't explicitly imported, don't import.
|
| - if (!(out_prefs->do_import_items & importer::HOME_PAGE)) {
|
| - out_prefs->dont_import_items |= importer::HOME_PAGE;
|
| - }
|
| - // If history isn't explicitly forbidden, do import.
|
| - if (!(out_prefs->dont_import_items & importer::HISTORY)) {
|
| - out_prefs->do_import_items |= importer::HISTORY;
|
| - }
|
| - }
|
| -
|
| - if (out_prefs->do_import_items || !import_bookmarks_path.empty()) {
|
| - // There is something to import from the default browser. This launches
|
| - // the importer process and blocks until done or until it fails.
|
| - scoped_refptr<ImporterList> importer_list(new ImporterList(NULL));
|
| - importer_list->DetectSourceProfilesHack();
|
| - if (!ImportSettingsWin(
|
| - NULL, importer_list->GetSourceProfileAt(0).importer_type,
|
| - out_prefs->do_import_items, base::FilePath::FromWStringHack(UTF8ToWide(
|
| - import_bookmarks_path)), true)) {
|
| - LOG(WARNING) << "silent import failed";
|
| - }
|
| - }
|
| -}
|
| -
|
| bool ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs) {
|
| if (IsEULANotAccepted(install_prefs)) {
|
| // Show the post-installation EULA. This is done by setup.exe and the
|
| @@ -509,17 +215,3 @@ base::FilePath MasterPrefsPath() {
|
|
|
| } // namespace internal
|
| } // namespace first_run
|
| -
|
| -namespace first_run {
|
| -
|
| -int ImportNow(Profile* profile, const CommandLine& cmdline) {
|
| - int return_code = internal::ImportBookmarkFromFileIfNeeded(profile, cmdline);
|
| -#if !defined(USE_AURA)
|
| - if (cmdline.HasSwitch(switches::kImport)) {
|
| - return_code = ImportFromBrowser(profile, cmdline);
|
| - }
|
| -#endif
|
| - return return_code;
|
| -}
|
| -
|
| -} // namespace first_run
|
|
|