OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/first_run/first_run.h" | 5 #include "chrome/browser/first_run/first_run.h" |
6 | 6 |
7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 // TODO(port): move more code in back from the first_run_win.cc module. | 9 // TODO(port): move more code in back from the first_run_win.cc module. |
10 | 10 |
11 #if defined(OS_WIN) | 11 #if defined(OS_WIN) |
| 12 #include "chrome/installer/util/google_update_settings.h" |
12 #include "chrome/installer/util/install_util.h" | 13 #include "chrome/installer/util/install_util.h" |
13 #endif | 14 #endif |
14 | 15 |
15 #include "base/command_line.h" | 16 #include "base/command_line.h" |
16 #include "base/file_util.h" | 17 #include "base/file_util.h" |
17 #include "base/path_service.h" | 18 #include "base/path_service.h" |
| 19 #include "base/utf_string_conversions.h" |
18 #include "chrome/browser/importer/importer.h" | 20 #include "chrome/browser/importer/importer.h" |
19 #include "chrome/browser/pref_service.h" | 21 #include "chrome/browser/pref_service.h" |
| 22 #include "chrome/browser/profile_manager.h" |
| 23 #include "chrome/browser/shell_integration.h" |
20 #include "chrome/common/chrome_paths.h" | 24 #include "chrome/common/chrome_paths.h" |
21 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/common/pref_names.h" | 26 #include "chrome/common/pref_names.h" |
| 27 #include "chrome/installer/util/master_preferences.h" |
| 28 #include "chrome/installer/util/util_constants.h" |
23 | 29 |
24 namespace { | 30 namespace { |
25 | 31 |
26 // The kSentinelFile file absence will tell us it is a first run. | 32 // The kSentinelFile file absence will tell us it is a first run. |
27 const char kSentinelFile[] = "First Run"; | 33 const char kSentinelFile[] = "First Run"; |
28 | 34 |
| 35 FilePath GetDefaultPrefFilePath(bool create_profile_dir, |
| 36 const FilePath& user_data_dir) { |
| 37 FilePath default_pref_dir = |
| 38 ProfileManager::GetDefaultProfileDir(user_data_dir); |
| 39 if (create_profile_dir) { |
| 40 if (!file_util::PathExists(default_pref_dir)) { |
| 41 if (!file_util::CreateDirectory(default_pref_dir)) |
| 42 return FilePath(); |
| 43 } |
| 44 } |
| 45 return ProfileManager::GetProfilePrefsPath(default_pref_dir); |
| 46 } |
| 47 |
29 } // namespace | 48 } // namespace |
30 | 49 |
31 FirstRun::FirstRunState FirstRun::first_run_ = FIRST_RUN_UNKNOWN; | 50 FirstRun::FirstRunState FirstRun::first_run_ = FIRST_RUN_UNKNOWN; |
32 | 51 |
33 // TODO(port): Import switches need to be ported to both Mac and Linux. Not all | 52 // TODO(port): Import switches need to be ported to both Mac and Linux. Not all |
34 // import switches here are implemented for Linux. None are implemented for Mac | 53 // import switches here are implemented for Linux. None are implemented for Mac |
35 // (as this function will not be called on Mac). | 54 // (as this function will not be called on Mac). |
36 int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) { | 55 int FirstRun::ImportNow(Profile* profile, const CommandLine& cmdline) { |
37 int return_code = true; | 56 int return_code = true; |
38 if (cmdline.HasSwitch(switches::kImportFromFile)) { | 57 if (cmdline.HasSwitch(switches::kImportFromFile)) { |
39 // Silently import preset bookmarks from file. | 58 // Silently import preset bookmarks from file. |
40 // This is an OEM scenario. | 59 // This is an OEM scenario. |
41 return_code = ImportFromFile(profile, cmdline); | 60 return_code = ImportFromFile(profile, cmdline); |
42 } | 61 } |
43 if (cmdline.HasSwitch(switches::kImport)) { | 62 if (cmdline.HasSwitch(switches::kImport)) { |
44 #if defined(OS_WIN) | 63 #if defined(OS_WIN) |
45 return_code = ImportFromBrowser(profile, cmdline); | 64 return_code = ImportFromBrowser(profile, cmdline); |
46 #else | 65 #else |
47 NOTIMPLEMENTED(); | 66 NOTIMPLEMENTED(); |
48 #endif | 67 #endif |
49 } | 68 } |
50 return return_code; | 69 return return_code; |
51 } | 70 } |
52 | 71 |
53 // static | 72 // static |
| 73 bool FirstRun::ProcessMasterPreferences(const FilePath& user_data_dir, |
| 74 MasterPrefs* out_prefs) { |
| 75 DCHECK(!user_data_dir.empty()); |
| 76 |
| 77 // The standard location of the master prefs is next to the chrome binary. |
| 78 FilePath master_prefs; |
| 79 if (!PathService::Get(base::DIR_EXE, &master_prefs)) |
| 80 return true; |
| 81 master_prefs = master_prefs.AppendASCII(installer_util::kDefaultMasterPrefs); |
| 82 |
| 83 scoped_ptr<DictionaryValue> prefs( |
| 84 installer_util::ParseDistributionPreferences(master_prefs)); |
| 85 if (!prefs.get()) |
| 86 return true; |
| 87 |
| 88 out_prefs->new_tabs = installer_util::GetFirstRunTabs(prefs.get()); |
| 89 |
| 90 bool value = false; |
| 91 |
| 92 #if defined(OS_WIN) |
| 93 // RLZ is currently a Windows-only phenomenon. When it comes to the Mac/ |
| 94 // Linux, enable it here. |
| 95 if (!installer_util::GetDistroIntegerPreference(prefs.get(), |
| 96 installer_util::master_preferences::kDistroPingDelay, |
| 97 &out_prefs->ping_delay)) { |
| 98 // 90 seconds is the default that we want to use in case master |
| 99 // preferences is missing, corrupt or ping_delay is missing. |
| 100 out_prefs->ping_delay = 90; |
| 101 } |
| 102 |
| 103 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 104 installer_util::master_preferences::kRequireEula, &value) && value) { |
| 105 // Show the post-installation EULA. This is done by setup.exe and the |
| 106 // result determines if we continue or not. We wait here until the user |
| 107 // dismisses the dialog. |
| 108 |
| 109 // The actual eula text is in a resource in chrome. We extract it to |
| 110 // a text file so setup.exe can use it as an inner frame. |
| 111 FilePath inner_html; |
| 112 if (WriteEULAtoTempFile(&inner_html)) { |
| 113 int retcode = 0; |
| 114 if (!LaunchSetupWithParam(installer_util::switches::kShowEula, |
| 115 inner_html.ToWStringHack(), &retcode) || |
| 116 (retcode == installer_util::EULA_REJECTED)) { |
| 117 LOG(WARNING) << "EULA rejected. Fast exit."; |
| 118 ::ExitProcess(1); |
| 119 } |
| 120 if (retcode == installer_util::EULA_ACCEPTED) { |
| 121 LOG(INFO) << "EULA : no collection"; |
| 122 GoogleUpdateSettings::SetCollectStatsConsent(false); |
| 123 } else if (retcode == installer_util::EULA_ACCEPTED_OPT_IN) { |
| 124 LOG(INFO) << "EULA : collection consent"; |
| 125 GoogleUpdateSettings::SetCollectStatsConsent(true); |
| 126 } |
| 127 } |
| 128 } |
| 129 #endif |
| 130 |
| 131 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 132 installer_util::master_preferences::kAltFirstRunBubble, &value) && value) |
| 133 FirstRun::SetOEMFirstRunBubblePref(); |
| 134 |
| 135 FilePath user_prefs = GetDefaultPrefFilePath(true, user_data_dir); |
| 136 if (user_prefs.empty()) |
| 137 return true; |
| 138 |
| 139 // The master prefs are regular prefs so we can just copy the file |
| 140 // to the default place and they just work. |
| 141 if (!file_util::CopyFile(master_prefs, user_prefs)) |
| 142 return true; |
| 143 |
| 144 #if defined(OS_WIN) |
| 145 DictionaryValue* extensions = 0; |
| 146 if (installer_util::HasExtensionsBlock(prefs.get(), &extensions)) { |
| 147 LOG(INFO) << "Extensions block found in master preferences"; |
| 148 DoDelayedInstallExtensions(); |
| 149 } |
| 150 #endif |
| 151 |
| 152 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 153 installer_util::master_preferences::kDistroImportSearchPref, &value)) { |
| 154 if (value) { |
| 155 out_prefs->do_import_items |= importer::SEARCH_ENGINES; |
| 156 } else { |
| 157 out_prefs->dont_import_items |= importer::SEARCH_ENGINES; |
| 158 } |
| 159 } |
| 160 |
| 161 // Check to see if search engine logos should be randomized. |
| 162 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 163 installer_util::master_preferences::kSearchEngineExperimentRandomizePref, |
| 164 &value) && value) |
| 165 out_prefs->randomize_search_engine_experiment = true; |
| 166 |
| 167 // If we're suppressing the first-run bubble, set that preference now. |
| 168 // Otherwise, wait until the user has completed first run to set it, so the |
| 169 // user is guaranteed to see the bubble iff he or she has completed the first |
| 170 // run process. |
| 171 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 172 installer_util::master_preferences::kDistroSuppressFirstRunBubble, |
| 173 &value) && value) |
| 174 FirstRun::SetShowFirstRunBubblePref(false); |
| 175 |
| 176 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 177 installer_util::master_preferences::kDistroImportHistoryPref, &value)) { |
| 178 if (value) { |
| 179 out_prefs->do_import_items |= importer::HISTORY; |
| 180 } else { |
| 181 out_prefs->dont_import_items |= importer::HISTORY; |
| 182 } |
| 183 } |
| 184 |
| 185 std::string not_used; |
| 186 out_prefs->homepage_defined = prefs->GetString(prefs::kHomePage, ¬_used); |
| 187 |
| 188 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 189 installer_util::master_preferences::kDistroImportHomePagePref, &value)) { |
| 190 if (value) { |
| 191 out_prefs->do_import_items |= importer::HOME_PAGE; |
| 192 } else { |
| 193 out_prefs->dont_import_items |= importer::HOME_PAGE; |
| 194 } |
| 195 } |
| 196 |
| 197 // Bookmarks are never imported unless specifically turned on. |
| 198 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 199 installer_util::master_preferences::kDistroImportBookmarksPref, &value) |
| 200 && value) { |
| 201 out_prefs->do_import_items |= importer::FAVORITES; |
| 202 } |
| 203 |
| 204 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 205 installer_util::master_preferences::kMakeChromeDefaultForUser, &value) && |
| 206 value) |
| 207 ShellIntegration::SetAsDefaultBrowser(); |
| 208 |
| 209 // TODO(mirandac): Refactor skip-first-run-ui process into regular first run |
| 210 // import process. http://crbug.com/49647 |
| 211 // Note we are skipping all other master preferences if skip-first-run-ui |
| 212 // is *not* specified. (That is, we continue only if skipping first run ui.) |
| 213 if (!installer_util::GetDistroBooleanPreference(prefs.get(), |
| 214 installer_util::master_preferences::kDistroSkipFirstRunPref, &value) || |
| 215 !value) |
| 216 return true; |
| 217 |
| 218 #if !defined(OS_WIN) |
| 219 // From here on we won't show first run so we need to do the work to show the |
| 220 // bubble anyway, unless it's already been explicitly suppressed. |
| 221 FirstRun::SetShowFirstRunBubblePref(true); |
| 222 #endif |
| 223 |
| 224 // We need to be able to create the first run sentinel or else we cannot |
| 225 // proceed because ImportSettings will launch the importer process which |
| 226 // would end up here if the sentinel is not present. |
| 227 if (!FirstRun::CreateSentinel()) |
| 228 return false; |
| 229 |
| 230 if (installer_util::GetDistroBooleanPreference(prefs.get(), |
| 231 installer_util::master_preferences::kDistroShowWelcomePage, &value) && |
| 232 value) |
| 233 FirstRun::SetShowWelcomePagePref(); |
| 234 |
| 235 std::string import_bookmarks_path; |
| 236 installer_util::GetDistroStringPreference(prefs.get(), |
| 237 installer_util::master_preferences::kDistroImportBookmarksFromFilePref, |
| 238 &import_bookmarks_path); |
| 239 |
| 240 #if defined(OS_WIN) |
| 241 std::wstring brand; |
| 242 GoogleUpdateSettings::GetBrand(&brand); |
| 243 // This should generally be true, as skip_first_run_ui is a setting used for |
| 244 // non-organic builds. |
| 245 if (!GoogleUpdateSettings::IsOrganic(brand)) { |
| 246 // If search engines aren't explicitly imported, don't import. |
| 247 if (!(out_prefs->do_import_items & importer::SEARCH_ENGINES)) { |
| 248 out_prefs->dont_import_items |= importer::SEARCH_ENGINES; |
| 249 } |
| 250 // If home page isn't explicitly imported, don't import. |
| 251 if (!(out_prefs->do_import_items & importer::HOME_PAGE)) { |
| 252 out_prefs->dont_import_items |= importer::HOME_PAGE; |
| 253 } |
| 254 // If history isn't explicitly forbidden, do import. |
| 255 if (!(out_prefs->dont_import_items & importer::HISTORY)) { |
| 256 out_prefs->do_import_items |= importer::HISTORY; |
| 257 } |
| 258 } |
| 259 |
| 260 if (out_prefs->do_import_items || !import_bookmarks_path.empty()) { |
| 261 // There is something to import from the default browser. This launches |
| 262 // the importer process and blocks until done or until it fails. |
| 263 scoped_refptr<ImporterHost> importer_host = new ImporterHost(); |
| 264 if (!FirstRun::ImportSettings(NULL, |
| 265 importer_host->GetSourceProfileInfoAt(0).browser_type, |
| 266 out_prefs->do_import_items, |
| 267 FilePath::FromWStringHack(UTF8ToWide(import_bookmarks_path)), |
| 268 true, NULL)) { |
| 269 LOG(WARNING) << "silent import failed"; |
| 270 } |
| 271 } |
| 272 #else |
| 273 if (!import_bookmarks_path.empty()) { |
| 274 // There are bookmarks to import from a file. |
| 275 FilePath path = FilePath::FromWStringHack(UTF8ToWide( |
| 276 import_bookmarks_path)); |
| 277 if (!FirstRun::ImportBookmarks(path)) { |
| 278 LOG(WARNING) << "silent bookmark import failed"; |
| 279 } |
| 280 } |
| 281 #endif |
| 282 |
| 283 return false; |
| 284 } |
| 285 |
| 286 // static |
54 bool FirstRun::IsChromeFirstRun() { | 287 bool FirstRun::IsChromeFirstRun() { |
55 if (first_run_ != FIRST_RUN_UNKNOWN) | 288 if (first_run_ != FIRST_RUN_UNKNOWN) |
56 return first_run_ == FIRST_RUN_TRUE; | 289 return first_run_ == FIRST_RUN_TRUE; |
57 | 290 |
58 FilePath first_run_sentinel; | 291 FilePath first_run_sentinel; |
59 if (!GetFirstRunSentinelFilePath(&first_run_sentinel) || | 292 if (!GetFirstRunSentinelFilePath(&first_run_sentinel) || |
60 file_util::PathExists(first_run_sentinel)) { | 293 file_util::PathExists(first_run_sentinel)) { |
61 first_run_ = FIRST_RUN_FALSE; | 294 first_run_ = FIRST_RUN_FALSE; |
62 return false; | 295 return false; |
63 } | 296 } |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 void FirstRunImportObserver::RunLoop() { | 447 void FirstRunImportObserver::RunLoop() { |
215 loop_running_ = true; | 448 loop_running_ = true; |
216 MessageLoop::current()->Run(); | 449 MessageLoop::current()->Run(); |
217 } | 450 } |
218 | 451 |
219 void FirstRunImportObserver::Finish() { | 452 void FirstRunImportObserver::Finish() { |
220 if (loop_running_) | 453 if (loop_running_) |
221 MessageLoop::current()->Quit(); | 454 MessageLoop::current()->Quit(); |
222 } | 455 } |
223 | 456 |
OLD | NEW |