auto_enrollment_client.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED() << "Bad restore mode " << restore_mode; 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return std::string(); 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)AutoEnrollmentClient::AutoEnrollmentClient( 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ProgressCallback& callback, 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceManagementService* service, 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PrefService* local_state, 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> system_request_context, 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& server_backed_state_key, 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool retrieve_device_state, 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int power_initial, 93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int power_limit) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : progress_callback_(callback), 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch state_(AUTO_ENROLLMENT_STATE_IDLE), 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_(false), 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_available_(false), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_id_(base::GenerateGUID()), 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) server_backed_state_key_(server_backed_state_key), 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) retrieve_device_state_(retrieve_device_state), 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) current_power_(power_initial), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_limit_(power_limit), 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) modulus_updates_received_(0), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_management_service_(service), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state_(local_state) { 106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request_context_ = new SystemPolicyRequestContext( 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system_request_context, GetUserAgent()); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_LE(current_power_, power_limit_); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!progress_callback_.is_null()); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!server_backed_state_key_.empty()) { 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) server_backed_state_key_hash_ = 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) crypto::SHA256HashString(server_backed_state_key_); 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochAutoEnrollmentClient::~AutoEnrollmentClient() { 118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutoEnrollmentClient::RegisterPrefs(PrefRegistrySimple* registry) { 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterBooleanPref(prefs::kShouldAutoEnroll, false); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->RegisterIntegerPref(prefs::kAutoEnrollmentPowerLimit, -1); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutoEnrollmentClient::CancelAutoEnrollment() { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state->SetBoolean(prefs::kShouldAutoEnroll, false); 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state->ClearPref(prefs::kServerBackedDeviceState); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state->CommitPendingWrite(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutoEnrollmentClient::Start() { 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // (Re-)register the network change observer. 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this); 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch net::NetworkChangeNotifier::AddNetworkChangeObserver(this); 139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drop the previous job and reset state. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_.reset(); 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch state_ = AUTO_ENROLLMENT_STATE_PENDING; 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) time_start_ = base::Time::Now(); 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) modulus_updates_received_ = 0; 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_ = false; 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_available_ = false; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NextStep(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AutoEnrollmentClient::Retry() { 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RetryStep(); 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutoEnrollmentClient::CancelAndDeleteSoon() { 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (time_start_.is_null() || !request_job_) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The client isn't running, just delete it. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Client still running, but our owner isn't interested in the result 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // anymore. Wait until the protocol completes to measure the extra time 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // needed. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_extra_start_ = base::Time::Now(); 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress_callback_.Reset(); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 168bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid AutoEnrollmentClient::OnNetworkChanged( 169bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch net::NetworkChangeNotifier::ConnectionType type) { 170bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (type != net::NetworkChangeNotifier::CONNECTION_NONE && 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !progress_callback_.is_null()) { 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RetryStep(); 173bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 174bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 175bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutoEnrollmentClient::GetCachedDecision() { 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const PrefService::Preference* has_server_state_pref = 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state_->FindPreference(prefs::kShouldAutoEnroll); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefService::Preference* previous_limit_pref = 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) local_state_->FindPreference(prefs::kAutoEnrollmentPowerLimit); 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool has_server_state = false; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int previous_limit = -1; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!has_server_state_pref || 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_pref->IsDefaultValue() || 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !has_server_state_pref->GetValue()->GetAsBoolean(&has_server_state) || 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !previous_limit_pref || 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous_limit_pref->IsDefaultValue() || 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !previous_limit_pref->GetValue()->GetAsInteger(&previous_limit) || 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) power_limit_ > previous_limit) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_ = has_server_state; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::RetryStep() { 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If there is a pending request job, let it finish. 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (request_job_) 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (GetCachedDecision()) { 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The bucket download check has completed already. If it came back 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // positive, then device state should be (re-)downloaded. 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (has_server_state_) { 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (retrieve_device_state_ && !device_state_available_ && 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SendDeviceStateRequest()) { 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start bucket download. 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (SendBucketDownloadRequest()) 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AutoEnrollmentClient::ReportProgress(AutoEnrollmentState state) { 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state_ = state; 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (progress_callback_.is_null()) { 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, this); 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress_callback_.Run(state_); 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AutoEnrollmentClient::NextStep() { 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!RetryStep()) { 232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Protocol finished successfully, report result. 233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool trigger_enrollment = false; 234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (retrieve_device_state_) { 235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::DictionaryValue* device_state_dict = 236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state_->GetDictionary(prefs::kServerBackedDeviceState); 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string restore_mode; 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_dict->GetString(kDeviceStateRestoreMode, &restore_mode); 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) trigger_enrollment = 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (restore_mode == kDeviceStateRestoreModeReEnrollmentRequested || 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) restore_mode == kDeviceStateRestoreModeReEnrollmentEnforced); 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) trigger_enrollment = has_server_state_; 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 246effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(trigger_enrollment ? AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT 247effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : AUTO_ENROLLMENT_STATE_NO_ENROLLMENT); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::SendBucketDownloadRequest() { 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (server_backed_state_key_hash_.empty()) 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only power-of-2 moduli are supported for now. These are computed by taking 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the lower |current_power_| bits of the hash. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 remainder = 0; 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (int i = 0; 8 * i < current_power_; ++i) { 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) uint64 byte = server_backed_state_key_hash_[31 - i] & 0xff; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remainder = remainder | (byte << (8 * i)); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remainder = remainder & ((GG_UINT64_C(1) << current_power_) - 1); 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 264effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(AUTO_ENROLLMENT_STATE_PENDING); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_.reset( 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_management_service_->CreateJob( 268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT, 269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) request_context_.get())); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_->SetClientID(device_id_); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) em::DeviceAutoEnrollmentRequest* request = 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_job_->GetRequest()->mutable_auto_enrollment_request(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request->set_remainder(remainder); 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->set_modulus(GG_INT64_C(1) << current_power_); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->Start( 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AutoEnrollmentClient::HandleRequestCompletion, 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this), 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AutoEnrollmentClient::OnBucketDownloadRequestCompletion)); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::SendDeviceStateRequest() { 283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(AUTO_ENROLLMENT_STATE_PENDING); 284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_.reset( 286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_management_service_->CreateJob( 287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceManagementRequestJob::TYPE_DEVICE_STATE_RETRIEVAL, 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_context_.get())); 289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->SetClientID(device_id_); 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) em::DeviceStateRetrievalRequest* request = 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->GetRequest()->mutable_device_state_retrieval_request(); 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request->set_server_backed_state_key(server_backed_state_key_); 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_->Start( 294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AutoEnrollmentClient::HandleRequestCompletion, 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this), 296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &AutoEnrollmentClient::OnDeviceStateRequestCompletion)); 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AutoEnrollmentClient::HandleRequestCompletion( 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RequestCompletionHandler handler, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceManagementStatus status, 303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) int net_error, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const em::DeviceManagementResponse& response) { 305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY(kUMARequestStatus, status); 306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (status != DM_STATUS_SUCCESS) { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Auto enrollment error: " << status; 308b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (status == DM_STATUS_REQUEST_FAILED) 309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_HISTOGRAM_SPARSE_SLOWLY(kUMANetworkErrorCode, -net_error); 310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_.reset(); 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Abort if CancelAndDeleteSoon has been called meanwhile. 313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (progress_callback_.is_null()) { 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoopProxy::current()->DeleteSoon(FROM_HERE, this); 315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 316effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(status == DM_STATUS_REQUEST_FAILED 317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ? AUTO_ENROLLMENT_STATE_CONNECTION_ERROR 318effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : AUTO_ENROLLMENT_STATE_SERVER_ERROR); 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool progress = (this->*handler)(status, net_error, response); 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_job_.reset(); 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (progress) 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NextStep(); 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 328effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ReportProgress(AUTO_ENROLLMENT_STATE_SERVER_ERROR); 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::OnBucketDownloadRequestCompletion( 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceManagementStatus status, 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int net_error, 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const em::DeviceManagementResponse& response) { 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool progress = false; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const em::DeviceAutoEnrollmentResponse& enrollment_response = 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response.auto_enrollment_response(); 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!response.has_auto_enrollment_response()) { 339a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Server failed to provide auto-enrollment response."; 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (enrollment_response.has_expected_modulus()) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Server is asking us to retry with a different modulus. 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) modulus_updates_received_++; 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 modulus = enrollment_response.expected_modulus(); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int power = NextPowerOf2(modulus); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((GG_INT64_C(1) << power) != modulus) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Auto enrollment: the server didn't ask for a power-of-2 " 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "modulus. Using the closest power-of-2 instead " 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "(" << modulus << " vs 2^" << power << ")"; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (modulus_updates_received_ >= 2) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Auto enrollment error: already retried with an updated " 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "modulus but the server asked for a new one again: " 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (power > power_limit_) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Auto enrollment error: the server asked for a larger " 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "modulus than the client accepts (" << power << " vs " 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power_limit_ << ")."; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retry at most once with the modulus that the server requested. 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (power <= current_power_) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Auto enrollment: the server asked to use a modulus (" 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << power << ") that isn't larger than the first used (" 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << current_power_ << "). Retrying anyway."; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 366bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Remember this value, so that eventual retries start with the correct 367bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // modulus. 368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) current_power_ = power; 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Server should have sent down a list of hashes to try. 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_server_state_ = IsIdHashInProtobuf(enrollment_response.hash()); 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Cache the current decision in local_state, so that it is reused in case 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // the device reboots before enrolling. 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state_->SetBoolean(prefs::kShouldAutoEnroll, has_server_state_); 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) local_state_->SetInteger(prefs::kAutoEnrollmentPowerLimit, power_limit_); 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) local_state_->CommitPendingWrite(); 379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "Auto enrollment check complete, has_server_state_ = " 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << has_server_state_; 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress = true; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Bucket download done, update UMA. 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateBucketDownloadTimingHistograms(); 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return progress; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::OnDeviceStateRequestCompletion( 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DeviceManagementStatus status, 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int net_error, 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const enterprise_management::DeviceManagementResponse& response) { 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool progress = false; 394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!response.has_device_state_retrieval_response()) { 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Server failed to provide auto-enrollment response."; 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const em::DeviceStateRetrievalResponse& state_response = 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) response.device_state_retrieval_response(); 399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { 400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DictionaryPrefUpdate dict(local_state_, prefs::kServerBackedDeviceState); 401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDict(dict.Get(), 402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kDeviceStateManagementDomain, 403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state_response.has_management_domain(), 404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new base::StringValue(state_response.management_domain())); 405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string restore_mode = 407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ConvertRestoreMode(state_response.restore_mode()); 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) UpdateDict(dict.Get(), 409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kDeviceStateRestoreMode, 410a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) !restore_mode.empty(), 411a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new base::StringValue(restore_mode)); 412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state_->CommitPendingWrite(); 414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) device_state_available_ = true; 415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) progress = true; 416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return progress; 419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AutoEnrollmentClient::IsIdHashInProtobuf( 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const google::protobuf::RepeatedPtrField<std::string>& hashes) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < hashes.size(); ++i) { 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (hashes.Get(i) == server_backed_state_key_hash_) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 430a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AutoEnrollmentClient::UpdateBucketDownloadTimingHistograms() { 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The minimum time can't be 0, must be at least 1. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const base::TimeDelta kMin = base::TimeDelta::FromMilliseconds(1); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const base::TimeDelta kMax = base::TimeDelta::FromMinutes(5); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, 0 can still be sampled. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const base::TimeDelta kZero = base::TimeDelta::FromMilliseconds(0); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBuckets = 50; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time now = base::Time::Now(); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!time_start_.is_null()) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delta = now - time_start_; 441b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES(kUMAProtocolTime, delta, kMin, kMax, kBuckets); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delta = kZero; 444bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!time_extra_start_.is_null()) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta = now - time_extra_start_; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This samples |kZero| when there was no need for extra time, so that we can 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // measure the ratio of users that succeeded without needing a delay to the 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // total users going through OOBE. 449b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES(kUMAExtraTime, delta, kMin, kMax, kBuckets); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 453