diff options
author | hamaji@chromium.org <hamaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-01 16:51:13 +0000 |
---|---|---|
committer | hamaji@chromium.org <hamaji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-01 16:51:13 +0000 |
commit | 8f96cef7e737970b9e16c97de788daaa5fb3181a (patch) | |
tree | 31887c9690fdc4ae20edb89f94745bc2310b665a /ppapi | |
parent | 0b4468ed16cf93bac23d5abf3ef39e400665d694 (diff) | |
download | chromium_src-8f96cef7e737970b9e16c97de788daaa5fb3181a.zip chromium_src-8f96cef7e737970b9e16c97de788daaa5fb3181a.tar.gz chromium_src-8f96cef7e737970b9e16c97de788daaa5fb3181a.tar.bz2 |
Unlike GetOSFileDescriptor, this API is asynchronous.
Both GetOSFileDescriptor and RequestOSFileHandle use GetOSFileDescriptor
chrome IPC for now. I'm planning to remove call sites of
GetOSFileDescriptor PPAPI and rename GetOSFileDescriptor chrome IPC to
RequestOSFileHandle.
- Add --allow-get-os-file-handle-api. With this flag,
1. browser_tests can test this API and 2. we can use this API even
before this issue is resolved: http://crbug.com/224123
- Add TestRequestOSFileHandle in FileIO. This checks if read, write,
lseek, and mmap work for FD fetched by this API.
- PepperFileIOHost::OnHostMsgGetOSFileDescriptor use
ShareHandleWithRemote to pass a file handle
- Fix ShareHandleWithRemote for in-process API
BUG=183015
TEST=trybots, browser_tests
Review URL: https://chromiumcodereview.appspot.com/13032002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191616 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/api/private/ppb_file_io_private.idl | 26 | ||||
-rw-r--r-- | ppapi/api/trusted/ppb_file_io_trusted.idl | 2 | ||||
-rw-r--r-- | ppapi/c/pp_macros.h | 4 | ||||
-rw-r--r-- | ppapi/c/private/ppb_file_io_private.h | 49 | ||||
-rw-r--r-- | ppapi/c/trusted/ppb_file_io_trusted.h | 4 | ||||
-rw-r--r-- | ppapi/cpp/private/file_io_private.cc | 39 | ||||
-rw-r--r-- | ppapi/cpp/private/file_io_private.h | 42 | ||||
-rw-r--r-- | ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c | 23 | ||||
-rw-r--r-- | ppapi/ppapi_shared.gypi | 1 | ||||
-rw-r--r-- | ppapi/ppapi_sources.gypi | 2 | ||||
-rw-r--r-- | ppapi/proxy/file_io_resource.cc | 41 | ||||
-rw-r--r-- | ppapi/proxy/file_io_resource.h | 9 | ||||
-rw-r--r-- | ppapi/proxy/interface_list.cc | 1 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 2 | ||||
-rw-r--r-- | ppapi/tests/all_c_includes.h | 1 | ||||
-rw-r--r-- | ppapi/tests/test_file_io.cc | 130 | ||||
-rw-r--r-- | ppapi/tests/test_file_io.h | 1 | ||||
-rw-r--r-- | ppapi/thunk/interfaces_ppb_private_no_permissions.h | 3 | ||||
-rw-r--r-- | ppapi/thunk/ppb_file_io_api.h | 6 | ||||
-rw-r--r-- | ppapi/thunk/ppb_file_io_private_thunk.cc | 44 |
20 files changed, 425 insertions, 5 deletions
diff --git a/ppapi/api/private/ppb_file_io_private.idl b/ppapi/api/private/ppb_file_io_private.idl new file mode 100644 index 0000000..38b2339 --- /dev/null +++ b/ppapi/api/private/ppb_file_io_private.idl @@ -0,0 +1,26 @@ +/* Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#inline c +#include "ppapi/c/private/pp_file_handle.h" +#endinl + +/* This file contains the <code>PPB_FileIO_Private</code> interface. */ +label Chrome { + M28 = 0.1 +}; + +/* PPB_FileIO_Private interface */ +interface PPB_FileIO_Private { + /** + * Returns a file handle corresponding to the given FileIO + * object. The FileIO object must have been opened with a + * successful call to FileIO::Open. The caller gets the ownership + * of the returned file handle and must close it. + */ + int32_t RequestOSFileHandle([in] PP_Resource file_io, + [out] PP_FileHandle handle, + [in] PP_CompletionCallback callback); +}; diff --git a/ppapi/api/trusted/ppb_file_io_trusted.idl b/ppapi/api/trusted/ppb_file_io_trusted.idl index 1ee03ab..7ba20de 100644 --- a/ppapi/api/trusted/ppb_file_io_trusted.idl +++ b/ppapi/api/trusted/ppb_file_io_trusted.idl @@ -19,6 +19,8 @@ interface PPB_FileIOTrusted { * descriptor. The FileIO object must have been opened with a successful * call to FileIO::Open. The file descriptor will be closed automatically * when the FileIO object is closed or destroyed. + * + * TODO(hamaji): Remove this and use RequestOSFileHandle instead. */ int32_t GetOSFileDescriptor([in] PP_Resource file_io); diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h index 83f85d6..6179380 100644 --- a/ppapi/c/pp_macros.h +++ b/ppapi/c/pp_macros.h @@ -3,13 +3,13 @@ * found in the LICENSE file. */ -/* From pp_macros.idl modified Fri Feb 15 16:46:46 2013. */ +/* From pp_macros.idl modified Tue Mar 19 12:29:49 2013. */ #ifndef PPAPI_C_PP_MACROS_H_ #define PPAPI_C_PP_MACROS_H_ -#define PPAPI_RELEASE 27 +#define PPAPI_RELEASE 28 /** * @file diff --git a/ppapi/c/private/ppb_file_io_private.h b/ppapi/c/private/ppb_file_io_private.h new file mode 100644 index 0000000..cdbbae7 --- /dev/null +++ b/ppapi/c/private/ppb_file_io_private.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* From private/ppb_file_io_private.idl modified Wed Mar 27 14:43:25 2013. */ + +#ifndef PPAPI_C_PRIVATE_PPB_FILE_IO_PRIVATE_H_ +#define PPAPI_C_PRIVATE_PPB_FILE_IO_PRIVATE_H_ + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_stdint.h" + +#define PPB_FILEIO_PRIVATE_INTERFACE_0_1 "PPB_FileIO_Private;0.1" +#define PPB_FILEIO_PRIVATE_INTERFACE PPB_FILEIO_PRIVATE_INTERFACE_0_1 + +/** + * @file + */ + + +#include "ppapi/c/private/pp_file_handle.h" + +/** + * @addtogroup Interfaces + * @{ + */ +/* PPB_FileIO_Private interface */ +struct PPB_FileIO_Private_0_1 { + /** + * Returns a file handle corresponding to the given FileIO + * object. The FileIO object must have been opened with a + * successful call to FileIO::Open. The caller gets the ownership + * of the returned file handle and must close it. + */ + int32_t (*RequestOSFileHandle)(PP_Resource file_io, + PP_FileHandle* handle, + struct PP_CompletionCallback callback); +}; + +typedef struct PPB_FileIO_Private_0_1 PPB_FileIO_Private; +/** + * @} + */ + +#endif /* PPAPI_C_PRIVATE_PPB_FILE_IO_PRIVATE_H_ */ + diff --git a/ppapi/c/trusted/ppb_file_io_trusted.h b/ppapi/c/trusted/ppb_file_io_trusted.h index 53953fbd..8e05589 100644 --- a/ppapi/c/trusted/ppb_file_io_trusted.h +++ b/ppapi/c/trusted/ppb_file_io_trusted.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From trusted/ppb_file_io_trusted.idl modified Wed Oct 5 14:06:02 2011. */ +/* From trusted/ppb_file_io_trusted.idl modified Wed Mar 27 14:50:12 2013. */ #ifndef PPAPI_C_TRUSTED_PPB_FILE_IO_TRUSTED_H_ #define PPAPI_C_TRUSTED_PPB_FILE_IO_TRUSTED_H_ @@ -35,6 +35,8 @@ struct PPB_FileIOTrusted_0_4 { * descriptor. The FileIO object must have been opened with a successful * call to FileIO::Open. The file descriptor will be closed automatically * when the FileIO object is closed or destroyed. + * + * TODO(hamaji): Remove this and use RequestOSFileHandle instead. */ int32_t (*GetOSFileDescriptor)(PP_Resource file_io); /** diff --git a/ppapi/cpp/private/file_io_private.cc b/ppapi/cpp/private/file_io_private.cc new file mode 100644 index 0000000..1479348 --- /dev/null +++ b/ppapi/cpp/private/file_io_private.cc @@ -0,0 +1,39 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/private/file_io_private.h" + +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_file_io_private.h" +#include "ppapi/cpp/file_io.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +template <> const char* interface_name<PPB_FileIO_Private>() { + return PPB_FILEIO_PRIVATE_INTERFACE_0_1; +} + +} // namespace + +FileIO_Private::FileIO_Private() + : FileIO() { +} + +FileIO_Private::FileIO_Private(const InstanceHandle& instance) + : FileIO(instance) { +} + +int32_t FileIO_Private::RequestOSFileHandle(PP_FileHandle* result_handle, + const CompletionCallback& cc) { + *result_handle = PP_kInvalidFileHandle; + if (has_interface<PPB_FileIO_Private>()) + return get_interface<PPB_FileIO_Private>()->RequestOSFileHandle( + pp_resource(), result_handle, cc.pp_completion_callback()); + return cc.MayForce(PP_ERROR_NOINTERFACE); +} + +} // namespace pp diff --git a/ppapi/cpp/private/file_io_private.h b/ppapi/cpp/private/file_io_private.h new file mode 100644 index 0000000..c291be5 --- /dev/null +++ b/ppapi/cpp/private/file_io_private.h @@ -0,0 +1,42 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_CPP_PRIVATE_FILE_IO_PRIVATE_H_ +#define PPAPI_CPP_PRIVATE_FILE_IO_PRIVATE_H_ + +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/private/pp_file_handle.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/file_io.h" + +namespace pp { + +class FileIO; + +class FileIO_Private : public FileIO { + public: + FileIO_Private(); + explicit FileIO_Private(const InstanceHandle& instance); + + // This interface may leak the memory and file handle if the factory + // of |cc| is destructed. We need to use + // CompletionCallbackWithOutput to prevent the memory leak and + // create something like PassFileHandle to prevent the handle leak. + // See https://codereview.chromium.org/13032002/#ps33001 + // + // Currently, TestCompletionCallbackWithOutput won't work for non + // vector types, so we should fix it first. + // http://crbug.com/224741 + // + // Meanwhile, this interface should be used only from tests and + // other code should use the C interface of this API. + // + // TODO(hamaji): Fix. http://crbug.com/224745 + int32_t RequestOSFileHandle(PP_FileHandle* result_handle, + const CompletionCallback& cc); +}; + +} // namespace pp + +#endif // PPAPI_CPP_PRIVATE_FILE_IO_PRIVATE_H_ diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index 758cb52..4f76f47 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -77,6 +77,7 @@ #include "ppapi/c/ppp_messaging.h" #include "ppapi/c/ppp_mouse_lock.h" #include "ppapi/c/private/ppb_content_decryptor_private.h" +#include "ppapi/c/private/ppb_file_io_private.h" #include "ppapi/c/private/ppb_file_ref_private.h" #include "ppapi/c/private/ppb_flash.h" #include "ppapi/c/private/ppb_flash_clipboard.h" @@ -233,6 +234,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_VideoDecoder_Dev_0_11; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Widget_Dev_0_2; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Zoom_Dev_0_3; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_6; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileIO_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Flash_12_4; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Flash_12_5; @@ -2429,6 +2431,16 @@ void Pnacl_M24_PPB_ContentDecryptor_Private_DeliverSamples(PP_Instance instance, /* End wrapper methods for PPB_ContentDecryptor_Private_0_6 */ +/* Begin wrapper methods for PPB_FileIO_Private_0_1 */ + +static __attribute__((pnaclcall)) +int32_t Pnacl_M28_PPB_FileIO_Private_RequestOSFileHandle(PP_Resource file_io, PP_FileHandle* handle, struct PP_CompletionCallback callback) { + const struct PPB_FileIO_Private_0_1 *iface = Pnacl_WrapperInfo_PPB_FileIO_Private_0_1.real_iface; + return iface->RequestOSFileHandle(file_io, handle, callback); +} + +/* End wrapper methods for PPB_FileIO_Private_0_1 */ + /* Begin wrapper methods for PPB_FileRefPrivate_0_1 */ static __attribute__((pnaclcall)) @@ -4356,6 +4368,10 @@ struct PPB_ContentDecryptor_Private_0_6 Pnacl_Wrappers_PPB_ContentDecryptor_Priv .DeliverSamples = (void (*)(PP_Instance instance, PP_Resource audio_frames, const struct PP_DecryptedBlockInfo* decrypted_block_info))&Pnacl_M24_PPB_ContentDecryptor_Private_DeliverSamples }; +struct PPB_FileIO_Private_0_1 Pnacl_Wrappers_PPB_FileIO_Private_0_1 = { + .RequestOSFileHandle = (int32_t (*)(PP_Resource file_io, PP_FileHandle* handle, struct PP_CompletionCallback callback))&Pnacl_M28_PPB_FileIO_Private_RequestOSFileHandle +}; + struct PPB_FileRefPrivate_0_1 Pnacl_Wrappers_PPB_FileRefPrivate_0_1 = { .GetAbsolutePath = (struct PP_Var (*)(PP_Resource file_ref))&Pnacl_M15_PPB_FileRefPrivate_GetAbsolutePath }; @@ -5281,6 +5297,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_ .real_iface = NULL }; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileIO_Private_0_1 = { + .iface_macro = PPB_FILEIO_PRIVATE_INTERFACE_0_1, + .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_FileIO_Private_0_1, + .real_iface = NULL +}; + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1 = { .iface_macro = PPB_FILEREFPRIVATE_INTERFACE_0_1, .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_FileRefPrivate_0_1, @@ -5606,6 +5628,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { &Pnacl_WrapperInfo_PPB_Widget_Dev_0_4, &Pnacl_WrapperInfo_PPB_Zoom_Dev_0_2, &Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_6, + &Pnacl_WrapperInfo_PPB_FileIO_Private_0_1, &Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1, &Pnacl_WrapperInfo_PPB_Flash_12_4, &Pnacl_WrapperInfo_PPB_Flash_12_5, diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index e69c2c7..3b39112 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -160,6 +160,7 @@ 'thunk/ppb_file_chooser_dev_thunk.cc', 'thunk/ppb_file_chooser_trusted_thunk.cc', 'thunk/ppb_file_io_api.h', + 'thunk/ppb_file_io_private_thunk.cc', 'thunk/ppb_file_io_thunk.cc', 'thunk/ppb_file_io_trusted_thunk.cc', 'thunk/ppb_file_ref_api.h', diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi index 3669be6..cf01f08 100644 --- a/ppapi/ppapi_sources.gypi +++ b/ppapi/ppapi_sources.gypi @@ -273,6 +273,8 @@ # Private interfaces. 'cpp/private/content_decryptor_private.cc', 'cpp/private/content_decryptor_private.h', + 'cpp/private/file_io_private.cc', + 'cpp/private/file_io_private.h', 'cpp/private/flash.cc', 'cpp/private/flash.h', 'cpp/private/flash_clipboard.cc', diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc index 77105a1..7d98356 100644 --- a/ppapi/proxy/file_io_resource.cc +++ b/ppapi/proxy/file_io_resource.cc @@ -224,6 +224,23 @@ int32_t FileIOResource::ReadValidated(int64_t offset, return PP_OK_COMPLETIONPENDING; } +int32_t FileIOResource::RequestOSFileHandle( + PP_FileHandle* handle, + scoped_refptr<TrackedCallback> callback) { + int32_t rv = state_manager_.CheckOperationState( + FileIOStateManager::OPERATION_EXCLUSIVE, true); + if (rv != PP_OK) + return rv; + + Call<PpapiPluginMsg_FileIO_RequestOSFileHandleReply>(RENDERER, + PpapiHostMsg_FileIO_RequestOSFileHandle(), + base::Bind(&FileIOResource::OnPluginMsgRequestOSFileHandleComplete, this, + callback, handle)); + + state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); + return PP_OK_COMPLETIONPENDING; +} + void FileIOResource::OnPluginMsgGeneralComplete( scoped_refptr<TrackedCallback> callback, const ResourceMessageReplyParams& params) { @@ -286,6 +303,28 @@ void FileIOResource::OnPluginMsgReadComplete( callback->Run(result); } +void FileIOResource::OnPluginMsgRequestOSFileHandleComplete( + scoped_refptr<TrackedCallback> callback, + PP_FileHandle* output_handle, + const ResourceMessageReplyParams& params) { + DCHECK(state_manager_.get_pending_operation() == + FileIOStateManager::OPERATION_EXCLUSIVE); + + if (!TrackedCallback::IsPending(callback)) { + state_manager_.SetOperationFinished(); + return; + } + + int32_t result = params.result(); + IPC::PlatformFileForTransit transit_file; + if (!params.TakeFileHandleAtIndex(0, &transit_file)) + result = PP_ERROR_FAILED; + *output_handle = IPC::PlatformFileForTransitToPlatformFile(transit_file); + + // End the operation now. The callback may perform another file operation. + state_manager_.SetOperationFinished(); + callback->Run(result); +} + } // namespace proxy } // namespace ppapi - diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h index f5a1aa8..a2b928d 100644 --- a/ppapi/proxy/file_io_resource.h +++ b/ppapi/proxy/file_io_resource.h @@ -7,6 +7,7 @@ #include <string> +#include "ppapi/c/private/pp_file_handle.h" #include "ppapi/proxy/connection.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_proxy_export.h" @@ -55,6 +56,9 @@ class PPAPI_PROXY_EXPORT FileIOResource virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual void Close() OVERRIDE; virtual int32_t GetOSFileDescriptor() OVERRIDE; + virtual int32_t RequestOSFileHandle( + PP_FileHandle* handle, + scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual int32_t WillWrite(int64_t offset, int32_t bytes_to_write, scoped_refptr<TrackedCallback> callback) OVERRIDE; @@ -82,6 +86,10 @@ class PPAPI_PROXY_EXPORT FileIOResource PP_ArrayOutput array_output, const ResourceMessageReplyParams& params, const std::string& data); + void OnPluginMsgRequestOSFileHandleComplete( + scoped_refptr<TrackedCallback> callback, + PP_FileHandle* output_handle, + const ResourceMessageReplyParams& params); FileIOStateManager state_manager_; @@ -92,4 +100,3 @@ class PPAPI_PROXY_EXPORT FileIOResource } // namespace ppapi #endif // PPAPI_PROXY_FILE_IO_RESOURCE_H_ - diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index 5950061..1e6bbfb 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -58,6 +58,7 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppp_instance.h" #include "ppapi/c/private/ppb_content_decryptor_private.h" +#include "ppapi/c/private/ppb_file_io_private.h" #include "ppapi/c/private/ppb_file_ref_private.h" #include "ppapi/c/private/ppb_flash_clipboard.h" #include "ppapi/c/private/ppb_flash_file.h" diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index eb921d9..eb87994 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1393,6 +1393,8 @@ IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_WillSetLength, IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_GetOSFileDescriptor) IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileIO_GetOSFileDescriptorReply, int32_t /* file descriptor */) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_RequestOSFileHandle) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_RequestOSFileHandleReply) IPC_MESSAGE_CONTROL0(PpapiPluginMsg_FileIO_GeneralReply) // Flash device ID. diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h index 51afbb4..3def529 100644 --- a/ppapi/tests/all_c_includes.h +++ b/ppapi/tests/all_c_includes.h @@ -97,6 +97,7 @@ #include "ppapi/c/ppp_mouse_lock.h" #include "ppapi/c/private/pp_private_font_charset.h" #include "ppapi/c/private/ppb_content_decryptor_private.h" +#include "ppapi/c/private/ppb_file_io_private.h" #include "ppapi/c/private/ppb_flash.h" #include "ppapi/c/private/ppb_flash_clipboard.h" #include "ppapi/c/private/ppb_flash_font_file.h" diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc index 29348a6..b9cfe5f 100644 --- a/ppapi/tests/test_file_io.cc +++ b/ppapi/tests/test_file_io.cc @@ -4,22 +4,41 @@ #include "ppapi/tests/test_file_io.h" +#include <errno.h> +#include <fcntl.h> #include <string.h> +#include <sys/stat.h> +#include <sys/types.h> #include <vector> #include "ppapi/c/dev/ppb_testing_dev.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/private/pp_file_handle.h" #include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/cpp/file_io.h" #include "ppapi/cpp/file_ref.h" #include "ppapi/cpp/file_system.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" +#include "ppapi/cpp/private/file_io_private.h" #include "ppapi/tests/test_utils.h" #include "ppapi/tests/testing_instance.h" +#if defined(PPAPI_OS_WIN) +# include <io.h> +# include <windows.h> +// TODO(hamaji): Use standard windows APIs instead of compatibility layer? +# define lseek _lseek +# define read _read +# define write _write +# define ssize_t int +#else +# include <sys/mman.h> +# include <unistd.h> +#endif + REGISTER_TEST_CASE(FileIO); namespace { @@ -148,6 +167,7 @@ void TestFileIO::RunTests(const std::string& filter) { RUN_TEST_FORCEASYNC_AND_NOT(ParallelWrites, filter); RUN_TEST_FORCEASYNC_AND_NOT(NotAllowMixedReadWrite, filter); RUN_TEST_FORCEASYNC_AND_NOT(WillWriteWillSetLength, filter); + RUN_TEST_FORCEASYNC_AND_NOT(RequestOSFileHandle, filter); // TODO(viettrungluu): add tests: // - that PP_ERROR_PENDING is correctly returned @@ -1248,6 +1268,116 @@ std::string TestFileIO::TestWillWriteWillSetLength() { PASS(); } +std::string TestFileIO::TestRequestOSFileHandle() { + TestCompletionCallback callback(instance_->pp_instance(), callback_type()); + + pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); + pp::FileRef file_ref(file_system, "/file_os_fd"); + + callback.WaitForResult(file_system.Open(1024, callback.GetCallback())); + if (callback.result() != PP_OK) + return ReportError("FileSystem::Open", callback.result()); + + pp::FileIO_Private file_io(instance_); + callback.WaitForResult(file_io.Open(file_ref, + PP_FILEOPENFLAG_CREATE | + PP_FILEOPENFLAG_TRUNCATE | + PP_FILEOPENFLAG_READ | + PP_FILEOPENFLAG_WRITE, + callback.GetCallback())); + if (callback.result() != PP_OK) + return ReportError("FileIO::Open", callback.result()); + + PP_FileHandle handle = PP_kInvalidFileHandle; + callback.WaitForResult( + file_io.RequestOSFileHandle(&handle, callback.GetCallback())); + if (callback.result() != PP_OK) + return ReportError("FileIO::RequestOSFileHandle", callback.result()); + + if (handle == PP_kInvalidFileHandle) + return "FileIO::RequestOSFileHandle() returned a bad file handle."; +#if defined(PPAPI_OS_WIN) + int fd = _open_osfhandle(reinterpret_cast<intptr_t>(handle), + _O_RDWR | _O_BINARY); +#else + int fd = handle; +#endif + if (fd < 0) + return "FileIO::RequestOSFileHandle() returned a bad file descriptor."; + + // Check write(2) for the native FD. + const std::string msg = "foobar"; + ssize_t cnt = write(fd, msg.data(), msg.size()); + if (cnt < 0) + return ReportError("write for native FD returned error", errno); + if (cnt != static_cast<ssize_t>(msg.size())) + return ReportError("write for native FD count mismatch", cnt); + + // Check lseek(2) for the native FD. + off_t off = lseek(fd, 0, SEEK_CUR); + if (off == static_cast<off_t>(-1)) + return ReportError("lseek for native FD returned error", errno); + if (off != static_cast<off_t>(msg.size())) + return ReportError("lseek for native FD offset mismatch", off); + + off = lseek(fd, 0, SEEK_SET); + if (off == static_cast<off_t>(-1)) + return ReportError("lseek for native FD returned error", errno); + if (off != 0) + return ReportError("lseek for native FD offset mismatch", off); + + // Check read(2) for the native FD. + std::string buf(msg.size(), '\0'); + cnt = read(fd, &buf[0], msg.size()); + if (cnt < 0) + return ReportError("read for native FD returned error", errno); + if (cnt != static_cast<ssize_t>(msg.size())) + return ReportError("read for native FD count mismatch", cnt); + if (msg != buf) + return ReportMismatch("read for native FD", buf, msg); + + // TODO(hamaji): Test CreateFileMapping for windows. +#if !defined(PPAPI_OS_WIN) + // Check mmap(2) for read. + char* mapped = reinterpret_cast<char*>( + mmap(NULL, msg.size(), PROT_READ, MAP_PRIVATE, fd, 0)); + if (mapped == MAP_FAILED) + return ReportError("mmap(r) for native FD returned errno", errno); + // Make sure the buffer is cleared. + buf = std::string(msg.size(), '\0'); + memcpy(&buf[0], mapped, msg.size()); + if (msg != buf) + return ReportMismatch("mmap(r) for native FD", buf, msg); + int r = munmap(mapped, msg.size()); + if (r < 0) + return ReportError("munmap for native FD returned error", errno); + + // Check mmap(2) for write. + mapped = reinterpret_cast<char*>( + mmap(NULL, msg.size(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + if (mapped == MAP_FAILED) + return ReportError("mmap(w) for native FD returned errno", errno); + // s/foo/baz/ + strcpy(mapped, "baz"); + + r = munmap(mapped, msg.size()); + if (r < 0) + return ReportError("munmap for native FD returned error", errno); +#endif + +#if defined(PPAPI_OS_WIN) + int r = _close(fd); +#else + r = close(handle); +#endif + if (r < 0) + return ReportError("close for native FD returned error", errno); + + // TODO(hamaji): Check if the file is actually updated? + + PASS(); +} + std::string TestFileIO::MatchOpenExpectations(pp::FileSystem* file_system, size_t open_flags, size_t expectations) { diff --git a/ppapi/tests/test_file_io.h b/ppapi/tests/test_file_io.h index 8db0ba1..36917b5 100644 --- a/ppapi/tests/test_file_io.h +++ b/ppapi/tests/test_file_io.h @@ -47,6 +47,7 @@ class TestFileIO : public TestCase { std::string TestParallelWrites(); std::string TestNotAllowMixedReadWrite(); std::string TestWillWriteWillSetLength(); + std::string TestRequestOSFileHandle(); // Helper method used by TestOpen(). // |expectations| is a combination of OpenExpectation values. The followings diff --git a/ppapi/thunk/interfaces_ppb_private_no_permissions.h b/ppapi/thunk/interfaces_ppb_private_no_permissions.h index 059f603..b00bddc 100644 --- a/ppapi/thunk/interfaces_ppb_private_no_permissions.h +++ b/ppapi/thunk/interfaces_ppb_private_no_permissions.h @@ -44,4 +44,7 @@ PROXIED_IFACE(PPB_NetworkMonitor_Private, PPB_NETWORKMONITOR_PRIVATE_INTERFACE_0_2, PPB_NetworkMonitor_Private_0_2) +PROXIED_IFACE(NoAPIName, PPB_FILEIO_PRIVATE_INTERFACE_0_1, + PPB_FileIO_Private_0_1) + #include "ppapi/thunk/interfaces_postamble.h" diff --git a/ppapi/thunk/ppb_file_io_api.h b/ppapi/thunk/ppb_file_io_api.h index b7b3d90..ec7f16d 100644 --- a/ppapi/thunk/ppb_file_io_api.h +++ b/ppapi/thunk/ppb_file_io_api.h @@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/private/pp_file_handle.h" #include "ppapi/thunk/ppapi_thunk_export.h" namespace ppapi { @@ -51,6 +52,11 @@ class PPAPI_THUNK_EXPORT PPB_FileIO_API { scoped_refptr<TrackedCallback> callback) = 0; virtual int32_t WillSetLength(int64_t length, scoped_refptr<TrackedCallback> callback) = 0; + + // Private API. + virtual int32_t RequestOSFileHandle( + PP_FileHandle* handle, + scoped_refptr<TrackedCallback> callback) = 0; }; } // namespace thunk diff --git a/ppapi/thunk/ppb_file_io_private_thunk.cc b/ppapi/thunk/ppb_file_io_private_thunk.cc new file mode 100644 index 0000000..20c7971 --- /dev/null +++ b/ppapi/thunk/ppb_file_io_private_thunk.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// From private/ppb_file_io_private.idl modified Tue Mar 26 15:29:46 2013. + +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_file_io_private.h" +#include "ppapi/shared_impl/tracked_callback.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_file_io_api.h" +#include "ppapi/thunk/ppb_instance_api.h" +#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/thunk/thunk.h" + +namespace ppapi { +namespace thunk { + +namespace { + +int32_t RequestOSFileHandle(PP_Resource file_io, + PP_FileHandle* handle, + struct PP_CompletionCallback callback) { + EnterResource<PPB_FileIO_API> enter(file_io, callback, true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult(enter.object()->RequestOSFileHandle( + handle, + enter.callback())); +} + +const PPB_FileIO_Private_0_1 g_ppb_fileio_private_thunk_0_1 = { + &RequestOSFileHandle +}; + +} // namespace + +const PPB_FileIO_Private_0_1* GetPPB_FileIO_Private_0_1_Thunk() { + return &g_ppb_fileio_private_thunk_0_1; +} + +} // namespace thunk +} // namespace ppapi |