1 // Copyright 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/sxs_linux.h" 6 7 #include <vector> 8 9 #include "base/logging.h" 10 #include "base/file_util.h" 11 #include "base/files/file_path.h" 12 #include "base/files/important_file_writer.h" 13 #include "base/path_service.h" 14 #include "base/strings/string_split.h" 15 #include "base/strings/string_util.h" 16 #include "chrome/common/chrome_paths.h" 17 #include "chrome/common/chrome_version_info.h" 18 #include "content/public/browser/browser_thread.h" 19 20 namespace { 21 22 bool DoAddChannelMarkToUserDataDir(const base::FilePath& user_data_dir) { 23 std::string product_channel_name; 24 chrome::VersionInfo::Channel product_channel( 25 chrome::VersionInfo::GetChannel()); 26 switch (product_channel) { 27 case chrome::VersionInfo::CHANNEL_UNKNOWN: { 28 // Add the channel mark even for Chromium builds (which do not have 29 // channel) to better handle possibility of users using Chromium builds 30 // with their Google Chrome profiles. Include version string modifier 31 // as additional piece of information for debugging (it can't make 32 // a meaningful difference for the code since unknown does not match any 33 // real channel name). 34 std::string version_string_modifier( 35 chrome::VersionInfo::GetVersionStringModifier()); 36 product_channel_name = "unknown (" + version_string_modifier + ")"; 37 break; 38 } 39 case chrome::VersionInfo::CHANNEL_CANARY: 40 product_channel_name = "canary"; 41 break; 42 case chrome::VersionInfo::CHANNEL_DEV: 43 product_channel_name = "dev"; 44 break; 45 case chrome::VersionInfo::CHANNEL_BETA: 46 product_channel_name = "beta"; 47 break; 48 case chrome::VersionInfo::CHANNEL_STABLE: 49 product_channel_name = "stable"; 50 break; 51 // Rely on -Wswitch compiler warning to detect unhandled enum values. 52 } 53 54 base::FilePath channels_path(user_data_dir.AppendASCII("Channels")); 55 std::vector<std::string> user_data_dir_channels; 56 57 // Note: failure to read the channels file is not fatal. It's possible 58 // and legitimate that it doesn't exist, e.g. for new profile or for profile 59 // existing before channel marks have been introduced. 60 std::string channels_contents; 61 if (file_util::ReadFileToString(channels_path, &channels_contents)) 62 base::SplitString(channels_contents, '\n', &user_data_dir_channels); 63 64 if (std::find(user_data_dir_channels.begin(), 65 user_data_dir_channels.end(), 66 product_channel_name) != user_data_dir_channels.end()) { 67 // No need to do further disk writes if our channel mark is already present. 68 return true; 69 } 70 71 user_data_dir_channels.push_back(product_channel_name); 72 return base::ImportantFileWriter::WriteFileAtomically( 73 channels_path, 74 JoinString(user_data_dir_channels, "\n")); 75 } 76 77 } // namespace 78 79 namespace sxs_linux { 80 81 void AddChannelMarkToUserDataDir() { 82 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 83 base::FilePath user_data_dir; 84 if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { 85 LOG(ERROR) << "Failed to get user data dir path. The profile will not be " 86 << "automatically migrated for updated Linux packages."; 87 return; 88 } 89 90 if (!DoAddChannelMarkToUserDataDir(user_data_dir)) { 91 LOG(ERROR) << "Failed to add channel mark to the user data dir (" 92 << user_data_dir.value() << "). This profile will not be " 93 << "automatically migrated for updated Linux packages."; 94 } 95 } 96 97 } // namespace sxs_linux 98