OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef MEDIA_CDM_PPAPI_CDM_FILE_IO_IMPL_H_ | 5 #ifndef MEDIA_CDM_PPAPI_CDM_FILE_IO_IMPL_H_ |
6 #define MEDIA_CDM_PPAPI_CDM_FILE_IO_IMPL_H_ | 6 #define MEDIA_CDM_PPAPI_CDM_FILE_IO_IMPL_H_ |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "media/cdm/ppapi/api/content_decryption_module.h" | 13 #include "media/cdm/ppapi/api/content_decryption_module.h" |
14 #include "ppapi/c/ppb_file_io.h" | 14 #include "ppapi/c/ppb_file_io.h" |
15 #include "ppapi/cpp/file_io.h" | 15 #include "ppapi/cpp/file_io.h" |
16 #include "ppapi/cpp/file_ref.h" | 16 #include "ppapi/cpp/file_ref.h" |
17 #include "ppapi/cpp/instance.h" | 17 #include "ppapi/cpp/instance.h" |
18 #include "ppapi/cpp/module.h" | 18 #include "ppapi/cpp/module.h" |
19 #include "ppapi/cpp/private/isolated_file_system_private.h" | 19 #include "ppapi/cpp/private/isolated_file_system_private.h" |
20 #include "ppapi/utility/completion_callback_factory.h" | 20 #include "ppapi/utility/completion_callback_factory.h" |
21 | 21 |
22 namespace media { | 22 namespace media { |
23 | 23 |
24 // Due to PPAPI limitations, all functions must be called on the main thread. | 24 // Due to PPAPI limitations, all functions must be called on the main thread. |
| 25 // |
| 26 // Implementation notes about states: |
| 27 // 1, When a method is called in an invalid state (e.g. Read() before Open() is |
| 28 // called, Write() before Open() finishes or Open() after Open()), kError |
| 29 // will be returned. The state of |this| will not change. |
| 30 // 2, When the file is opened by another CDM instance, or when we call Read()/ |
| 31 // Write() during a pending Read()/Write(), kInUse will be returned. The |
| 32 // state of |this| will not change. |
| 33 // 3, When a pepper operation failed (either synchronously or asynchronously), |
| 34 // kError will be returned. The state of |this| will be set to ERROR. |
| 35 // 4. Any operation in ERROR state will end up with kError. |
25 class CdmFileIOImpl : public cdm::FileIO { | 36 class CdmFileIOImpl : public cdm::FileIO { |
26 public: | 37 public: |
27 // A class that helps release |file_lock_map_|. | 38 // A class that helps release |file_lock_map_|. |
28 // There should be only one instance of ResourceTracker in a process. Also, | 39 // There should be only one instance of ResourceTracker in a process. Also, |
29 // ResourceTracker should outlive all CdmFileIOImpl instances. | 40 // ResourceTracker should outlive all CdmFileIOImpl instances. |
30 class ResourceTracker { | 41 class ResourceTracker { |
31 public: | 42 public: |
32 ResourceTracker(); | 43 ResourceTracker(); |
33 ~ResourceTracker(); | 44 ~ResourceTracker(); |
34 private: | 45 private: |
35 DISALLOW_COPY_AND_ASSIGN(ResourceTracker); | 46 DISALLOW_COPY_AND_ASSIGN(ResourceTracker); |
36 }; | 47 }; |
37 | 48 |
38 // After the first successful file read, call |first_file_read_cb| to report | 49 // After the first successful file read, call |first_file_read_cb| to report |
39 // the file size. |first_file_read_cb| takes one parameter: the file size in | 50 // the file size. |first_file_read_cb| takes one parameter: the file size in |
40 // bytes. | 51 // bytes. |
41 CdmFileIOImpl(cdm::FileIOClient* client, | 52 CdmFileIOImpl(cdm::FileIOClient* client, |
42 PP_Instance pp_instance, | 53 PP_Instance pp_instance, |
43 const pp::CompletionCallback& first_file_read_cb); | 54 const pp::CompletionCallback& first_file_read_cb); |
44 | 55 |
45 // cdm::FileIO implementation. | 56 // cdm::FileIO implementation. |
46 virtual void Open(const char* file_name, uint32_t file_name_size) OVERRIDE; | 57 virtual void Open(const char* file_name, uint32_t file_name_size) OVERRIDE; |
47 virtual void Read() OVERRIDE; | 58 virtual void Read() OVERRIDE; |
48 virtual void Write(const uint8_t* data, uint32_t data_size) OVERRIDE; | 59 virtual void Write(const uint8_t* data, uint32_t data_size) OVERRIDE; |
49 virtual void Close() OVERRIDE; | 60 virtual void Close() OVERRIDE; |
50 | 61 |
51 private: | 62 private: |
| 63 // TODO(xhwang): Introduce more detailed states for UMA logging if needed. |
52 enum State { | 64 enum State { |
53 FILE_UNOPENED, | 65 STATE_UNOPENED, |
54 OPENING_FILE_SYSTEM, | 66 STATE_OPENING_FILE_SYSTEM, |
55 OPENING_FILE, | 67 STATE_FILE_SYSTEM_OPENED, |
56 FILE_OPENED, | 68 STATE_READING, |
57 READING_FILE, | 69 STATE_WRITING, |
58 WRITING_FILE, | 70 STATE_CLOSED, |
59 FILE_CLOSED | 71 STATE_ERROR |
60 }; | 72 }; |
61 | 73 |
62 enum ErrorType { | 74 enum ErrorType { |
63 OPEN_WHILE_IN_USE, | 75 OPEN_WHILE_IN_USE, |
64 READ_WHILE_IN_USE, | 76 READ_WHILE_IN_USE, |
65 WRITE_WHILE_IN_USE, | 77 WRITE_WHILE_IN_USE, |
66 OPEN_ERROR, | 78 OPEN_ERROR, |
67 READ_ERROR, | 79 READ_ERROR, |
68 WRITE_ERROR | 80 WRITE_ERROR |
69 }; | 81 }; |
(...skipping 29 matching lines...) Expand all Loading... |
99 | 111 |
100 // Acquires the file lock. Returns true if the lock is successfully acquired. | 112 // Acquires the file lock. Returns true if the lock is successfully acquired. |
101 // After the lock is acquired, other cdm::FileIO objects in the same process | 113 // After the lock is acquired, other cdm::FileIO objects in the same process |
102 // and in the same origin will get kInUse when trying to open the same file. | 114 // and in the same origin will get kInUse when trying to open the same file. |
103 bool AcquireFileLock(); | 115 bool AcquireFileLock(); |
104 | 116 |
105 // Releases the file lock so that the file can be opened by other cdm::FileIO | 117 // Releases the file lock so that the file can be opened by other cdm::FileIO |
106 // objects. | 118 // objects. |
107 void ReleaseFileLock(); | 119 void ReleaseFileLock(); |
108 | 120 |
| 121 // Helper functions for Open(). |
109 void OpenFileSystem(); | 122 void OpenFileSystem(); |
110 void OnFileSystemOpened(int32_t result, pp::FileSystem file_system); | 123 void OnFileSystemOpened(int32_t result, pp::FileSystem file_system); |
111 void OpenFile(); | 124 |
112 void OnFileOpened(int32_t result); | 125 // Helper functions for Read(). |
| 126 void OpenFileForRead(); |
| 127 void OnFileOpenedForRead(int32_t result); |
113 void ReadFile(); | 128 void ReadFile(); |
114 void OnFileRead(int32_t bytes_read); | 129 void OnFileRead(int32_t bytes_read); |
115 void SetLength(uint32_t length); | |
116 void OnLengthSet(int32_t result); | |
117 void WriteFile(); | |
118 void OnFileWritten(int32_t bytes_written); | |
119 | 130 |
120 void CloseFile(); | 131 // Helper functions for Write(). We always write data to a temporary file, |
| 132 // then rename the temporary file to the target file. This can prevent data |
| 133 // corruption if |this| is Close()'ed while waiting for writing to complete. |
| 134 // However, if Close() is called after OpenTempFileForWrite() but before |
| 135 // RenameTempFile(), we may still end up with an empty, partially written or |
| 136 // fully written temporary file in the file system. This temporary file will |
| 137 // be truncated next time OpenTempFileForWrite() is called. |
121 | 138 |
122 // Calls client_->OnXxxxComplete with kError asynchronously. In some cases we | 139 void OpenTempFileForWrite(); |
123 // could actually call them synchronously, but since these errors shouldn't | 140 void OnTempFileOpenedForWrite(int32_t result); |
124 // happen in normal cases, we are not optimizing such cases. | 141 void WriteTempFile(); |
| 142 void OnTempFileWritten(int32_t bytes_written); |
| 143 // Note: pp::FileRef::Rename() actually does a "move": if the target file |
| 144 // exists, Rename() will succeed and the target file will be overwritten. |
| 145 // See PepperInternalFileRefBackend::Rename() for implementation detail. |
| 146 void RenameTempFile(); |
| 147 void OnTempFileRenamed(int32_t result); |
| 148 |
| 149 // Reset |this| to a clean state. |
| 150 void Reset(); |
| 151 |
| 152 // For real open/read/write errors, Reset() and set the |state_| to ERROR. |
| 153 // Calls client_->OnXxxxComplete with kError or kInUse asynchronously. In some |
| 154 // cases we could actually call them synchronously, but since these errors |
| 155 // shouldn't happen in normal cases, we are not optimizing such cases. |
125 void OnError(ErrorType error_type); | 156 void OnError(ErrorType error_type); |
126 | 157 |
127 // Callback to notify client of error asynchronously. | 158 // Callback to notify client of error asynchronously. |
128 void NotifyClientOfError(int32_t result, ErrorType error_type); | 159 void NotifyClientOfError(int32_t result, ErrorType error_type); |
129 | 160 |
130 State state_; | 161 State state_; |
131 | 162 |
132 // Non-owning pointer. | 163 // Non-owning pointer. |
133 cdm::FileIOClient* const client_; | 164 cdm::FileIOClient* const client_; |
134 | 165 |
135 const pp::InstanceHandle pp_instance_handle_; | 166 const pp::InstanceHandle pp_instance_handle_; |
136 | 167 |
| 168 // Format: /<requested_file_name> |
137 std::string file_name_; | 169 std::string file_name_; |
138 | 170 |
139 // A string ID that uniquely identifies a file in the user's profile. | 171 // A string ID that uniquely identifies a file in the user's profile. |
140 // It consists of the origin of the document URL (including scheme, host and | 172 // It consists of the origin of the document URL (including scheme, host and |
141 // port, delimited by colons) and the |file_name_|. | 173 // port, delimited by colons) and the |file_name_|. |
142 // For example: http:example.com:8080/foo_file.txt | 174 // For example: http:example.com:8080/foo_file.txt |
143 std::string file_id_; | 175 std::string file_id_; |
144 | 176 |
145 pp::IsolatedFileSystemPrivate isolated_file_system_; | 177 pp::IsolatedFileSystemPrivate isolated_file_system_; |
146 pp::FileSystem file_system_; | 178 pp::FileSystem file_system_; |
| 179 |
| 180 // Shared between read and write. During read, |file_ref_| refers to the real |
| 181 // file to read data from. During write, it refers to the temporary file to |
| 182 // write data into. |
147 pp::FileIO file_io_; | 183 pp::FileIO file_io_; |
148 pp::FileRef file_ref_; | 184 pp::FileRef file_ref_; |
149 | 185 |
150 pp::CompletionCallbackFactory<CdmFileIOImpl> callback_factory_; | |
151 | |
152 // A temporary buffer to hold (partial) data to write or the data that has | 186 // A temporary buffer to hold (partial) data to write or the data that has |
153 // been read. The size of |io_buffer_| is always "bytes to write" or "bytes to | 187 // been read. The size of |io_buffer_| is always "bytes to write" or "bytes to |
154 // read". Use "char" instead of "unit8_t" because PPB_FileIO uses char* for | 188 // read". Use "char" instead of "unit8_t" because PPB_FileIO uses char* for |
155 // binary data read and write. | 189 // binary data read and write. |
156 std::vector<char> io_buffer_; | 190 std::vector<char> io_buffer_; |
157 | 191 |
158 // Offset into the file for reading/writing data. When writing data to the | 192 // Offset into the file for reading/writing data. When writing data to the |
159 // file, this is also the offset to the |io_buffer_|. | 193 // file, this is also the offset to the |io_buffer_|. |
160 size_t io_offset_; | 194 size_t io_offset_; |
161 | 195 |
162 // Buffer to hold all read data requested. This buffer is passed to |client_| | 196 // Buffer to hold all read data requested. This buffer is passed to |client_| |
163 // when read completes. | 197 // when read completes. |
164 std::vector<char> cumulative_read_buffer_; | 198 std::vector<char> cumulative_read_buffer_; |
165 | 199 |
166 bool first_file_read_reported_; | 200 bool first_file_read_reported_; |
167 | 201 |
168 // Callback to report the file size in bytes after the first successful read. | 202 // Callback to report the file size in bytes after the first successful read. |
169 pp::CompletionCallback first_file_read_cb_; | 203 pp::CompletionCallback first_file_read_cb_; |
170 | 204 |
| 205 pp::CompletionCallbackFactory<CdmFileIOImpl> callback_factory_; |
| 206 |
171 DISALLOW_COPY_AND_ASSIGN(CdmFileIOImpl); | 207 DISALLOW_COPY_AND_ASSIGN(CdmFileIOImpl); |
172 }; | 208 }; |
173 | 209 |
174 } // namespace media | 210 } // namespace media |
175 | 211 |
176 #endif // MEDIA_CDM_PPAPI_CDM_FILE_IO_IMPL_H_ | 212 #endif // MEDIA_CDM_PPAPI_CDM_FILE_IO_IMPL_H_ |
OLD | NEW |