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