chromium/chrome/browser/ash/policy/status_collector/tpm_status_combiner.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_POLICY_STATUS_COLLECTOR_TPM_STATUS_COMBINER_H_
#define CHROME_BROWSER_ASH_POLICY_STATUS_COLLECTOR_TPM_STATUS_COMBINER_H_

#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "chrome/browser/ash/policy/status_collector/device_status_collector.h"
#include "chromeos/ash/components/dbus/attestation/interface.pb.h"
#include "chromeos/dbus/tpm_manager/tpm_manager.pb.h"
#include "components/policy/proto/device_management_backend.pb.h"

namespace policy {

// This class is meant to combine multiple statuses around TPM and enrollment.
// Because the result `enterprise_management::TpmStatusInfo` comes from
// different sources of D-Bus calls, this class is designed to be used as a
// shared pointer that resides in multiple callbacks. When all the replies of
// the D-Bus calls, which are sent by the user of this class, are finished, this
// class combines the results into a single `enterprise_policy::TpmStatusInfo`
// and get destroyed naturally when all the callbacks of the D-Bus calls are
// done.
//
// Note that in order to increase test coverage of `DeviceStatusCollector`, this
// class doesn't have its own unittest; instead, it is tested along with
// `DeviceStatusCollector` end-to-end.
class TpmStatusCombiner : public base::RefCounted<TpmStatusCombiner> {
 public:
  // The passed `callback` is invoked when all the D-Bus responses of
  // interest are received.
  explicit TpmStatusCombiner(DeviceStatusCollector::TpmStatusReceiver callback);

  // Not copyable or movable.
  TpmStatusCombiner(const TpmStatusCombiner&) = delete;
  TpmStatusCombiner& operator=(const TpmStatusCombiner&) = delete;
  TpmStatusCombiner(TpmStatusCombiner&&) = delete;
  TpmStatusCombiner& operator=(TpmStatusCombiner&&) = delete;

  // Designed to be the callback of
  // `TpmManagerClient::GetTpmNonsensitiveStatus()`.
  void OnGetTpmStatus(
      const ::tpm_manager::GetTpmNonsensitiveStatusReply& reply);
  // Designed to be the callback of `AttestationClient::GetStatus()`.
  void OnGetEnrollmentStatus(const ::attestation::GetStatusReply& reply);
  // Designed to be the callback of
  // `AttestationClient::GetDictionaryAttackInfoReply()`.
  void OnGetDictionaryAttackInfo(
      const ::tpm_manager::GetDictionaryAttackInfoReply& reply);
  // Designed to be the callback of
  // `TpmManagerClient::OnGetSupportedFeatures()`.
  void OnGetSupportedFeatures(
      const ::tpm_manager::GetSupportedFeaturesReply& reply);

 private:
  // `RefCounted` subclass requires the destructor to be non-public.
  friend class base::RefCounted<TpmStatusCombiner>;
  ~TpmStatusCombiner();

  // Called when receiving any D-Bus response. If it's the last D-Bus response
  // we expect to handle, runs the callback passed in
  void RunCallbackIfComplete();

  // Invoked when all D-Bus response are handled.
  DeviceStatusCollector::TpmStatusReceiver callback_;

  // The combined result passed into `callback_`.
  enterprise_management::TpmStatusInfo tpm_status_info_;

  // Indicates each D-Bus response being received or not.
  bool has_tpm_status_ = false;
  bool has_enrollment_status_ = false;
  bool has_dictionary_attack_info_ = false;
  bool has_supported_features_ = false;
};

}  // namespace policy

#endif  // CHROME_BROWSER_ASH_POLICY_STATUS_COLLECTOR_TPM_STATUS_COMBINER_H_