Index: chrome/browser/policy/device_management_policy_provider.cc |
diff --git a/chrome/browser/policy/device_management_policy_provider.cc b/chrome/browser/policy/device_management_policy_provider.cc |
index 627db0cdbbbce8bf62d39a22ddc8f10136083c5e..84834e248e638d710c5c2972bc33198fd09d81d6 100644 |
--- a/chrome/browser/policy/device_management_policy_provider.cc |
+++ b/chrome/browser/policy/device_management_policy_provider.cc |
@@ -13,6 +13,7 @@ |
#include "chrome/browser/policy/device_management_backend.h" |
#include "chrome/browser/policy/device_management_policy_cache.h" |
#include "chrome/browser/policy/proto/device_management_constants.h" |
+#include "chrome/browser/policy/proto/device_management_local.pb.h" |
#include "chrome/common/chrome_paths.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/notification_service.h" |
@@ -20,12 +21,20 @@ |
namespace policy { |
+namespace em = enterprise_management; |
+ |
const int64 kPolicyRefreshRateInMilliseconds = 3 * 60 * 60 * 1000; // 3 hours |
const int64 kPolicyRefreshMaxEarlierInMilliseconds = 20 * 60 * 1000; // 20 mins |
// These are the base values for delays before retrying after an error. They |
// will be doubled each time they are used. |
const int64 kPolicyRefreshErrorDelayInMilliseconds = 3 * 1000; // 3 seconds |
const int64 kDeviceTokenRefreshErrorDelayInMilliseconds = 3 * 1000; |
+// For unmanaged devices, check once per day whether they're still unmanaged. |
+const int64 kPolicyRefreshUnmanagedDeviceInMilliseconds = 24 * 60 * 60 * 1000; |
+ |
+const char* kDeviceTokenFilename = "Token"; |
+const char* kPolicyFilename = "Policy"; |
+const char* kUnmanagedDeviceMarkerFilename = "UnmanagedDevice"; |
danno
2010/11/25 16:35:01
It occurs to me that the information in this file
Jakob Kummerow
2010/11/26 09:17:23
Done.
|
// Ensures that the portion of the policy provider implementation that requires |
// the IOThread is deferred until the IOThread is fully initialized. The policy |
@@ -78,10 +87,13 @@ DeviceManagementPolicyProvider::DeviceManagementPolicyProvider( |
storage_dir_(GetOrCreateDeviceManagementDir(storage_dir)), |
policy_request_pending_(false), |
refresh_task_pending_(false), |
+ waiting_for_initial_policies_(true), |
policy_refresh_rate_ms_(kPolicyRefreshRateInMilliseconds), |
policy_refresh_max_earlier_ms_(kPolicyRefreshMaxEarlierInMilliseconds), |
policy_refresh_error_delay_ms_(kPolicyRefreshErrorDelayInMilliseconds), |
- token_fetch_error_delay_ms_(kDeviceTokenRefreshErrorDelayInMilliseconds) { |
+ token_fetch_error_delay_ms_(kDeviceTokenRefreshErrorDelayInMilliseconds), |
+ unmanaged_device_refresh_rate_ms_( |
+ kPolicyRefreshUnmanagedDeviceInMilliseconds) { |
Initialize(); |
} |
@@ -102,6 +114,9 @@ void DeviceManagementPolicyProvider::HandlePolicyResponse( |
// Reset the error delay since policy fetching succeeded this time. |
policy_refresh_error_delay_ms_ = kPolicyRefreshErrorDelayInMilliseconds; |
ScheduleRefreshTask(GetRefreshTaskDelay()); |
+ // Update this provider's internal waiting state, but don't notify anyone |
+ // else yet (that's done by the PrefValueStore that receives the policy). |
+ waiting_for_initial_policies_ = false; |
} |
void DeviceManagementPolicyProvider::OnError( |
@@ -116,25 +131,16 @@ void DeviceManagementPolicyProvider::OnError( |
policy_refresh_rate_ms_ < policy_refresh_error_delay_ms_) { |
policy_refresh_error_delay_ms_ = policy_refresh_rate_ms_; |
} |
-#if defined(OS_CHROMEOS) |
- // Send a CLOUD_POLICY_UPDATE notification to unblock ChromeOS logins that |
- // are waiting for an initial policy fetch to complete. |
- NotifyCloudPolicyUpdate(); |
-#endif |
-} |
- |
-#if defined(OS_CHROMEOS) |
-void DeviceManagementPolicyProvider::NotifyCloudPolicyUpdate() const { |
- NotificationService::current()->Notify( |
- NotificationType::CLOUD_POLICY_UPDATE, |
- Source<DeviceManagementPolicyProvider>(this), |
- NotificationService::NoDetails()); |
+ StopWaitingForInitialPolicies(); |
} |
-#endif |
void DeviceManagementPolicyProvider::OnTokenSuccess() { |
- if (policy_request_pending_) |
- return; |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, |
+ FROM_HERE, |
+ NewRunnableFunction( |
+ &DeviceManagementPolicyProvider::DeleteUnmanagedDeviceMarker, |
+ storage_dir_)); |
SendPolicyRequest(); |
} |
@@ -144,10 +150,20 @@ void DeviceManagementPolicyProvider::OnTokenError() { |
token_fetch_error_delay_ms_ *= 2; |
if (token_fetch_error_delay_ms_ > policy_refresh_rate_ms_) |
token_fetch_error_delay_ms_ = policy_refresh_rate_ms_; |
+ StopWaitingForInitialPolicies(); |
} |
void DeviceManagementPolicyProvider::OnNotManaged() { |
VLOG(1) << "This device is not managed."; |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, |
+ FROM_HERE, |
+ NewRunnableFunction( |
+ &DeviceManagementPolicyProvider::CreateUnmanagedDeviceMarker, |
+ storage_dir_, |
+ base::Time::NowFromSystemTime())); |
+ ScheduleRefreshTask(unmanaged_device_refresh_rate_ms_); |
+ StopWaitingForInitialPolicies(); |
} |
void DeviceManagementPolicyProvider::Shutdown() { |
@@ -158,19 +174,40 @@ void DeviceManagementPolicyProvider::Shutdown() { |
void DeviceManagementPolicyProvider::Initialize() { |
const FilePath policy_path = storage_dir_.Append( |
- FILE_PATH_LITERAL("Policy")); |
+ FILE_PATH_LITERAL(kPolicyFilename)); |
+ if (UnmanagedDeviceMarkerExists()) { |
+ // This is a non-first login on an unmanaged device. |
+ waiting_for_initial_policies_ = false; |
+ // Defer token_fetcher_ initialization until this device should ask for |
+ // a device token again. |
+ base::Time unmanaged_timestamp = GetUnmanagedDeviceTimestamp(); |
+ int64 delay = unmanaged_device_refresh_rate_ms_ - |
+ (base::Time::NowFromSystemTime().ToInternalValue() - |
+ unmanaged_timestamp.ToInternalValue()); |
+ if (delay < 0) |
+ delay = 0; |
+ BrowserThread::PostDelayedTask( |
+ BrowserThread::UI, FROM_HERE, |
+ new InitializeAfterIOThreadExistsTask(AsWeakPtr()), |
+ delay); |
+ } else { |
+ if (file_util::PathExists( |
+ storage_dir_.Append(FILE_PATH_LITERAL(kDeviceTokenFilename)))) { |
+ // This is a non-first login on a managed device. |
+ waiting_for_initial_policies_ = false; |
+ } |
+ // Defer initialization that requires the IOThread until after the IOThread |
+ // has been initialized. |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ new InitializeAfterIOThreadExistsTask(AsWeakPtr())); |
+ } |
cache_.reset(new DeviceManagementPolicyCache(policy_path)); |
cache_->LoadPolicyFromFile(); |
- |
- // Defer initialization that requires the IOThread until after the IOThread |
- // has been initialized. |
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
- new InitializeAfterIOThreadExistsTask(AsWeakPtr())); |
} |
void DeviceManagementPolicyProvider::InitializeAfterIOThreadExists() { |
const FilePath token_path = storage_dir_.Append( |
- FILE_PATH_LITERAL("Token")); |
+ FILE_PATH_LITERAL(kDeviceTokenFilename)); |
if (token_service_) { |
token_fetcher_ = |
new DeviceTokenFetcher(backend_.get(), token_service_, token_path); |
@@ -181,17 +218,17 @@ void DeviceManagementPolicyProvider::InitializeAfterIOThreadExists() { |
} |
void DeviceManagementPolicyProvider::SendPolicyRequest() { |
- if (!policy_request_pending_) { |
- policy_request_pending_ = true; |
- em::DevicePolicyRequest policy_request; |
- policy_request.set_policy_scope(kChromePolicyScope); |
- em::DevicePolicySettingRequest* setting = |
- policy_request.add_setting_request(); |
- setting->set_key(kChromeDevicePolicySettingKey); |
- backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(), |
- token_fetcher_->GetDeviceID(), |
- policy_request, this); |
- } |
+ if (policy_request_pending_) |
danno
2010/11/25 16:35:01
Why reverse this? Seems like an unrelated change.
Jakob Kummerow
2010/11/25 16:54:24
It is indeed unrelated and merely a formatting cha
|
+ return; |
+ policy_request_pending_ = true; |
+ em::DevicePolicyRequest policy_request; |
+ policy_request.set_policy_scope(kChromePolicyScope); |
+ em::DevicePolicySettingRequest* setting = |
+ policy_request.add_setting_request(); |
+ setting->set_key(kChromeDevicePolicySettingKey); |
+ backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(), |
+ token_fetcher_->GetDeviceID(), |
+ policy_request, this); |
} |
void DeviceManagementPolicyProvider::RefreshTaskExecute() { |
@@ -231,6 +268,80 @@ int64 DeviceManagementPolicyProvider::GetRefreshTaskDelay() { |
return delay; |
} |
+void DeviceManagementPolicyProvider::StopWaitingForInitialPolicies() { |
+ waiting_for_initial_policies_ = false; |
+#if defined(OS_CHROMEOS) |
danno
2010/11/25 16:35:01
Do you need this #define here? sending the notific
Jakob Kummerow
2010/11/25 16:54:24
This is Markus' code, I only moved it. Battle it o
|
+ // Send a CLOUD_POLICY_UPDATE notification to unblock ChromeOS logins that |
+ // are waiting for an initial policy fetch to complete. |
+ NotifyCloudPolicyUpdate(); |
danno
2010/11/25 16:35:01
Would it be possible to create a specific observer
Jakob Kummerow
2010/11/25 16:54:24
Same as above -- not my code. I'm just keeping the
|
+#endif |
+} |
+ |
+#if defined(OS_CHROMEOS) |
+void DeviceManagementPolicyProvider::NotifyCloudPolicyUpdate() const { |
+ NotificationService::current()->Notify( |
+ NotificationType::CLOUD_POLICY_UPDATE, |
+ Source<DeviceManagementPolicyProvider>(this), |
+ NotificationService::NoDetails()); |
+} |
+#endif |
+ |
+// static |
+FilePath DeviceManagementPolicyProvider::GetUnmanagedDeviceMarkerPath( |
+ const FilePath& storage_dir) { |
+ return storage_dir.Append(FILE_PATH_LITERAL(kUnmanagedDeviceMarkerFilename)); |
+} |
+ |
+// static |
+void DeviceManagementPolicyProvider::CreateUnmanagedDeviceMarker( |
+ const FilePath& storage_dir, const base::Time& timestamp) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ std::string data; |
+ em::UnmanagedDevice unmanaged_device; |
+ unmanaged_device.set_timestamp(timestamp.ToInternalValue()); |
+ if (!unmanaged_device.SerializeToString(&data)) { |
+ LOG(WARNING) << "Failed to serialize UnmanagedDevice timestamp."; |
+ return; |
+ } |
+ int size = data.size(); |
+ FilePath path(GetUnmanagedDeviceMarkerPath(storage_dir)); |
+ if (file_util::WriteFile(path, data.c_str(), size) != size) { |
+ LOG(WARNING) << "Failed to write "<< path.value(); |
+ } |
+} |
+ |
+// static |
+void DeviceManagementPolicyProvider::DeleteUnmanagedDeviceMarker( |
+ const FilePath& storage_dir) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ FilePath marker_file = GetUnmanagedDeviceMarkerPath(storage_dir); |
+ if (file_util::PathExists(marker_file)) { |
+ if (!file_util::Delete(marker_file, false)) { |
+ LOG(WARNING) << "Failed to delete UnmanagedDevice marker from " |
+ << marker_file.value(); |
+ } |
+ } |
+} |
+ |
+bool DeviceManagementPolicyProvider::UnmanagedDeviceMarkerExists() { |
+ return file_util::PathExists(GetUnmanagedDeviceMarkerPath(storage_dir_)); |
+} |
+ |
+base::Time DeviceManagementPolicyProvider::GetUnmanagedDeviceTimestamp() { |
+ FilePath file_path(GetUnmanagedDeviceMarkerPath(storage_dir_)); |
+ DCHECK(file_util::PathExists(file_path)); |
+ std::string data; |
+ if (!file_util::ReadFileToString(file_path, &data)) { |
+ LOG(WARNING) << "Failed to read UnmanagedDevice timestamp from " |
+ << file_path.value(); |
+ } |
+ em::UnmanagedDevice unmanaged_device; |
+ if (!unmanaged_device.ParseFromArray(data.c_str(), data.size())) { |
+ LOG(WARNING) << "Failed to parse UnmanagedDevice timestamp."; |
+ } |
+ return base::Time::FromInternalValue(unmanaged_device.timestamp()); |
+} |
+ |
// static |
std::string DeviceManagementPolicyProvider::GetDeviceManagementURL() { |
return CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
@@ -249,12 +360,8 @@ FilePath DeviceManagementPolicyProvider::GetOrCreateDeviceManagementDir( |
return device_management_dir; |
} |
-bool DeviceManagementPolicyProvider::IsPolicyCacheEmpty() const { |
- return cache_->last_policy_refresh_time().is_null(); |
-} |
- |
bool DeviceManagementPolicyProvider::WaitingForInitialPolicies() const { |
- return (IsPolicyCacheEmpty() && IsPolicyRequestPending()); |
+ return waiting_for_initial_policies_; |
} |
} // namespace policy |