1 // Copyright (c) 2012 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/sync/glue/device_info.h" 6 7 #include "base/command_line.h" 8 #include "base/threading/sequenced_worker_pool.h" 9 #include "base/values.h" 10 #include "chrome/common/chrome_version_info.h" 11 #include "chrome/common/chrome_switches.h" 12 #include "content/public/browser/browser_thread.h" 13 #include "sync/util/get_session_name.h" 14 #include "ui/base/device_form_factor.h" 15 16 namespace browser_sync { 17 18 namespace { 19 20 #if defined(OS_ANDROID) 21 bool IsTabletUI() { 22 return ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET; 23 } 24 #endif 25 26 // Converts VersionInfo::Channel to string for user-agent string. 27 std::string ChannelToString(chrome::VersionInfo::Channel channel) { 28 switch (channel) { 29 case chrome::VersionInfo::CHANNEL_UNKNOWN: 30 return "unknown"; 31 case chrome::VersionInfo::CHANNEL_CANARY: 32 return "canary"; 33 case chrome::VersionInfo::CHANNEL_DEV: 34 return "dev"; 35 case chrome::VersionInfo::CHANNEL_BETA: 36 return "beta"; 37 case chrome::VersionInfo::CHANNEL_STABLE: 38 return "stable"; 39 default: 40 NOTREACHED(); 41 return "unknown"; 42 }; 43 } 44 45 } // namespace 46 47 DeviceInfo::DeviceInfo(const std::string& guid, 48 const std::string& client_name, 49 const std::string& chrome_version, 50 const std::string& sync_user_agent, 51 const sync_pb::SyncEnums::DeviceType device_type) 52 : guid_(guid), 53 client_name_(client_name), 54 chrome_version_(chrome_version), 55 sync_user_agent_(sync_user_agent), 56 device_type_(device_type) { 57 } 58 59 DeviceInfo::~DeviceInfo() { } 60 61 const std::string& DeviceInfo::guid() const { 62 return guid_; 63 } 64 65 const std::string& DeviceInfo::client_name() const { 66 return client_name_; 67 } 68 69 const std::string& DeviceInfo::chrome_version() const { 70 return chrome_version_; 71 } 72 73 const std::string& DeviceInfo::sync_user_agent() const { 74 return sync_user_agent_; 75 } 76 77 const std::string& DeviceInfo::public_id() const { 78 return public_id_; 79 } 80 81 sync_pb::SyncEnums::DeviceType DeviceInfo::device_type() const { 82 return device_type_; 83 } 84 85 std::string DeviceInfo::GetOSString() const { 86 switch (device_type_) { 87 case sync_pb::SyncEnums_DeviceType_TYPE_WIN: 88 return "win"; 89 case sync_pb::SyncEnums_DeviceType_TYPE_MAC: 90 return "mac"; 91 case sync_pb::SyncEnums_DeviceType_TYPE_LINUX: 92 return "linux"; 93 case sync_pb::SyncEnums_DeviceType_TYPE_CROS: 94 return "chrome_os"; 95 case sync_pb::SyncEnums_DeviceType_TYPE_PHONE: 96 case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: 97 // TODO(lipalani): crbug.com/170375. Add support for ios 98 // phones and tablets. 99 return "android"; 100 default: 101 return "unknown"; 102 } 103 } 104 105 std::string DeviceInfo::GetDeviceTypeString() const { 106 switch (device_type_) { 107 case sync_pb::SyncEnums_DeviceType_TYPE_WIN: 108 case sync_pb::SyncEnums_DeviceType_TYPE_MAC: 109 case sync_pb::SyncEnums_DeviceType_TYPE_LINUX: 110 case sync_pb::SyncEnums_DeviceType_TYPE_CROS: 111 return "desktop_or_laptop"; 112 case sync_pb::SyncEnums_DeviceType_TYPE_PHONE: 113 return "phone"; 114 case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: 115 return "tablet"; 116 default: 117 return "unknown"; 118 } 119 } 120 121 bool DeviceInfo::Equals(const DeviceInfo& other) const { 122 return this->guid() == other.guid() 123 && this->client_name() == other.client_name() 124 && this->chrome_version() == other.chrome_version() 125 && this->sync_user_agent() == other.sync_user_agent() 126 && this->device_type() == other.device_type(); 127 } 128 129 // static. 130 sync_pb::SyncEnums::DeviceType DeviceInfo::GetLocalDeviceType() { 131 #if defined(OS_CHROMEOS) 132 return sync_pb::SyncEnums_DeviceType_TYPE_CROS; 133 #elif defined(OS_LINUX) 134 return sync_pb::SyncEnums_DeviceType_TYPE_LINUX; 135 #elif defined(OS_MACOSX) 136 return sync_pb::SyncEnums_DeviceType_TYPE_MAC; 137 #elif defined(OS_WIN) 138 return sync_pb::SyncEnums_DeviceType_TYPE_WIN; 139 #elif defined(OS_ANDROID) 140 return IsTabletUI() ? 141 sync_pb::SyncEnums_DeviceType_TYPE_TABLET : 142 sync_pb::SyncEnums_DeviceType_TYPE_PHONE; 143 #else 144 return sync_pb::SyncEnums_DeviceType_TYPE_OTHER; 145 #endif 146 } 147 148 // static 149 std::string DeviceInfo::MakeUserAgentForSyncApi( 150 const chrome::VersionInfo& version_info) { 151 std::string user_agent; 152 user_agent = "Chrome "; 153 #if defined(OS_WIN) 154 user_agent += "WIN "; 155 #elif defined(OS_CHROMEOS) 156 user_agent += "CROS "; 157 #elif defined(OS_ANDROID) 158 if (IsTabletUI()) 159 user_agent += "ANDROID-TABLET "; 160 else 161 user_agent += "ANDROID-PHONE "; 162 #elif defined(OS_LINUX) 163 user_agent += "LINUX "; 164 #elif defined(OS_FREEBSD) 165 user_agent += "FREEBSD "; 166 #elif defined(OS_OPENBSD) 167 user_agent += "OPENBSD "; 168 #elif defined(OS_MACOSX) 169 user_agent += "MAC "; 170 #endif 171 if (!version_info.is_valid()) { 172 DLOG(ERROR) << "Unable to create chrome::VersionInfo object"; 173 return user_agent; 174 } 175 176 user_agent += version_info.Version(); 177 user_agent += " (" + version_info.LastChange() + ")"; 178 if (!version_info.IsOfficialBuild()) { 179 user_agent += "-devel"; 180 } else { 181 user_agent += " channel(" + 182 ChannelToString(version_info.GetChannel()) + ")"; 183 } 184 185 return user_agent; 186 } 187 188 base::DictionaryValue* DeviceInfo::ToValue() { 189 base::DictionaryValue* value = new base::DictionaryValue(); 190 value->SetString("name", client_name_); 191 value->SetString("id", public_id_); 192 value->SetString("os", GetOSString()); 193 value->SetString("type", GetDeviceTypeString()); 194 value->SetString("chromeVersion", chrome_version_); 195 return value; 196 } 197 198 void DeviceInfo::set_public_id(std::string id) { 199 public_id_ = id; 200 } 201 202 // static. 203 void DeviceInfo::CreateLocalDeviceInfo( 204 const std::string& guid, 205 base::Callback<void(const DeviceInfo& local_info)> callback) { 206 GetClientName( 207 base::Bind(&DeviceInfo::CreateLocalDeviceInfoContinuation, 208 guid, 209 callback)); 210 } 211 212 // static. 213 void DeviceInfo::GetClientName( 214 base::Callback<void(const std::string& client_name)> callback) { 215 syncer::GetSessionName( 216 content::BrowserThread::GetBlockingPool(), 217 base::Bind(&DeviceInfo::GetClientNameContinuation, 218 callback)); 219 } 220 221 void DeviceInfo::GetClientNameContinuation( 222 base::Callback<void(const std::string& local_info)> callback, 223 const std::string& session_name) { 224 callback.Run(session_name); 225 } 226 227 // static. 228 void DeviceInfo::CreateLocalDeviceInfoContinuation( 229 const std::string& guid, 230 base::Callback<void(const DeviceInfo& local_info)> callback, 231 const std::string& session_name) { 232 chrome::VersionInfo version_info; 233 234 DeviceInfo local_info( 235 guid, 236 session_name, 237 version_info.CreateVersionString(), 238 MakeUserAgentForSyncApi(version_info), 239 GetLocalDeviceType()); 240 241 callback.Run(local_info); 242 } 243 244 } // namespace browser_sync 245