C++程序  |  168行  |  5.82 KB

// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_
#define CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_
#pragma once

#include <string>

#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "base/task.h"
#include "chrome/browser/policy/device_management_backend.h"
#include "chrome/browser/policy/policy_notifier.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"

namespace policy {

class CloudPolicyCacheBase;
class DeviceManagementService;

namespace em = enterprise_management;

// Fetches the device token that can be used for policy requests with the device
// management server, either from disk if it already has been successfully
// requested, otherwise from the device management server. An instance of the
// fetcher is shared as a singleton by all users of the device management token
// to ensure they all get the same token.
class DeviceTokenFetcher
    : public DeviceManagementBackend::DeviceRegisterResponseDelegate {
 public:
  class Observer {
   public:
    virtual ~Observer() {}
    virtual void OnDeviceTokenAvailable() = 0;
  };

  // |service| is used to talk to the device management service and |cache| is
  // used to persist whether the device is unmanaged.
  DeviceTokenFetcher(DeviceManagementService* service,
                     CloudPolicyCacheBase* cache,
                     PolicyNotifier* notifier);
  // Version for tests that allows to set timing parameters.
  DeviceTokenFetcher(DeviceManagementService* service,
                     CloudPolicyCacheBase* cache,
                     PolicyNotifier* notifier,
                     int64 token_fetch_error_delay_ms,
                     int64 token_fetch_error_max_delay_ms,
                     int64 unmanaged_device_refresh_rate_ms);
  virtual ~DeviceTokenFetcher();

  // Starts fetching a token.
  // Declared virtual so it can be overridden by mocks.
  virtual void FetchToken(const std::string& auth_token,
                          const std::string& device_id,
                          em::DeviceRegisterRequest_Type policy_type,
                          const std::string& machine_id,
                          const std::string& machine_model);

  virtual void SetUnmanagedState();

  // Returns the device management token or the empty string if not available.
  // Declared virtual so it can be overridden by mocks.
  virtual const std::string& GetDeviceToken();

  // Disables the auto-retry-on-error behavior of this token fetcher.
  void StopAutoRetry();

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // DeviceManagementBackend::DeviceRegisterResponseDelegate method overrides:
  virtual void HandleRegisterResponse(
      const em::DeviceRegisterResponse& response);
  virtual void OnError(DeviceManagementBackend::ErrorCode code);

 private:
  friend class DeviceTokenFetcherTest;

  // The different states that the fetcher can be in during the process of
  // getting the device token. |state_| is initialized to INACTIVE, depending
  // on the result of a token fetching attempt can transition to either of
  // TOKEN_AVAILABLE, UNMANAGED, or ERROR. The first attempt must be triggered
  // externally. When |state_| is UNMANAGED, a new fetching attempt is
  // performed every |unmanaged_device_refresh_rate_ms_|; when it's ERROR,
  // a new attempt is done after |effective_token_fetch_error_delay_ms_|.
  enum FetcherState {
    // Fetcher inactive.
    STATE_INACTIVE,
    // Token available.
    STATE_TOKEN_AVAILABLE,
    // Device unmanaged.
    STATE_UNMANAGED,
    // Error, retry later.
    STATE_ERROR,
    // Temporary error. Retry sooner.
    STATE_TEMPORARY_ERROR,
    // Server rejected the auth token.
    STATE_BAD_AUTH
  };

  // Common initialization helper.
  void Initialize(DeviceManagementService* service,
                  CloudPolicyCacheBase* cache,
                  PolicyNotifier* notifier,
                  int64 token_fetch_error_delay_ms,
                  int64 token_fetch_error_max_delay_ms,
                  int64 unmanaged_device_refresh_rate_ms);

  // Moves the fetcher into a new state.
  void SetState(FetcherState state);

  // Resets |backend_|, then uses |auth_token_| and |device_id_| to perform
  // an actual token fetch.
  void FetchTokenInternal();

  // Called back from the |retry_task_|.
  void ExecuteRetryTask();

  // Cancels the |retry_task_|.
  void CancelRetryTask();

  // Service and backend. A new backend is created whenever the fetcher gets
  // reset.
  DeviceManagementService* service_;  // weak
  scoped_ptr<DeviceManagementBackend> backend_;

  // Reference to the cache. Used to persist and read unmanaged state.
  CloudPolicyCacheBase* cache_;

  PolicyNotifier* notifier_;

  // Refresh parameters.
  int64 token_fetch_error_delay_ms_;
  int64 token_fetch_error_max_delay_ms_;
  int64 effective_token_fetch_error_delay_ms_;
  int64 unmanaged_device_refresh_rate_ms_;

  // State the fetcher is currently in.
  FetcherState state_;

  // Current device token.
  std::string device_token_;

  // Contains the AuthToken for the device management server.
  std::string auth_token_;
  // Device identifier to send to the server.
  std::string device_id_;
  // Contains policy type to send to the server.
  em::DeviceRegisterRequest_Type policy_type_;
  // Contains physical machine id to send to the server.
  std::string machine_id_;
  // Contains physical machine model to send to server.
  std::string machine_model_;

  // Task that has been scheduled to retry fetching a token.
  CancelableTask* retry_task_;

  ScopedRunnableMethodFactory<DeviceTokenFetcher> method_factory_;

  ObserverList<Observer, true> observer_list_;
};

}  // namespace policy

#endif  // CHROME_BROWSER_POLICY_DEVICE_TOKEN_FETCHER_H_