1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/policy/policy_notifier.h" 6 7 namespace policy { 8 9 void PolicyNotifier::AddObserver(CloudPolicySubsystem::Observer* observer) { 10 observer_list_.AddObserver(observer); 11 } 12 13 void PolicyNotifier::RemoveObserver(CloudPolicySubsystem::Observer* observer) { 14 observer_list_.RemoveObserver(observer); 15 } 16 17 PolicyNotifier::PolicyNotifier() 18 : state_(CloudPolicySubsystem::UNENROLLED), 19 error_details_(CloudPolicySubsystem::NO_DETAILS) { 20 for (int i = 0; i < NUM_SOURCES; ++i) { 21 component_states_[i] = CloudPolicySubsystem::UNENROLLED; 22 component_error_details_[i] = CloudPolicySubsystem::NO_DETAILS; 23 } 24 } 25 26 PolicyNotifier::~PolicyNotifier() { 27 } 28 29 void PolicyNotifier::Inform(PolicySubsystemState state, 30 ErrorDetails error_details, 31 StatusSource source) { 32 component_states_[source] = state; 33 component_error_details_[source] = error_details; 34 RecomputeState(); 35 } 36 37 void PolicyNotifier::RecomputeState() { 38 // Define shortcuts. 39 PolicySubsystemState* s = component_states_; 40 ErrorDetails* e = component_error_details_; 41 42 // Compute overall state. General idea: If any component knows we're 43 // unmanaged, set that as global state. Otherwise, ask components in the 44 // order they normally do work in. If anyone reports 'SUCCESS' or 'UNENROLLED' 45 // (which can also be read as 'undefined/unknown', ask the next component. 46 if (s[TOKEN_FETCHER] == CloudPolicySubsystem::UNMANAGED || 47 s[POLICY_CONTROLLER] == CloudPolicySubsystem::UNMANAGED || 48 s[POLICY_CACHE] == CloudPolicySubsystem::UNMANAGED) { 49 state_ = CloudPolicySubsystem::UNMANAGED; 50 error_details_ = CloudPolicySubsystem::NO_DETAILS; 51 } else if (s[TOKEN_FETCHER] == CloudPolicySubsystem::NETWORK_ERROR) { 52 state_ = s[TOKEN_FETCHER]; 53 error_details_ = e[TOKEN_FETCHER]; 54 } else if (s[TOKEN_FETCHER] == CloudPolicySubsystem::BAD_GAIA_TOKEN) { 55 state_ = s[TOKEN_FETCHER]; 56 error_details_ = e[TOKEN_FETCHER]; 57 } else if (s[POLICY_CONTROLLER] == CloudPolicySubsystem::NETWORK_ERROR) { 58 state_ = s[POLICY_CONTROLLER]; 59 error_details_ = e[POLICY_CONTROLLER]; 60 } else if (s[TOKEN_FETCHER] == CloudPolicySubsystem::SUCCESS && 61 s[POLICY_CONTROLLER] != CloudPolicySubsystem::SUCCESS) { 62 // We need to be able to differentiate between token fetch success or 63 // policy fetch success. 64 state_ = CloudPolicySubsystem::TOKEN_FETCHED; 65 error_details_ = CloudPolicySubsystem::NO_DETAILS; 66 } else { 67 state_ = s[POLICY_CACHE]; 68 error_details_ = e[POLICY_CACHE]; 69 } 70 71 FOR_EACH_OBSERVER(CloudPolicySubsystem::Observer, observer_list_, 72 OnPolicyStateChanged(state_, error_details_)); 73 } 74 75 } // namespace policy 76