blob: d79faaddc4c963a5d9edfdb2d1e3ad3d3f508669 [file] [log] [blame]
John Rummellaa05b9c2017-10-30 08:41:291// Copyright 2017 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#ifndef CONTENT_BROWSER_MEDIA_CDM_FILE_IMPL_H_
6#define CONTENT_BROWSER_MEDIA_CDM_FILE_IMPL_H_
7
8#include <string>
John Rummell9fcfaa72019-06-13 23:08:129#include <vector>
John Rummellaa05b9c2017-10-30 08:41:2910
11#include "base/callback_forward.h"
12#include "base/files/file.h"
John Rummellaa05b9c2017-10-30 08:41:2913#include "base/memory/ref_counted.h"
14#include "base/memory/weak_ptr.h"
John Rummell879f96f2019-07-25 07:32:1415#include "base/threading/sequence_bound.h"
John Rummellaa05b9c2017-10-30 08:41:2916#include "base/threading/thread_checker.h"
John Rummelldc30ef532019-08-17 00:14:2017#include "base/time/time.h"
Austin Sullivan22e0f3d2022-01-29 00:59:1718#include "media/cdm/cdm_type.h"
Miyoung Shin25bb8c092019-08-03 00:56:5719#include "media/mojo/mojom/cdm_storage.mojom.h"
Austin Sullivan53755752022-03-03 02:31:2420#include "mojo/public/cpp/bindings/associated_receiver.h"
DongJun Kimfebb3c22019-10-21 02:08:0621#include "storage/browser/file_system/async_file_util.h"
John Rummellaa05b9c2017-10-30 08:41:2922#include "url/origin.h"
23
24namespace storage {
25class FileSystemContext;
26class FileSystemURL;
27} // namespace storage
28
29namespace content {
Austin Sullivan53755752022-03-03 02:31:2430class MediaLicenseStorageHost;
John Rummellaa05b9c2017-10-30 08:41:2931
32// This class implements the media::mojom::CdmFile interface. It uses the same
33// mojo pipe as CdmStorageImpl, to enforce message dispatch order.
34class CdmFileImpl final : public media::mojom::CdmFile {
35 public:
John Rummell9fcfaa72019-06-13 23:08:1236 // Check whether |name| is valid as a usable file name. Returns true if it is,
37 // false otherwise.
38 static bool IsValidName(const std::string& name);
39
Austin Sullivan53755752022-03-03 02:31:2440 // This "file" is actually just an entry in a custom backend for CDM, uniquely
41 // identified by a storage key, CDM type, and file name. File operations are
42 // routed through `host` which is owned by the storage partition.
43 CdmFileImpl(
44 MediaLicenseStorageHost* host,
45 const media::CdmType& cdm_type,
46 const std::string& file_name,
47 mojo::PendingAssociatedReceiver<media::mojom::CdmFile> pending_receiver);
48
John Rummellaa05b9c2017-10-30 08:41:2949 CdmFileImpl(const std::string& file_name,
50 const url::Origin& origin,
Austin Sullivan22e0f3d2022-01-29 00:59:1751 const media::CdmType& cdm_type,
John Rummellaa05b9c2017-10-30 08:41:2952 const std::string& file_system_root_uri,
53 scoped_refptr<storage::FileSystemContext> file_system_context);
Peter Boström828b9022021-09-21 02:28:4354
55 CdmFileImpl(const CdmFileImpl&) = delete;
56 CdmFileImpl& operator=(const CdmFileImpl&) = delete;
57
John Rummellaa05b9c2017-10-30 08:41:2958 ~CdmFileImpl() final;
59
John Rummell9fcfaa72019-06-13 23:08:1260 // Called to grab a lock on the file. Returns false if the file is in use by
61 // other CDMs or by the system, true otherwise. Note that |this| should not
62 // be used anymore if Initialize() fails.
63 bool Initialize();
John Rummellaa05b9c2017-10-30 08:41:2964
John Rummell9fcfaa72019-06-13 23:08:1265 // media::mojom::CdmFile implementation.
66 void Read(ReadCallback callback) final;
67 void Write(const std::vector<uint8_t>& data, WriteCallback callback) final;
John Rummellaa05b9c2017-10-30 08:41:2968
69 private:
John Rummell137a6a52019-07-16 21:47:2270 class FileReader;
John Rummell879f96f2019-07-25 07:32:1471 class FileWriter;
John Rummellaa05b9c2017-10-30 08:41:2972
John Rummell137a6a52019-07-16 21:47:2273 // Called when the file is read. If |success| is true, |data| is the contents
74 // of the file read.
75 void ReadDone(bool success, std::vector<uint8_t> data);
John Rummell9fcfaa72019-06-13 23:08:1276
John Rummell879f96f2019-07-25 07:32:1477 // Called in sequence to write the file. |buffer| is the contents to be
78 // written to the file, |bytes_to_write| is the length. Uses |file_writer_|,
79 // which is cleared when no longer needed. |write_callback_| will always be
80 // called with the result.
John Rummell4894a802019-09-24 01:24:3181 void OnEnsureTempFileExists(scoped_refptr<net::IOBuffer> buffer,
82 int bytes_to_write,
83 base::File::Error result,
84 bool created);
85 void OnTempFileIsEmpty(scoped_refptr<net::IOBuffer> buffer,
86 int bytes_to_write,
87 base::File::Error result);
John Rummell879f96f2019-07-25 07:32:1488 void WriteDone(bool success);
89 void OnFileRenamed(base::File::Error move_result);
John Rummell9fcfaa72019-06-13 23:08:1290
91 // Deletes |file_name_| asynchronously.
John Rummell879f96f2019-07-25 07:32:1492 void DeleteFile();
93 void OnFileDeleted(base::File::Error result);
John Rummellaa05b9c2017-10-30 08:41:2994
95 // Returns the FileSystemURL for the specified |file_name|.
96 storage::FileSystemURL CreateFileSystemURL(const std::string& file_name);
97
98 // Helper methods to lock and unlock a file.
99 bool AcquireFileLock(const std::string& file_name);
John Rummellaa05b9c2017-10-30 08:41:29100 void ReleaseFileLock(const std::string& file_name);
101
John Rummelldc30ef532019-08-17 00:14:20102 // Report operation time to UMA.
103 void ReportFileOperationTimeUMA(const std::string& uma_name);
104
Austin Sullivan53755752022-03-03 02:31:24105 void ReadUsingMediaLicenseStorageDelegate();
106 void DidReadUsingMediaLicenseStorageDelegate(
107 absl::optional<std::vector<uint8_t>> data);
108 void WriteUsingMediaLicenseStorageDelegate(const std::vector<uint8_t>& data);
109 void DidWriteUsingMediaLicenseStorageDelegate(bool success);
110 void DeleteUsingMediaLicenseStorageDelegate();
111 void DidDeleteUsingMediaLicenseStorageDelegate(bool success);
112
113 void OnReceiverDisconnect();
114
115 // This receiver is associated with the CdmStorage receiver which creates it.
116 mojo::AssociatedReceiver<media::mojom::CdmFile> receiver_{this};
117
John Rummellaa05b9c2017-10-30 08:41:29118 // Names of the files this class represents.
119 const std::string file_name_;
120 const std::string temp_file_name_;
121
Austin Sullivan1fd07812021-12-15 02:43:28122 // TODO(crbug.com/1231162): Remove some of these fields and update this
123 // comment when we migrate off of the PluginPrivateFileSystem.
John Rummellaa05b9c2017-10-30 08:41:29124 // Files are stored in the PluginPrivateFileSystem. The following are needed
125 // to access files.
126 const url::Origin origin_;
Austin Sullivan22e0f3d2022-01-29 00:59:17127 const media::CdmType cdm_type_;
John Rummellaa05b9c2017-10-30 08:41:29128 const std::string file_system_root_uri_;
129 scoped_refptr<storage::FileSystemContext> file_system_context_;
130
John Rummell9fcfaa72019-06-13 23:08:12131 // Keep track of when the original file |file_name_| is locked.
132 // Initialize() can only be called if false and takes the lock (on success).
133 // Read() and Write() can only be called if true.
134 // Note that having a lock on |file_name| implies that |temp_file_name| is
135 // reserved for use by this object only, and an explicit lock on
136 // |temp_file_name| is not required.
137 bool file_locked_ = false;
John Rummellaa05b9c2017-10-30 08:41:29138
John Rummell137a6a52019-07-16 21:47:22139 // Used when reading the file. |file_reader_| lives on the IO thread.
140 ReadCallback read_callback_;
John Rummell879f96f2019-07-25 07:32:14141 base::SequenceBound<FileReader> file_reader_;
142
143 // Used when writing the file. |file_writer_| lives on the IO thread.
144 WriteCallback write_callback_;
145 base::SequenceBound<FileWriter> file_writer_;
John Rummellaa05b9c2017-10-30 08:41:29146
John Rummelldc30ef532019-08-17 00:14:20147 // Time when the read or write operation starts.
148 base::TimeTicks start_time_;
149
Austin Sullivan53755752022-03-03 02:31:24150 // Backing store which CDM file operations are routed through.
151 // Owned by MediaLicenseManager.
152 const raw_ptr<MediaLicenseStorageHost> host_ = nullptr;
153
John Rummellaa05b9c2017-10-30 08:41:29154 THREAD_CHECKER(thread_checker_);
Jeremy Roman3bca4bf2019-07-11 03:41:25155 base::WeakPtrFactory<CdmFileImpl> weak_factory_{this};
John Rummellaa05b9c2017-10-30 08:41:29156};
157
158} // namespace content
159
160#endif // CONTENT_BROWSER_MEDIA_CDM_FILE_IMPL_H_