Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: media/cdm/ppapi/cdm_file_io_impl.h

Issue 545983005: CdmFileIOImpl: Refactor Write() implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments addressed Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | media/cdm/ppapi/cdm_file_io_impl.cc » ('j') | media/cdm/ppapi/cdm_file_io_test.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_
OLDNEW
« no previous file with comments | « no previous file | media/cdm/ppapi/cdm_file_io_impl.cc » ('j') | media/cdm/ppapi/cdm_file_io_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698