device_id_fetcher.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// found in the LICENSE file. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/renderer_host/pepper/device_id_fetcher.h" 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/file_util.h" 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/prefs/pref_service.h" 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/pref_names.h" 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(OS_CHROMEOS) 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chromeos/cryptohome/cryptohome_library.h" 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h" 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/browser_context.h" 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/browser_ppapi_host.h" 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/render_process_host.h" 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "crypto/encryptor.h" 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "crypto/random.h" 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "crypto/sha2.h" 2306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#if defined(ENABLE_RLZ) 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "rlz/lib/machine_id.h" 255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif 265d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 2776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)using content::BrowserPpapiHost; 28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)using content::BrowserThread; 2906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)using content::RenderProcessHost; 3006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)namespace chrome { 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)namespace { 34e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const char kDRMIdentifierFile[] = "Pepper DRM ID.0"; 36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const uint32_t kSaltLength = 32; 38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 39197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid GetMachineIDAsync(const DeviceIDFetcher::IDCallback& callback) { 40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch std::string result; 41197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if defined(OS_WIN) && defined(ENABLE_RLZ) 42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch rlz_lib::GetMachineId(&result); 43197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#elif defined(OS_CHROMEOS) 44197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch result = chromeos::CryptohomeLibrary::Get()->GetSystemSalt(); 45197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (result.empty()) { 46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // cryptohome must not be running; re-request after a delay. 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const int64 kRequestSystemSaltDelayMs = 500; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 49323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) FROM_HERE, 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::Bind(&GetMachineIDAsync, callback), 51323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kRequestSystemSaltDelayMs)); 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Not implemented for other platforms. 5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) NOTREACHED(); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback.Run(result); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 61bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} // namespace 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DeviceIDFetcher::DeviceIDFetcher(int render_process_id) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : in_progress_(false), 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) render_process_id_(render_process_id) { 6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DeviceIDFetcher::~DeviceIDFetcher() { 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool DeviceIDFetcher::Start(const IDCallback& callback) { 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (in_progress_) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) in_progress_ = true; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback_ = callback; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BrowserThread::PostTask( 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BrowserThread::UI, FROM_HERE, 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::Bind(&DeviceIDFetcher::CheckPrefsOnUIThread, this)); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 8506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)} 8606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) 8706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)// static 8806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)void DeviceIDFetcher::RegisterProfilePrefs( 89bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) user_prefs::PrefRegistrySyncable* prefs) { 908abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) prefs->RegisterBooleanPref(prefs::kEnableDRM, 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) true, 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs->RegisterStringPref( 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs::kDRMSalt, 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) "", 96197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// static 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)base::FilePath DeviceIDFetcher::GetLegacyDeviceIDPath( 101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const base::FilePath& profile_path) { 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return profile_path.AppendASCII(kDRMIdentifierFile); 103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 104bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DeviceIDFetcher::CheckPrefsOnUIThread() { 1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 107d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 1088abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) Profile* profile = NULL; 10951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) RenderProcessHost* render_process_host = 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderProcessHost::FromID(render_process_id_); 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (render_process_host && render_process_host->GetBrowserContext()) { 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) profile = Profile::FromBrowserContext( 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) render_process_host->GetBrowserContext()); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!profile || 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) profile->IsOffTheRecord() || 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) !profile->GetPrefs()->GetBoolean(prefs::kEnableDRM)) { 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RunCallbackOnIOThread(std::string()); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 123bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Check if the salt pref is set. If it isn't, set it. 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::string salt = profile->GetPrefs()->GetString(prefs::kDRMSalt); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (salt.empty()) { 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint8_t salt_bytes[kSaltLength]; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) crypto::RandBytes(salt_bytes, arraysize(salt_bytes)); 128f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // Since it will be stored in a string pref, convert it to hex. 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) salt = base::HexEncode(salt_bytes, arraysize(salt_bytes)); 130f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) profile->GetPrefs()->SetString(prefs::kDRMSalt, salt); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(OS_CHROMEOS) 134bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Try the legacy path first for ChromeOS. We pass the new salt in as well 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // in case the legacy id doesn't exist. 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BrowserThread::PostBlockingPoolTask( 13706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) FROM_HERE, 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::Bind(&DeviceIDFetcher::LegacyComputeOnBlockingPool, 139bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) this, 140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) profile->GetPath(), salt)); 141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#else 1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Get the machine ID and call ComputeOnUIThread with salt + machine_id. 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetMachineIDAsync(base::Bind(&DeviceIDFetcher::ComputeOnUIThread, 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this, salt)); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 147bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DeviceIDFetcher::ComputeOnUIThread(const std::string& salt, 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const std::string& machine_id) { 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (machine_id.empty()) { 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LOG(ERROR) << "Empty machine id"; 154bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) RunCallbackOnIOThread(std::string()); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 157f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Build the identifier as follows: 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // SHA256(machine-id||service||SHA256(machine-id||service||salt)) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::vector<uint8> salt_bytes; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!base::HexStringToBytes(salt, &salt_bytes)) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) salt_bytes.clear(); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (salt_bytes.size() != kSaltLength) { 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LOG(ERROR) << "Unexpected salt bytes length: " << salt_bytes.size(); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RunCallbackOnIOThread(std::string()); 166f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) return; 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 168bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 169bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) char id_buf[256 / 8]; // 256-bits for SHA256 170bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) std::string input = machine_id; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) input.append(kDRMIdentifierFile); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) input.append(salt_bytes.begin(), salt_bytes.end()); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) crypto::SHA256HashString(input, &id_buf, sizeof(id_buf)); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::string id = StringToLowerASCII( 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::HexEncode(reinterpret_cast<const void*>(id_buf), sizeof(id_buf))); 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) input = machine_id; 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) input.append(kDRMIdentifierFile); 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) input.append(id); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) crypto::SHA256HashString(input, &id_buf, sizeof(id_buf)); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) id = StringToLowerASCII(base::HexEncode( 1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci reinterpret_cast<const void*>(id_buf), 1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci sizeof(id_buf))); 1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 184bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) RunCallbackOnIOThread(id); 1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// TODO(raymes): This is temporary code to migrate ChromeOS devices to the new 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// scheme for generating device IDs. Delete this once we are sure most ChromeOS 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// devices have been migrated. 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DeviceIDFetcher::LegacyComputeOnBlockingPool( 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const base::FilePath& profile_path, 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const std::string& salt) { 1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci std::string id; 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // First check if the legacy device ID file exists on ChromeOS. If it does, we 1957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // should just return that. 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) base::FilePath id_path = GetLegacyDeviceIDPath(profile_path); 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (base::PathExists(id_path)) { 198c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (base::ReadFileToString(id_path, &id) && !id.empty()) { 199 RunCallbackOnIOThread(id); 200 return; 201 } 202 } 203 // If we didn't find an ID, get the machine ID and call the new code path to 204 // generate an ID. 205 BrowserThread::PostTask( 206 BrowserThread::UI, FROM_HERE, 207 base::Bind(&GetMachineIDAsync, 208 base::Bind(&DeviceIDFetcher::ComputeOnUIThread, 209 this, salt))); 210} 211 212void DeviceIDFetcher::RunCallbackOnIOThread(const std::string& id) { 213 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 214 BrowserThread::PostTask( 215 BrowserThread::IO, FROM_HERE, 216 base::Bind(&DeviceIDFetcher::RunCallbackOnIOThread, this, id)); 217 return; 218 } 219 in_progress_ = false; 220 callback_.Run(id); 221} 222 223} // namespace chrome 224