auto_enrollment_client.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/auto_enrollment_client.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/guid.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/metrics/sparse_histogram.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/chromeos/policy/server_backed_device_state.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/common/chrome_content_client.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/device_management_service.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/system_policy_request_context.h" 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/sha2.h" 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h" 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "url/gurl.h" 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using content::BrowserThread; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace policy { 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// UMA histogram names. 38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char kUMAProtocolTime[] = "Enterprise.AutoEnrollmentProtocolTime"; 39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char kUMAExtraTime[] = "Enterprise.AutoEnrollmentExtraTime"; 40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char kUMARequestStatus[] = "Enterprise.AutoEnrollmentRequestStatus"; 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char kUMANetworkErrorCode[] = 42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) "Enterprise.AutoEnrollmentRequestNetworkErrorCode"; 43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the power of the next power-of-2 starting at |value|. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int NextPowerOf2(int64 value) { 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (int i = 0; i <= AutoEnrollmentClient::kMaximumPower; ++i) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((GG_INT64_C(1) << i) >= value) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No other value can be represented in an int64. 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return AutoEnrollmentClient::kMaximumPower + 1; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Sets or clears a value in a dictionary. 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void UpdateDict(base::DictionaryValue* dict, 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* pref_path, 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool set_or_clear, 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Value* value) { 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<base::Value> scoped_value(value); 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (set_or_clear) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dict->Set(pref_path, scoped_value.release()); 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dict->Remove(pref_path, NULL); 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Converts a restore mode enum value from the DM protocol into the 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// corresponding prefs string constant. 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string ConvertRestoreMode( 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) em::DeviceStateRetrievalResponse::RestoreMode restore_mode) { 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (restore_mode) { 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case em::DeviceStateRetrievalResponse::RESTORE_MODE_NONE: 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return std::string(); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_REQUESTED: 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return kDeviceStateRestoreModeReEnrollmentRequested; 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case em::DeviceStateRetrievalResponse::RESTORE_MODE_REENROLLMENT_ENFORCED: 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return kDeviceStateRestoreModeReEnrollmentEnforced; 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Return is required to avoid compiler warning. 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED() << "Bad restore mode " << restore_mode; 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return std::string(); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)AutoEnrollmentClient::AutoEnrollmentClient( 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ProgressCallback& callback, 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceManagementService* service, 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PrefService* local_state, 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> system_request_context, 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& server_backed_state_key, 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool retrieve_device_state, 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int power_initial, 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int power_limit) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : progress_callback_(callback), 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch state_(AUTO_ENROLLMENT_STATE_IDLE), 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_(false), 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_available_(false), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_id_(base::GenerateGUID()), 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) server_backed_state_key_(server_backed_state_key), 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) retrieve_device_state_(retrieve_device_state), 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) current_power_(power_initial), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_limit_(power_limit), 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) modulus_updates_received_(0), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_management_service_(service), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state_(local_state) { 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request_context_ = new SystemPolicyRequestContext( 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system_request_context, GetUserAgent()); 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_LE(current_power_, power_limit_); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!progress_callback_.is_null()); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!server_backed_state_key_.empty()) { 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) server_backed_state_key_hash_ = 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) crypto::SHA256HashString(server_backed_state_key_); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochAutoEnrollmentClient::~AutoEnrollmentClient() { 119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutoEnrollmentClient::RegisterPrefs(PrefRegistrySimple* registry) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterBooleanPref(prefs::kShouldAutoEnroll, false); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterIntegerPref(prefs::kAutoEnrollmentPowerLimit, -1); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutoEnrollmentClient::CancelAutoEnrollment() { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state->SetBoolean(prefs::kShouldAutoEnroll, false); 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state->ClearPref(prefs::kServerBackedDeviceState); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state->CommitPendingWrite(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutoEnrollmentClient::Start() { 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // (Re-)register the network change observer. 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch net::NetworkChangeNotifier::AddNetworkChangeObserver(this); 140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drop the previous job and reset state. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_.reset(); 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch state_ = AUTO_ENROLLMENT_STATE_PENDING; 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) time_start_ = base::Time::Now(); 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) modulus_updates_received_ = 0; 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_ = false; 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_available_ = false; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NextStep(); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AutoEnrollmentClient::Retry() { 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RetryStep(); 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutoEnrollmentClient::CancelAndDeleteSoon() { 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (time_start_.is_null() || !request_job_) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The client isn't running, just delete it. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Client still running, but our owner isn't interested in the result 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // anymore. Wait until the protocol completes to measure the extra time 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // needed. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_extra_start_ = base::Time::Now(); 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress_callback_.Reset(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 169bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid AutoEnrollmentClient::OnNetworkChanged( 170bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch net::NetworkChangeNotifier::ConnectionType type) { 171bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (type != net::NetworkChangeNotifier::CONNECTION_NONE && 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !progress_callback_.is_null()) { 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RetryStep(); 174bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 175bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 176bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutoEnrollmentClient::GetCachedDecision() { 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const PrefService::Preference* has_server_state_pref = 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state_->FindPreference(prefs::kShouldAutoEnroll); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefService::Preference* previous_limit_pref = 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state_->FindPreference(prefs::kAutoEnrollmentPowerLimit); 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool has_server_state = false; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int previous_limit = -1; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!has_server_state_pref || 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_pref->IsDefaultValue() || 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !has_server_state_pref->GetValue()->GetAsBoolean(&has_server_state) || 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !previous_limit_pref || 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_limit_pref->IsDefaultValue() || 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !previous_limit_pref->GetValue()->GetAsInteger(&previous_limit) || 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_limit_ > previous_limit) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_ = has_server_state; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::RetryStep() { 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If there is a pending request job, let it finish. 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (request_job_) 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (GetCachedDecision()) { 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The bucket download check has completed already. If it came back 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // positive, then device state should be (re-)downloaded. 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (has_server_state_) { 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (retrieve_device_state_ && !device_state_available_ && 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendDeviceStateRequest()) { 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start bucket download. 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (SendBucketDownloadRequest()) 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AutoEnrollmentClient::ReportProgress(AutoEnrollmentState state) { 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state_ = state; 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (progress_callback_.is_null()) { 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, this); 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress_callback_.Run(state_); 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AutoEnrollmentClient::NextStep() { 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!RetryStep()) { 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Protocol finished successfully, report result. 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool trigger_enrollment = false; 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (retrieve_device_state_) { 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::DictionaryValue* device_state_dict = 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state_->GetDictionary(prefs::kServerBackedDeviceState); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string restore_mode; 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode); 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) trigger_enrollment = 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested || 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced); 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) trigger_enrollment = has_server_state_; 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(trigger_enrollment ? AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT 248effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : AUTO_ENROLLMENT_STATE_NO_ENROLLMENT); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::SendBucketDownloadRequest() { 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (server_backed_state_key_hash_.empty()) 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only power-of-2 moduli are supported for now. These are computed by taking 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the lower |current_power_| bits of the hash. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 remainder = 0; 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (int i = 0; 8 * i < current_power_; ++i) { 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint64 byte = server_backed_state_key_hash_[31 - i] & 0xff; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remainder = remainder | (byte << (8 * i)); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remainder = remainder & ((GG_UINT64_C(1) << current_power_) - 1); 264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 265effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(AUTO_ENROLLMENT_STATE_PENDING); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_.reset( 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_management_service_->CreateJob( 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, 270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request_context_.get())); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_->SetClientID(device_id_); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em::DeviceAutoEnrollmentRequest* request = 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_->GetRequest()->mutable_auto_enrollment_request(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->set_remainder(remainder); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->set_modulus(GG_INT64_C(1) << current_power_); 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->Start( 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AutoEnrollmentClient::HandleRequestCompletion, 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this), 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AutoEnrollmentClient::OnBucketDownloadRequestCompletion)); 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::SendDeviceStateRequest() { 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(AUTO_ENROLLMENT_STATE_PENDING); 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_.reset( 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_management_service_->CreateJob( 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceManagementRequestJob::TYPE_DEVICE_STATE_RETRIEVAL, 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_context_.get())); 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->SetClientID(device_id_); 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) em::DeviceStateRetrievalRequest* request = 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->GetRequest()->mutable_device_state_retrieval_request(); 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->set_server_backed_state_key(server_backed_state_key_); 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->Start( 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AutoEnrollmentClient::HandleRequestCompletion, 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this), 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AutoEnrollmentClient::OnDeviceStateRequestCompletion)); 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AutoEnrollmentClient::HandleRequestCompletion( 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RequestCompletionHandler handler, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceManagementStatus status, 304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) int net_error, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const em::DeviceManagementResponse& response) { 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY(kUMARequestStatus, status); 307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (status != DM_STATUS_SUCCESS) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Auto enrollment error: " << status; 309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (status == DM_STATUS_REQUEST_FAILED) 310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY(kUMANetworkErrorCode, -net_error); 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_.reset(); 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Abort if CancelAndDeleteSoon has been called meanwhile. 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (progress_callback_.is_null()) { 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, this); 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(status == DM_STATUS_REQUEST_FAILED 318effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ? AUTO_ENROLLMENT_STATE_CONNECTION_ERROR 319effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : AUTO_ENROLLMENT_STATE_SERVER_ERROR); 320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool progress = (this->*handler)(status, net_error, response); 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_.reset(); 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (progress) 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NextStep(); 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 329effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(AUTO_ENROLLMENT_STATE_SERVER_ERROR); 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::OnBucketDownloadRequestCompletion( 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceManagementStatus status, 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int net_error, 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const em::DeviceManagementResponse& response) { 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool progress = false; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const em::DeviceAutoEnrollmentResponse& enrollment_response = 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.auto_enrollment_response(); 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!response.has_auto_enrollment_response()) { 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Server failed to provide auto-enrollment response."; 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (enrollment_response.has_expected_modulus()) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Server is asking us to retry with a different modulus. 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) modulus_updates_received_++; 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 modulus = enrollment_response.expected_modulus(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int power = NextPowerOf2(modulus); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((GG_INT64_C(1) << power) != modulus) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Auto enrollment: the server didn't ask for a power-of-2 " 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "modulus. Using the closest power-of-2 instead " 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "(" << modulus << " vs 2^" << power << ")"; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (modulus_updates_received_ >= 2) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Auto enrollment error: already retried with an updated " 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "modulus but the server asked for a new one again: " 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (power > power_limit_) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Auto enrollment error: the server asked for a larger " 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "modulus than the client accepts (" << power << " vs " 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power_limit_ << ")."; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retry at most once with the modulus that the server requested. 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (power <= current_power_) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Auto enrollment: the server asked to use a modulus (" 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power << ") that isn't larger than the first used (" 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << current_power_ << "). Retrying anyway."; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 367bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Remember this value, so that eventual retries start with the correct 368bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // modulus. 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) current_power_ = power; 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Server should have sent down a list of hashes to try. 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_ = IsIdHashInProtobuf(enrollment_response.hash()); 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Cache the current decision in local_state, so that it is reused in case 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the device reboots before enrolling. 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state_->SetBoolean(prefs::kShouldAutoEnroll, has_server_state_); 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) local_state_->SetInteger(prefs::kAutoEnrollmentPowerLimit, power_limit_); 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) local_state_->CommitPendingWrite(); 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Auto enrollment check complete, has_server_state_ = " 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << has_server_state_; 382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress = true; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Bucket download done, update UMA. 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateBucketDownloadTimingHistograms(); 387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return progress; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::OnDeviceStateRequestCompletion( 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceManagementStatus status, 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int net_error, 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const enterprise_management::DeviceManagementResponse& response) { 394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool progress = false; 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!response.has_device_state_retrieval_response()) { 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Server failed to provide auto-enrollment response."; 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const em::DeviceStateRetrievalResponse& state_response = 399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response.device_state_retrieval_response(); 400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DictionaryPrefUpdate dict(local_state_, prefs::kServerBackedDeviceState); 402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDict(dict.Get(), 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kDeviceStateManagementDomain, 404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state_response.has_management_domain(), 405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new base::StringValue(state_response.management_domain())); 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string restore_mode = 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ConvertRestoreMode(state_response.restore_mode()); 409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDict(dict.Get(), 410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kDeviceStateRestoreMode, 411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !restore_mode.empty(), 412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new base::StringValue(restore_mode)); 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state_->CommitPendingWrite(); 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_available_ = true; 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress = true; 417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return progress; 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::IsIdHashInProtobuf( 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const google::protobuf::RepeatedPtrField<std::string>& hashes) { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < hashes.size(); ++i) { 425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (hashes.Get(i) == server_backed_state_key_hash_) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AutoEnrollmentClient::UpdateBucketDownloadTimingHistograms() { 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The minimum time can't be 0, must be at least 1. 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const base::TimeDelta kMin = base::TimeDelta::FromMilliseconds(1); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const base::TimeDelta kMax = base::TimeDelta::FromMinutes(5); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, 0 can still be sampled. 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const base::TimeDelta kZero = base::TimeDelta::FromMilliseconds(0); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBuckets = 50; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time now = base::Time::Now(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!time_start_.is_null()) { 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delta = now - time_start_; 442b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES(kUMAProtocolTime, delta, kMin, kMax, kBuckets); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delta = kZero; 445bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!time_extra_start_.is_null()) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta = now - time_extra_start_; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This samples |kZero| when there was no need for extra time, so that we can 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // measure the ratio of users that succeeded without needing a delay to the 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // total users going through OOBE. 450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES(kUMAExtraTime, delta, kMin, kMax, kBuckets); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 454