1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155

content / browser / media / cdm_storage_manager.h [blame]

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

#ifndef CONTENT_BROWSER_MEDIA_CDM_STORAGE_MANAGER_H_
#define CONTENT_BROWSER_MEDIA_CDM_STORAGE_MANAGER_H_

#include <optional>

#include "base/containers/flat_map.h"
#include "base/memory/raw_ref.h"
#include "base/memory/scoped_refptr.h"
#include "base/threading/sequence_bound.h"
#include "base/types/pass_key.h"
#include "content/browser/media/cdm_file_impl.h"
#include "content/browser/media/cdm_storage_common.h"
#include "content/browser/media/cdm_storage_database.h"
#include "content/common/content_export.h"
#include "content/public/browser/cdm_storage_data_model.h"
#include "content/public/browser/storage_partition.h"
#include "media/cdm/cdm_type.h"
#include "media/mojo/mojom/cdm_storage.mojom.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"

namespace content {

class CONTENT_EXPORT CdmStorageManager : public media::mojom::CdmStorage,
                                         public CdmStorageDataModel {
 public:
  explicit CdmStorageManager(const base::FilePath& path);
  CdmStorageManager(const CdmStorageManager&) = delete;
  CdmStorageManager& operator=(const CdmStorageManager&) = delete;
  ~CdmStorageManager() override;

  // media::mojom::CdmStorage implementation.
  void Open(const std::string& file_name, OpenCallback callback) final;

  // CdmStorageDataModel implementation.
  void GetUsagePerAllStorageKeys(
      base::OnceCallback<void(const CdmStorageKeyUsageSize&)> callback,
      base::Time begin,
      base::Time end) final;
  void DeleteDataForStorageKey(const blink::StorageKey& storage_key,
                               base::OnceCallback<void(bool)> callback) final;

  void OpenCdmStorage(const CdmStorageBindingContext& binding_context,
                      mojo::PendingReceiver<media::mojom::CdmStorage> receiver);

  void ReadFile(
      const blink::StorageKey& storage_key,
      const media::CdmType& cdm_type,
      const std::string& file_name,
      base::OnceCallback<void(std::optional<std::vector<uint8_t>>)> callback);

  void WriteFile(const blink::StorageKey& storage_key,
                 const media::CdmType& cdm_type,
                 const std::string& file_name,
                 const std::vector<uint8_t>& data,
                 base::OnceCallback<void(bool)> callback);

  void GetSizeForFile(const blink::StorageKey& storage_key,
                      const media::CdmType& cdm_type,
                      const std::string& file_name,
                      base::OnceCallback<void(uint64_t)> callback);

  void GetSizeForStorageKey(const blink::StorageKey& storage_key,
                            const base::Time begin,
                            const base::Time end,
                            base::OnceCallback<void(uint64_t)> callback);

  void GetSizeForTimeFrame(const base::Time begin,
                           const base::Time end,
                           base::OnceCallback<void(uint64_t)> callback);

  void DeleteFile(const blink::StorageKey& storage_key,
                  const media::CdmType& cdm_type,
                  const std::string& file_name,
                  base::OnceCallback<void(bool)> callback);

  void DeleteData(
      const StoragePartition::StorageKeyMatcherFunction& storage_key_matcher,
      const blink::StorageKey& storage_key,
      const base::Time begin,
      const base::Time end,
      base::OnceCallback<void(bool)> callback);

  void OnFileReceiverDisconnect(const std::string& name,
                                const media::CdmType& cdm_type,
                                const blink::StorageKey& storage_key,
                                base::PassKey<CdmFileImpl> pass_key);

  bool has_empty_receiver_set() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return receivers_.empty();
  }

  CdmStorageBindingContext current_context() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return receivers_.current_context();
  }

  bool in_memory() const {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return path_.empty();
  }

 private:
  SEQUENCE_CHECKER(sequence_checker_);

  void DidOpenFile(const blink::StorageKey& storage_key,
                   const media::CdmType& cdm_type,
                   const std::string& file_name,
                   OpenCallback callback,
                   CdmStorageOpenError error);

  void DidReadFile(
      base::OnceCallback<void(std::optional<std::vector<uint8_t>>)> callback,
      std::optional<std::vector<uint8_t>> data);

  void DidWriteFile(base::OnceCallback<void(bool)> callback, bool success);

  void DidGetDatabaseSize(const uint64_t size);

  void DidGetSize(base::OnceCallback<void(uint64_t)> callback,
                  const std::string& operation,
                  std::optional<uint64_t> size);

  void ReportDatabaseOpenError(CdmStorageOpenError error);

  const base::FilePath path_;

  // Track CdmStorageDatabase size.
  bool database_size_reported_ = false;

  // All file operations are run through this member.
  base::SequenceBound<CdmStorageDatabase> db_
      GUARDED_BY_CONTEXT(sequence_checker_);

  // All receivers for frames and workers whose storage key is `storage_key()`.
  mojo::ReceiverSet<media::mojom::CdmStorage, CdmStorageBindingContext>
      receivers_ GUARDED_BY_CONTEXT(sequence_checker_);

  // Keep track of all media::mojom::CdmFile receivers, as each CdmFileImpl
  // object keeps a reference to `this`. If `this` goes away unexpectedly,
  // all remaining CdmFile receivers will be closed.
  std::map<CdmFileIdTwo, std::unique_ptr<CdmFileImpl>> cdm_files_
      GUARDED_BY_CONTEXT(sequence_checker_);

  base::WeakPtrFactory<CdmStorageManager> weak_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_MEDIA_CDM_STORAGE_MANAGER_H_