| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium OS 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 VOLUME_H_ | |
| 6 #define VOLUME_H_ | |
| 7 | |
| 8 #include <pthread.h> | |
| 9 | |
| 10 #include "archive.h" | |
| 11 #include "ppapi/cpp/instance_handle.h" | |
| 12 #include "ppapi/cpp/var_array_buffer.h" | |
| 13 #include "ppapi/cpp/var_dictionary.h" | |
| 14 #include "ppapi/utility/completion_callback_factory.h" | |
| 15 #include "ppapi/utility/threading/lock.h" | |
| 16 #include "ppapi/utility/threading/simple_thread.h" | |
| 17 | |
| 18 #include "javascript_requestor_interface.h" | |
| 19 #include "javascript_message_sender_interface.h" | |
| 20 #include "volume_archive.h" | |
| 21 | |
| 22 // A factory that creates VolumeArchive(s). Useful for testing. | |
| 23 class VolumeArchiveFactoryInterface { | |
| 24 public: | |
| 25 virtual ~VolumeArchiveFactoryInterface() {} | |
| 26 | |
| 27 // Creates a new VolumeArchive. | |
| 28 virtual VolumeArchive* Create(VolumeReader* reader) = 0; | |
| 29 }; | |
| 30 | |
| 31 // A factory that creates VolumeReader(s). Useful for testing. | |
| 32 class VolumeReaderFactoryInterface { | |
| 33 public: | |
| 34 virtual ~VolumeReaderFactoryInterface() {} | |
| 35 | |
| 36 // Creates a new VolumeReader. Returns NULL if failed. | |
| 37 // Passes VolumeReader ownership to the implementation of | |
| 38 // VolumeArchiveInterfaceInterface. | |
| 39 virtual VolumeReader* Create(int64_t archive_size) = 0; | |
| 40 }; | |
| 41 | |
| 42 // Handles all operations like reading metadata and reading files from a single | |
| 43 // Volume. | |
| 44 class Volume { | |
| 45 public: | |
| 46 Volume(const pp::InstanceHandle& instance_handle /* Used for workers. */, | |
| 47 const std::string& file_system_id, | |
| 48 JavaScriptMessageSenderInterface* message_sender); | |
| 49 | |
| 50 // Used by tests to create custom VolumeArchive and VolumeReader objects. | |
| 51 // VolumeArchiveFactory and VolumeReaderFactory should be allocated with new | |
| 52 // and the ownership will be passed to Volume on constructing it. | |
| 53 Volume(const pp::InstanceHandle& instance_handle /* Used for workers. */, | |
| 54 const std::string& file_system_id, | |
| 55 JavaScriptMessageSenderInterface* message_sender, | |
| 56 VolumeArchiveFactoryInterface* volume_archive_factory, | |
| 57 VolumeReaderFactoryInterface* volume_reader_factory); | |
| 58 | |
| 59 virtual ~Volume(); | |
| 60 | |
| 61 // Initializes the volume. | |
| 62 bool Init(); | |
| 63 | |
| 64 // Reads archive metadata using libarchive. | |
| 65 void ReadMetadata(const std::string& request_id, | |
| 66 const std::string& encoding, | |
| 67 int64_t archive_size); | |
| 68 | |
| 69 // Processes a successful archive chunk read from JavaScript. Read offset | |
| 70 // represents the offset from where the data contained in array_buffer starts. | |
| 71 void ReadChunkDone(const std::string& nacl_request_id, | |
| 72 const pp::VarArrayBuffer& array_buffer, | |
| 73 int64_t read_offset); | |
| 74 | |
| 75 // Processes an invalid archive chunk read from JavaScript. | |
| 76 void ReadChunkError(const std::string& nacl_request_id); | |
| 77 | |
| 78 // Processes a successful passphrase read from JavaScript. | |
| 79 void ReadPassphraseDone(const std::string& nacl_request_id, | |
| 80 const std::string& passphrase); | |
| 81 | |
| 82 // Processes an error when requesting a passphrase from JavaScript. | |
| 83 void ReadPassphraseError(const std::string& nacl_request_id); | |
| 84 | |
| 85 // Opens a file. | |
| 86 void OpenFile(const std::string& request_id, | |
| 87 int64_t index, | |
| 88 const std::string& encoding, | |
| 89 int64_t archive_size); | |
| 90 | |
| 91 // Closes a file. | |
| 92 void CloseFile(const std::string& request_id, | |
| 93 const std::string& open_request_id); | |
| 94 | |
| 95 // Reads a file contents from offset to offset + length. dictionary | |
| 96 // should contain the open_request_id, the offset and the length with | |
| 97 // the keys as defined in "request" namespace, and they should have | |
| 98 // valid types. The reason for not passing them directly is that | |
| 99 // pp::CompletionCallbackFactory can create a callback with a maximum of | |
| 100 // 3 parameters, not 4 as needed here (including request_id). | |
| 101 void ReadFile(const std::string& request_id, | |
| 102 const pp::VarDictionary& dictionary); | |
| 103 | |
| 104 JavaScriptMessageSenderInterface* message_sender() { return message_sender_; } | |
| 105 JavaScriptRequestorInterface* requestor() { return requestor_; } | |
| 106 std::string file_system_id() { return file_system_id_; } | |
| 107 | |
| 108 private: | |
| 109 // Encapsulates arguments to OpenFileCallback, as NewCallback supports binding | |
| 110 // up to three arguments, while here we have four. | |
| 111 struct OpenFileArgs; | |
| 112 | |
| 113 // A callback helper for ReadMetadata. | |
| 114 void ReadMetadataCallback(int32_t result, | |
| 115 const std::string& request_id, | |
| 116 const std::string& encoding, | |
| 117 int64_t archive_size); | |
| 118 | |
| 119 // A calback helper for OpenFile. | |
| 120 void OpenFileCallback(int32_t result, | |
| 121 const OpenFileArgs& args); | |
| 122 | |
| 123 // A callback helper for CloseFile. | |
| 124 void CloseFileCallback(int32_t result, | |
| 125 const std::string& request_id, | |
| 126 const std::string& open_request_id); | |
| 127 | |
| 128 // A calback helper for ReadFile. | |
| 129 void ReadFileCallback(int32_t result, | |
| 130 const std::string& request_id, | |
| 131 const pp::VarDictionary& dictionary); | |
| 132 | |
| 133 // Creates a new archive object for this volume. | |
| 134 VolumeArchive* CreateVolumeArchive(const std::string& request_id, | |
| 135 const std::string& encoding, | |
| 136 int64_t archive_size); | |
| 137 | |
| 138 // Clears job. | |
| 139 void ClearJob(); | |
| 140 | |
| 141 // Libarchive wrapper instance per volume, shared across all operations. | |
| 142 VolumeArchive* volume_archive_; | |
| 143 | |
| 144 // The file system id for this volume. | |
| 145 std::string file_system_id_; | |
| 146 | |
| 147 // An object that sends messages to JavaScript. | |
| 148 JavaScriptMessageSenderInterface* message_sender_; | |
| 149 | |
| 150 // A worker for jobs that require blocking operations or a lot of processing | |
| 151 // time. Those shouldn't be done on the main thread. The jobs submitted to | |
| 152 // this thread are executed in order, so a new job must wait for the last job | |
| 153 // to finish. | |
| 154 // TODO(cmihail): Consider using multiple workers in case of many jobs to | |
| 155 // improve execution speedup. In case multiple workers are added | |
| 156 // synchronization between workers might be needed. | |
| 157 pp::SimpleThread worker_; | |
| 158 | |
| 159 // Callback factory used to submit jobs to worker_. | |
| 160 // See "Detailed Description" Note at: | |
| 161 // https://developer.chrome.com/native-client/ | |
| 162 // pepper_dev/cpp/classpp_1_1_completion_callback_factory | |
| 163 // | |
| 164 // As a minus this would require ugly synchronization between the main thread | |
| 165 // and the function that is executed on worker_ construction. Current | |
| 166 // implementation is simimlar to examples in $NACL_SDK_ROOT and according to | |
| 167 // https://chromiumcodereview.appspot.com/lint_patch/issue10790078_24001_25013 | |
| 168 // it should be safe (see TODO(dmichael)). That's because both worker_ and | |
| 169 // callback_factory_ will be alive during the life of Volume and deleting a | |
| 170 // Volume is permitted only if there are no requests in progress on | |
| 171 // JavaScript side (this means no Callbacks in progress). | |
| 172 pp::CompletionCallbackFactory<Volume> callback_factory_; | |
| 173 | |
| 174 // Request ID of the current reader instance. | |
| 175 std::string reader_request_id_; | |
| 176 | |
| 177 pp::Lock job_lock_; // A lock for guarding members related to jobs. | |
| 178 | |
| 179 // A requestor for making calls to JavaScript. | |
| 180 JavaScriptRequestorInterface* requestor_; | |
| 181 | |
| 182 // A factory for creating VolumeArchive. | |
| 183 VolumeArchiveFactoryInterface* volume_archive_factory_; | |
| 184 | |
| 185 // A factory for creating VolumeReader. | |
| 186 VolumeReaderFactoryInterface* volume_reader_factory_; | |
| 187 }; | |
| 188 | |
| 189 #endif /// VOLUME_H_ | |
| OLD | NEW |