1 // Copyright (c) 2013 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/user_data_dir_extractor_win.h" 6 7 #include "base/command_line.h" 8 #include "base/file_util.h" 9 #include "base/logging.h" 10 #include "base/path_service.h" 11 #include "base/process/launch.h" 12 #include "chrome/browser/ui/user_data_dir_dialog.h" 13 #include "chrome/browser/user_data_dir_extractor.h" 14 #include "chrome/common/chrome_paths.h" 15 #include "chrome/common/chrome_switches.h" 16 #include "content/public/common/main_function_params.h" 17 #include "ui/base/l10n/l10n_util.h" 18 #include "ui/base/resource/resource_bundle.h" 19 20 namespace chrome { 21 22 namespace { 23 24 GetUserDataDirCallback* custom_get_user_data_dir_callback = NULL; 25 26 const char kUserDataDirDialogFallbackLocale[] = "en-US"; 27 28 } // namespace 29 30 void InstallCustomGetUserDataDirCallbackForTest( 31 GetUserDataDirCallback* callback) { 32 custom_get_user_data_dir_callback = callback; 33 } 34 35 base::FilePath GetUserDataDir(const content::MainFunctionParams& parameters) { 36 // If tests have installed a custom callback for GetUserDataDir(), invoke the 37 // callback and return. 38 if (custom_get_user_data_dir_callback) 39 return custom_get_user_data_dir_callback->Run(); 40 41 base::FilePath user_data_dir; 42 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 43 44 // On Windows, if we fail to get the user data dir, bring up a dialog to 45 // prompt the user to pick a different directory, and restart chrome with 46 // the new dir. 47 // http://code.google.com/p/chromium/issues/detail?id=11510 48 if (!base::PathExists(user_data_dir)) { 49 #if defined(USE_AURA) 50 // TODO(beng): 51 NOTIMPLEMENTED(); 52 #else 53 // Make sure ResourceBundle is initialized. The user data dialog needs to 54 // access string resources. See http://crbug.com/230432 55 if (!ResourceBundle::HasSharedInstance()) { 56 std::string locale = l10n_util::GetApplicationLocale(std::string()); 57 DCHECK(!locale.empty()); 58 if (locale.empty()) 59 locale = kUserDataDirDialogFallbackLocale; 60 ResourceBundle::InitSharedInstanceWithLocale(locale, NULL); 61 } 62 63 base::FilePath new_user_data_dir = 64 chrome::ShowUserDataDirDialog(user_data_dir); 65 66 if (!new_user_data_dir.empty()) { 67 // Because of the way CommandLine parses, it's sufficient to append a new 68 // --user-data-dir switch. The last flag of the same name wins. 69 // TODO(tc): It would be nice to remove the flag we don't want, but that 70 // sounds risky if we parse differently than CommandLineToArgvW. 71 CommandLine new_command_line = parameters.command_line; 72 new_command_line.AppendSwitchPath(switches::kUserDataDir, 73 new_user_data_dir); 74 base::LaunchProcess(new_command_line, base::LaunchOptions(), NULL); 75 } 76 #endif 77 NOTREACHED() << "Failed to get user data directory!"; 78 } 79 return user_data_dir; 80 } 81 82 } // namespace chrome 83