Home | History | Annotate | Download | only in policy
      1 // Copyright 2014 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/chromeos/policy/server_backed_state_keys_broker.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/bind.h"
     10 #include "base/location.h"
     11 #include "base/task_runner.h"
     12 #include "chromeos/dbus/session_manager_client.h"
     13 
     14 namespace policy {
     15 
     16 namespace {
     17 
     18 // Refresh interval for state keys. There's a quantized time component in
     19 // state key generation, so they rotate over time. The quantum size is pretty
     20 // coarse though (currently 2^23 seconds), so simply polling for a new state
     21 // keys once a day is good enough.
     22 const int kPollIntervalSeconds = 60 * 60 * 24;
     23 
     24 }  // namespace
     25 
     26 ServerBackedStateKeysBroker::ServerBackedStateKeysBroker(
     27     chromeos::SessionManagerClient* session_manager_client,
     28     scoped_refptr<base::TaskRunner> delayed_task_runner)
     29     : session_manager_client_(session_manager_client),
     30       delayed_task_runner_(delayed_task_runner),
     31       first_boot_(false),
     32       requested_(false),
     33       initial_retrieval_completed_(false),
     34       weak_factory_(this) {
     35 }
     36 
     37 ServerBackedStateKeysBroker::~ServerBackedStateKeysBroker() {
     38 }
     39 
     40 ServerBackedStateKeysBroker::Subscription
     41 ServerBackedStateKeysBroker::RegisterUpdateCallback(
     42     const base::Closure& callback) {
     43   if (!available())
     44     FetchStateKeys();
     45   return update_callbacks_.Add(callback);
     46 }
     47 
     48 void ServerBackedStateKeysBroker::RequestStateKeys(
     49     const StateKeysCallback& callback) {
     50   if (pending()) {
     51     request_callbacks_.push_back(callback);
     52     FetchStateKeys();
     53     return;
     54   }
     55 
     56   if (!callback.is_null())
     57     callback.Run(state_keys_, first_boot_);
     58   return;
     59 }
     60 
     61 void ServerBackedStateKeysBroker::FetchStateKeys() {
     62   if (!requested_) {
     63     requested_ = true;
     64     session_manager_client_->GetServerBackedStateKeys(
     65         base::Bind(&ServerBackedStateKeysBroker::StoreStateKeys,
     66                    weak_factory_.GetWeakPtr()));
     67   }
     68 }
     69 
     70 void ServerBackedStateKeysBroker::StoreStateKeys(
     71     const std::vector<std::string>& state_keys, bool first_boot) {
     72   bool send_notification = !initial_retrieval_completed_;
     73 
     74   requested_ = false;
     75   initial_retrieval_completed_ = true;
     76   if (state_keys.empty()) {
     77     LOG(WARNING) << "Failed to obtain server-backed state keys.";
     78   } else if (state_keys.end() !=
     79              std::find(state_keys.begin(), state_keys.end(), std::string())) {
     80     LOG(WARNING) << "Bad state keys.";
     81   } else {
     82     send_notification |= state_keys_ != state_keys;
     83     state_keys_ = state_keys;
     84     first_boot_ = first_boot;
     85   }
     86 
     87   if (send_notification)
     88     update_callbacks_.Notify();
     89 
     90   std::vector<StateKeysCallback> callbacks;
     91   request_callbacks_.swap(callbacks);
     92   for (std::vector<StateKeysCallback>::const_iterator callback(
     93            callbacks.begin());
     94        callback != callbacks.end();
     95        ++callback) {
     96     if (!callback->is_null())
     97       callback->Run(state_keys_, first_boot_);
     98   }
     99 
    100   delayed_task_runner_->PostDelayedTask(
    101       FROM_HERE,
    102       base::Bind(&ServerBackedStateKeysBroker::FetchStateKeys,
    103                  weak_factory_.GetWeakPtr()),
    104       base::TimeDelta::FromSeconds(kPollIntervalSeconds));
    105 }
    106 
    107 }  // namespace policy
    108