diff options
author | Torne (Richard Coles) <torne@google.com> | 2013-10-18 15:46:22 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2013-10-18 15:46:22 +0100 |
commit | 4e180b6a0b4720a9b8e9e959a882386f690f08ff (patch) | |
tree | 788435d09362885908ba5ba9ef868b852ca82c0b /ppapi | |
parent | 1179b92b08db0c652a0cf003ab4d89b31ce3610f (diff) | |
download | chromium_org-4e180b6a0b4720a9b8e9e959a882386f690f08ff.tar.gz |
Merge from Chromium at DEPS revision 228962
This commit was generated by merge_to_master.py.
Change-Id: I23bd7d7766f213fd52f28ae5e1ecc6ae9df905ea
Diffstat (limited to 'ppapi')
89 files changed, 2671 insertions, 1111 deletions
diff --git a/ppapi/PRESUBMIT.py b/ppapi/PRESUBMIT.py index 7d6a400bd4..46038fbe70 100644 --- a/ppapi/PRESUBMIT.py +++ b/ppapi/PRESUBMIT.py @@ -43,7 +43,8 @@ def RunUnittests(input_api, output_api): # Verify that the files do not contain a 'TODO' in them. RE_TODO = re.compile(r'\WTODO\W', flags=re.I) def CheckTODO(input_api, output_api): - files = input_api.LocalPaths() + live_files = input_api.AffectedFiles(include_deletes=False) + files = [f.LocalPath() for f in live_files] todo = [] for filename in files: @@ -81,7 +82,8 @@ def CheckTODO(input_api, output_api): # Verify that no CPP wrappers use un-versioned PPB interface name macros. RE_UNVERSIONED_PPB = re.compile(r'\bPPB_\w+_INTERFACE\b') def CheckUnversionedPPB(input_api, output_api): - files = input_api.LocalPaths() + live_files = input_api.AffectedFiles(include_deletes=False) + files = [f.LocalPath() for f in live_files] todo = [] for filename in files: diff --git a/ppapi/api/dev/ppb_file_io_dev.idl b/ppapi/api/dev/ppb_file_io_dev.idl new file mode 100644 index 0000000000..f46a4a8693 --- /dev/null +++ b/ppapi/api/dev/ppb_file_io_dev.idl @@ -0,0 +1,118 @@ +/* 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. + */ + + +/** + * This file defines methods for use with a PPB_FileIO resource that may become + * stable in the future. For now, they can be used only in plugins with DEV + * permissions. + */ + +[generate_thunk] + +label Chrome { + M31 = 0.1 +}; + +/** + * The PP_FileMapProtection values indicate the permissions requested for the + * file mapping. These should be used in a uint32_t bitfield. + */ +[assert_size(4)] + enum PP_FileMapProtection { + /** Requests read access to the mapped address. */ + PP_FILEMAPPROTECTION_READ = 1u << 0, + + /** Requests write access to the mapped address. */ + PP_FILEMAPPROTECTION_WRITE = 1u << 1 +}; + +/** + * The PP_FileMapFlags contain flag values for use with Map(). + */ +[assert_size(4)] + enum PP_FileMapFlags { + /** + * Requests a shared mapping. If this flag is set, changes written to the + * memory region will be reflected in the underlying file and will thus + * eventually be visible to other processes which have opened the file. The + * file may not actually be updated until Unmap() is called. This is only + * valid if the PPB_FileIO resource was opened with write permission. + */ + PP_FILEMAPFLAG_SHARED = 1u << 0, + + /** + * Requests a copy-on-write mapping. If this flag is set, changes are not + * written to the underlying file, but only in the memory of the process + * (copy-on-write). + */ + PP_FILEMAPFLAG_PRIVATE = 1u << 1, + + /** + * Forces Map() to map the file contents at the provided |address|. If Map() + * can not comply, Map() will fail. + */ + PP_FILEMAPFLAG_FIXED = 1u << 2 +}; + +/** + * PPB_FileIO_Dev contains functions that are usable with PPB_FileIO resources + * but aren't yet considered stable yet and thus are not supported for general + * NaCl or PNaCl apps yet. Features here are being tested and refined for + * possible future inclusion in (stable) PPB_FileIO. + */ +interface PPB_FileIO_Dev { + /** + * Map() maps the contents from an offset of the file into memory. + * + * @param[in] file_io A PP_Resource corresponding to a file. + * @param[in] length The number of bytes to map. + * @param[in] map_protection A bitfield containing values from + * PP_FileMapProtection, indicating what memory operations should be permitted + * on the mapped region. + * @param[in] map_flags A bitfield containing values from + * PP_FileMapFlags, providing options for the behavior of Map. If the region + * is to be writeable, then exactly one of PP_FILEMAPFLAG_SHARED or + * PP_FILEMAPFLAG_PRIVATE must be set. + * @param[in] offset The offset into the file. Must be a multiple of the + * Map page size as returned by GetMapPageSize. + * @param[inout] address The value of |*address|, if non-NULL, will be used as + * a hint to determine where in memory the file should be mapped. If the value + * is NULL, the host operating system will choose |address|. Upon + * Map() completing, |*address| will contain the actual memory location at + * which the file was mapped. If the plugin provides a non-NULL |*address|, it + * must be a multiple of the map page size as returned by GetMapPageSize(). + * @param[in] callback A PP_CompletionCallback to be called upon + * completion of Map(). + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + */ + int32_t Map([in] PP_Resource file_io, + [in] int64_t length, + [in] uint32_t map_protection, + [in] uint32_t map_flags, + [in] int64_t offset, + [inout] mem_ptr_t address, + [in] PP_CompletionCallback callback); + + /** + * Unmap() deletes the mapping of the specified address address to a + * file io. The specified address must have been retrieved with + * Map(). + * @param[in] file_io A PP_Resource corresponding to a file. + * @param[in] address The starting address of the address in memory to + * be unmapped. + * @param[in] length The length of the region to unmap. + */ + void Unmap(PP_Resource file_io, mem_t address, int64_t length); + + /** + * GetMapPageSize() returns the size of pages that Map() uses. Returns 0 on + * failure. + */ + [on_failure=0] + int64_t GetMapPageSize(PP_Resource file_io); +}; + diff --git a/ppapi/api/dev/ppb_truetype_font_dev.idl b/ppapi/api/dev/ppb_truetype_font_dev.idl index b327eec681..8a3ff2b0f0 100644 --- a/ppapi/api/dev/ppb_truetype_font_dev.idl +++ b/ppapi/api/dev/ppb_truetype_font_dev.idl @@ -249,7 +249,8 @@ interface PPB_TrueTypeFont_Dev { * @param[in] table A 4 byte value indicating which table to copy. * For example, 'glyf' will cause the outline table to be copied into the * output array. A zero tag value will cause the entire font to be copied. - * @param[in] offset The offset into the font table. + * @param[in] offset The offset into the font table. Passing an offset + * greater than or equal to the table size will succeed with 0 bytes copied. * @param[in] max_data_length The maximum number of bytes to transfer from * <code>offset</code>. * @param[in] output A <code>PP_ArrayOutput</code> to hold the font data. diff --git a/ppapi/api/pp_stdint.idl b/ppapi/api/pp_stdint.idl index 0a6d6b6a78..9f54d63bad 100644 --- a/ppapi/api/pp_stdint.idl +++ b/ppapi/api/pp_stdint.idl @@ -40,6 +40,9 @@ describe { /** Pointer to memory (void *). */ mem_t; + /** Pointer to pointer to memory (void **). */ + mem_ptr_t; + /** Pointer to null terminated string (char *). */ str_t; diff --git a/ppapi/api/private/ppb_output_protection_private.idl b/ppapi/api/private/ppb_output_protection_private.idl index 395d253399..44a2585be0 100644 --- a/ppapi/api/private/ppb_output_protection_private.idl +++ b/ppapi/api/private/ppb_output_protection_private.idl @@ -32,7 +32,8 @@ label Chrome { PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA = 1 << 2, PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI = 1 << 3, PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI = 1 << 4, - PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT = 1 << 5 + PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT = 1 << 5, + PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK = 1 << 6 }; /** @@ -124,9 +125,12 @@ interface PPB_OutputProtection_Private { * @param[in] desired_protection_mask The desired protection methods, which * is a bit-mask of the <code>PP_OutputProtectionMethod_Private</code> * values. - * @param[in] callback A <code>PP_CompletionCallback</code> to be called when - * the protection request has been made. This may be before the protection - * have actually been applied. Call QueryStatus to get protection status. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called with + * <code>PP_OK</code> when the protection request has been made. This may be + * before the protection have actually been applied. Call QueryStatus to get + * protection status. If it failed to make the protection request, the + * callback is called with <code>PP_ERROR_FAILED</code> and there is no need + * to call QueryStatus(). * * @return An int32_t containing an error code from <code>pp_errors.h</code>. */ diff --git a/ppapi/api/trusted/ppb_file_io_trusted.idl b/ppapi/api/trusted/ppb_file_io_trusted.idl deleted file mode 100644 index 7ba20deb4b..0000000000 --- a/ppapi/api/trusted/ppb_file_io_trusted.idl +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2012 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. - */ - -/* - * This file defines the trusted file IO interface - */ - -label Chrome { - M14= 0.4 -}; - -// Available only to trusted implementations. -interface PPB_FileIOTrusted { - /** - * Returns a file descriptor corresponding to the given FileIO object. On - * Windows, returns a HANDLE; on all other platforms, returns a POSIX file - * 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); - - /** - * Notifies the browser that underlying file will be modified. This gives - * the browser the opportunity to apply quota restrictions and possibly - * return an error to indicate that the write is not allowed. - */ - int32_t WillWrite([in] PP_Resource file_io, - [in] int64_t offset, - [in] int32_t bytes_to_write, - [in] PP_CompletionCallback callback); - - /** - * Notifies the browser that underlying file will be modified. This gives - * the browser the opportunity to apply quota restrictions and possibly - * return an error to indicate that the write is not allowed. - * - * TODO(darin): Maybe unify the above into a single WillChangeFileSize - * method? The above methods have the advantage of mapping to PPB_FileIO - * Write and SetLength calls. WillChangeFileSize would require the caller to - * compute the file size resulting from a Write call, which may be - * undesirable. - */ - int32_t WillSetLength([in] PP_Resource file_io, - [in] int64_t length, - [in] PP_CompletionCallback callback); - -}; - diff --git a/ppapi/c/dev/ppb_file_io_dev.h b/ppapi/c/dev/ppb_file_io_dev.h new file mode 100644 index 0000000000..a60d3a64c1 --- /dev/null +++ b/ppapi/c/dev/ppb_file_io_dev.h @@ -0,0 +1,138 @@ +/* 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 dev/ppb_file_io_dev.idl modified Thu Sep 19 10:07:03 2013. */ + +#ifndef PPAPI_C_DEV_PPB_FILE_IO_DEV_H_ +#define PPAPI_C_DEV_PPB_FILE_IO_DEV_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_DEV_INTERFACE_0_1 "PPB_FileIO(Dev);0.1" +#define PPB_FILEIO_DEV_INTERFACE PPB_FILEIO_DEV_INTERFACE_0_1 + +/** + * @file + * This file defines methods for use with a PPB_FileIO resource that may become + * stable in the future. For now, they can be used only in plugins with DEV + * permissions. + */ + + +/** + * @addtogroup Enums + * @{ + */ +/** + * The PP_FileMapProtection values indicate the permissions requested for the + * file mapping. These should be used in a uint32_t bitfield. + */ +typedef enum { + /** Requests read access to the mapped address. */ + PP_FILEMAPPROTECTION_READ = 1u << 0, + /** Requests write access to the mapped address. */ + PP_FILEMAPPROTECTION_WRITE = 1u << 1 +} PP_FileMapProtection; +PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_FileMapProtection, 4); + +/** + * The PP_FileMapFlags contain flag values for use with Map(). + */ +typedef enum { + /** + * Requests a shared mapping. If this flag is set, changes written to the + * memory region will be reflected in the underlying file and will thus + * eventually be visible to other processes which have opened the file. The + * file may not actually be updated until Unmap() is called. This is only + * valid if the PPB_FileIO resource was opened with write permission. + */ + PP_FILEMAPFLAG_SHARED = 1u << 0, + /** + * Requests a copy-on-write mapping. If this flag is set, changes are not + * written to the underlying file, but only in the memory of the process + * (copy-on-write). + */ + PP_FILEMAPFLAG_PRIVATE = 1u << 1, + /** + * Forces Map() to map the file contents at the provided |address|. If Map() + * can not comply, Map() will fail. + */ + PP_FILEMAPFLAG_FIXED = 1u << 2 +} PP_FileMapFlags; +PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_FileMapFlags, 4); +/** + * @} + */ + +/** + * @addtogroup Interfaces + * @{ + */ +/** + * PPB_FileIO_Dev contains functions that are usable with PPB_FileIO resources + * but aren't yet considered stable yet and thus are not supported for general + * NaCl or PNaCl apps yet. Features here are being tested and refined for + * possible future inclusion in (stable) PPB_FileIO. + */ +struct PPB_FileIO_Dev_0_1 { + /** + * Map() maps the contents from an offset of the file into memory. + * + * @param[in] file_io A PP_Resource corresponding to a file. + * @param[in] length The number of bytes to map. + * @param[in] map_protection A bitfield containing values from + * PP_FileMapProtection, indicating what memory operations should be permitted + * on the mapped region. + * @param[in] map_flags A bitfield containing values from + * PP_FileMapFlags, providing options for the behavior of Map. If the region + * is to be writeable, then exactly one of PP_FILEMAPFLAG_SHARED or + * PP_FILEMAPFLAG_PRIVATE must be set. + * @param[in] offset The offset into the file. Must be a multiple of the + * Map page size as returned by GetMapPageSize. + * @param[inout] address The value of |*address|, if non-NULL, will be used as + * a hint to determine where in memory the file should be mapped. If the value + * is NULL, the host operating system will choose |address|. Upon + * Map() completing, |*address| will contain the actual memory location at + * which the file was mapped. If the plugin provides a non-NULL |*address|, it + * must be a multiple of the map page size as returned by GetMapPageSize(). + * @param[in] callback A PP_CompletionCallback to be called upon + * completion of Map(). + * + * @return An int32_t containing an error code from <code>pp_errors.h</code>. + */ + int32_t (*Map)(PP_Resource file_io, + int64_t length, + uint32_t map_protection, + uint32_t map_flags, + int64_t offset, + void** address, + struct PP_CompletionCallback callback); + /** + * Unmap() deletes the mapping of the specified address address to a + * file io. The specified address must have been retrieved with + * Map(). + * @param[in] file_io A PP_Resource corresponding to a file. + * @param[in] address The starting address of the address in memory to + * be unmapped. + * @param[in] length The length of the region to unmap. + */ + void (*Unmap)(PP_Resource file_io, void* address, int64_t length); + /** + * GetMapPageSize() returns the size of pages that Map() uses. Returns 0 on + * failure. + */ + int64_t (*GetMapPageSize)(PP_Resource file_io); +}; + +typedef struct PPB_FileIO_Dev_0_1 PPB_FileIO_Dev; +/** + * @} + */ + +#endif /* PPAPI_C_DEV_PPB_FILE_IO_DEV_H_ */ + diff --git a/ppapi/c/dev/ppb_truetype_font_dev.h b/ppapi/c/dev/ppb_truetype_font_dev.h index 5172caee73..1511ca4af3 100644 --- a/ppapi/c/dev/ppb_truetype_font_dev.h +++ b/ppapi/c/dev/ppb_truetype_font_dev.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From dev/ppb_truetype_font_dev.idl modified Wed Apr 17 15:38:46 2013. */ +/* From dev/ppb_truetype_font_dev.idl modified Tue Oct 15 05:52:52 2013. */ #ifndef PPAPI_C_DEV_PPB_TRUETYPE_FONT_DEV_H_ #define PPAPI_C_DEV_PPB_TRUETYPE_FONT_DEV_H_ @@ -266,7 +266,8 @@ struct PPB_TrueTypeFont_Dev_0_1 { * @param[in] table A 4 byte value indicating which table to copy. * For example, 'glyf' will cause the outline table to be copied into the * output array. A zero tag value will cause the entire font to be copied. - * @param[in] offset The offset into the font table. + * @param[in] offset The offset into the font table. Passing an offset + * greater than or equal to the table size will succeed with 0 bytes copied. * @param[in] max_data_length The maximum number of bytes to transfer from * <code>offset</code>. * @param[in] output A <code>PP_ArrayOutput</code> to hold the font data. diff --git a/ppapi/c/private/ppb_output_protection_private.h b/ppapi/c/private/ppb_output_protection_private.h index d0438be8f3..d489c009e3 100644 --- a/ppapi/c/private/ppb_output_protection_private.h +++ b/ppapi/c/private/ppb_output_protection_private.h @@ -4,7 +4,7 @@ */ /* From private/ppb_output_protection_private.idl, - * modified Sat Aug 31 03:18:39 2013. + * modified Tue Oct 8 13:22:13 2013. */ #ifndef PPAPI_C_PRIVATE_PPB_OUTPUT_PROTECTION_PRIVATE_H_ @@ -52,7 +52,8 @@ typedef enum { PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_VGA = 1 << 2, PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_HDMI = 1 << 3, PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DVI = 1 << 4, - PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT = 1 << 5 + PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_DISPLAYPORT = 1 << 5, + PP_OUTPUT_PROTECTION_LINK_TYPE_PRIVATE_NETWORK = 1 << 6 } PP_OutputProtectionLinkType_Private; PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_OutputProtectionLinkType_Private, 4); /** @@ -148,9 +149,12 @@ struct PPB_OutputProtection_Private_0_1 { * @param[in] desired_protection_mask The desired protection methods, which * is a bit-mask of the <code>PP_OutputProtectionMethod_Private</code> * values. - * @param[in] callback A <code>PP_CompletionCallback</code> to be called when - * the protection request has been made. This may be before the protection - * have actually been applied. Call QueryStatus to get protection status. + * @param[in] callback A <code>PP_CompletionCallback</code> to be called with + * <code>PP_OK</code> when the protection request has been made. This may be + * before the protection have actually been applied. Call QueryStatus to get + * protection status. If it failed to make the protection request, the + * callback is called with <code>PP_ERROR_FAILED</code> and there is no need + * to call QueryStatus(). * * @return An int32_t containing an error code from <code>pp_errors.h</code>. */ diff --git a/ppapi/c/trusted/ppb_file_io_trusted.h b/ppapi/c/trusted/ppb_file_io_trusted.h deleted file mode 100644 index 8e05589eeb..0000000000 --- a/ppapi/c/trusted/ppb_file_io_trusted.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2012 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 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_ - -#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_FILEIOTRUSTED_INTERFACE_0_4 "PPB_FileIOTrusted;0.4" -#define PPB_FILEIOTRUSTED_INTERFACE PPB_FILEIOTRUSTED_INTERFACE_0_4 - -/** - * @file - * - * This file defines the trusted file IO interface - */ - - -/** - * @addtogroup Interfaces - * @{ - */ -/* Available only to trusted implementations. */ -struct PPB_FileIOTrusted_0_4 { - /** - * Returns a file descriptor corresponding to the given FileIO object. On - * Windows, returns a HANDLE; on all other platforms, returns a POSIX file - * 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); - /** - * Notifies the browser that underlying file will be modified. This gives - * the browser the opportunity to apply quota restrictions and possibly - * return an error to indicate that the write is not allowed. - */ - int32_t (*WillWrite)(PP_Resource file_io, - int64_t offset, - int32_t bytes_to_write, - struct PP_CompletionCallback callback); - /** - * Notifies the browser that underlying file will be modified. This gives - * the browser the opportunity to apply quota restrictions and possibly - * return an error to indicate that the write is not allowed. - * - * TODO(darin): Maybe unify the above into a single WillChangeFileSize - * method? The above methods have the advantage of mapping to PPB_FileIO - * Write and SetLength calls. WillChangeFileSize would require the caller to - * compute the file size resulting from a Write call, which may be - * undesirable. - */ - int32_t (*WillSetLength)(PP_Resource file_io, - int64_t length, - struct PP_CompletionCallback callback); -}; - -typedef struct PPB_FileIOTrusted_0_4 PPB_FileIOTrusted; -/** - * @} - */ - -#endif /* PPAPI_C_TRUSTED_PPB_FILE_IO_TRUSTED_H_ */ - diff --git a/ppapi/cpp/private/flash_drm.cc b/ppapi/cpp/private/flash_drm.cc index 44887abc20..f576fb26d0 100644 --- a/ppapi/cpp/private/flash_drm.cc +++ b/ppapi/cpp/private/flash_drm.cc @@ -71,7 +71,7 @@ int32_t DRM::GetVoucherFile( callback.output(), callback.pp_completion_callback()); } - return PP_ERROR_FAILED; + return PP_ERROR_NOINTERFACE; } } // namespace flash diff --git a/ppapi/cpp/private/output_protection_private.cc b/ppapi/cpp/private/output_protection_private.cc new file mode 100644 index 0000000000..9b244fef34 --- /dev/null +++ b/ppapi/cpp/private/output_protection_private.cc @@ -0,0 +1,59 @@ +// Copyright 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/output_protection_private.h" + +#include <stdio.h> +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_output_protection_private.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/instance_handle.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +template <> const char* interface_name<PPB_OutputProtection_Private_0_1>() { + return PPB_OUTPUTPROTECTION_PRIVATE_INTERFACE_0_1; +} + +} // namespace + +OutputProtection_Private::OutputProtection_Private( + const InstanceHandle& instance) { + if (has_interface<PPB_OutputProtection_Private_0_1>()) { + PassRefFromConstructor( + get_interface<PPB_OutputProtection_Private_0_1>()->Create( + instance.pp_instance())); + } +} + +OutputProtection_Private::~OutputProtection_Private() { +} + +int32_t OutputProtection_Private::QueryStatus( + uint32_t* link_mask, + uint32_t* protection_mask, + const CompletionCallback& callback) { + if (has_interface<PPB_OutputProtection_Private_0_1>()) { + return get_interface<PPB_OutputProtection_Private_0_1>()->QueryStatus( + pp_resource(), link_mask, protection_mask, + callback.pp_completion_callback()); + } + return callback.MayForce(PP_ERROR_NOINTERFACE); +} + +int32_t OutputProtection_Private::EnableProtection( + uint32_t desired_method_mask, + const CompletionCallback& callback) { + if (has_interface<PPB_OutputProtection_Private_0_1>()) { + return get_interface<PPB_OutputProtection_Private_0_1>()->EnableProtection( + pp_resource(), desired_method_mask, + callback.pp_completion_callback()); + } + return callback.MayForce(PP_ERROR_NOINTERFACE); +} + +} // namespace pp diff --git a/ppapi/cpp/private/output_protection_private.h b/ppapi/cpp/private/output_protection_private.h new file mode 100644 index 0000000000..6b543ea222 --- /dev/null +++ b/ppapi/cpp/private/output_protection_private.h @@ -0,0 +1,28 @@ +// Copyright 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_OUTPUT_PROTECTION_PRIVATE_H_ +#define PPAPI_CPP_PRIVATE_OUTPUT_PROTECTION_PRIVATE_H_ + +#include "ppapi/c/private/ppb_output_protection_private.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/resource.h" + +namespace pp { + +class OutputProtection_Private : public Resource { + public: + explicit OutputProtection_Private(const InstanceHandle& instance); + virtual ~OutputProtection_Private(); + + // PPB_OutputProtection_Private implementation. + int32_t QueryStatus(uint32_t* link_mask, uint32_t* protection_mask, + const CompletionCallback& callback); + int32_t EnableProtection(uint32_t desired_method_mask, + const CompletionCallback& callback); +}; + +} // namespace pp + +#endif // PPAPI_CPP_PRIVATE_OUTPUT_PROTECTION_PRIVATE_H_ diff --git a/ppapi/cpp/trusted/file_io_trusted.cc b/ppapi/cpp/trusted/file_io_trusted.cc deleted file mode 100644 index a3123cac18..0000000000 --- a/ppapi/cpp/trusted/file_io_trusted.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2011 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/trusted/file_io_trusted.h" - -#include "ppapi/c/pp_errors.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" -#include "ppapi/cpp/completion_callback.h" -#include "ppapi/cpp/file_io.h" -#include "ppapi/cpp/module_impl.h" - -namespace pp { - -namespace { - -template <> const char* interface_name<PPB_FileIOTrusted>() { - return PPB_FILEIOTRUSTED_INTERFACE_0_4; -} - -} // namespace - -FileIO_Trusted::FileIO_Trusted() { -} - -int32_t FileIO_Trusted::GetOSFileDescriptor(const FileIO& file_io) { - const int32_t kInvalidOSFileDescriptor = -1; - if (!has_interface<PPB_FileIOTrusted>()) - return kInvalidOSFileDescriptor; - return get_interface<PPB_FileIOTrusted>()->GetOSFileDescriptor( - file_io.pp_resource()); -} - -int32_t FileIO_Trusted::WillWrite(const FileIO& file_io, - int64_t offset, - int32_t bytes_to_write, - const CompletionCallback& callback) { - if (!has_interface<PPB_FileIOTrusted>()) - return callback.MayForce(PP_ERROR_NOINTERFACE); - return get_interface<PPB_FileIOTrusted>()->WillWrite( - file_io.pp_resource(), offset, bytes_to_write, - callback.pp_completion_callback()); -} - -int32_t FileIO_Trusted::WillSetLength(const FileIO& file_io, - int64_t length, - const CompletionCallback& callback) { - if (!has_interface<PPB_FileIOTrusted>()) - return callback.MayForce(PP_ERROR_NOINTERFACE); - return get_interface<PPB_FileIOTrusted>()->WillSetLength( - file_io.pp_resource(), length, callback.pp_completion_callback()); -} - -} // namespace pp diff --git a/ppapi/cpp/trusted/file_io_trusted.h b/ppapi/cpp/trusted/file_io_trusted.h deleted file mode 100644 index 3ba2140832..0000000000 --- a/ppapi/cpp/trusted/file_io_trusted.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2011 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_TRUSTED_FILE_IO_TRUSTED_H_ -#define PPAPI_CPP_TRUSTED_FILE_IO_TRUSTED_H_ - -#include <string> - -#include "ppapi/c/pp_stdint.h" - -namespace pp { - -class FileIO; -class CompletionCallback; - -class FileIO_Trusted { - public: - /// Creates a FileIO_Trusted object. - FileIO_Trusted(); - - int32_t GetOSFileDescriptor(const FileIO& file_io); - - int32_t WillWrite(const FileIO& file_io, - int64_t offset, - int32_t bytes_to_write, - const CompletionCallback& callback); - - int32_t WillSetLength(const FileIO& file_io, - int64_t length, - const CompletionCallback& callback); -}; - -} // namespace pp - -#endif // PPAPI_CPP_TRUSTED_FILE_IO_TRUSTED_H_ diff --git a/ppapi/generators/idl_ast.py b/ppapi/generators/idl_ast.py index 2765892100..3c2b32dccd 100644 --- a/ppapi/generators/idl_ast.py +++ b/ppapi/generators/idl_ast.py @@ -15,7 +15,8 @@ from idl_release import IDLReleaseList, IDLReleaseMap # BuiltIn = set(['int8_t', 'int16_t', 'int32_t', 'int64_t', 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t', 'double_t', 'float_t', - 'handle_t', 'interface_t', 'char', 'mem_t', 'str_t', 'void']) + 'handle_t', 'interface_t', 'char', 'mem_t', 'mem_ptr_t', + 'str_t', 'void']) # diff --git a/ppapi/generators/idl_c_proto.py b/ppapi/generators/idl_c_proto.py index 0e0797ac42..7e49c02d50 100755 --- a/ppapi/generators/idl_c_proto.py +++ b/ppapi/generators/idl_c_proto.py @@ -125,6 +125,13 @@ class CGen(object): 'return': '%s', 'store': '%s' }, + 'mem_ptr_t': { + 'in': 'const %s', + 'inout': '%s', + 'out': '%s', + 'return': '%s', + 'store': '%s' + }, 'str_t': { 'in': 'const %s', 'inout': '%s', @@ -161,6 +168,7 @@ class CGen(object): 'double_t': 'double', 'handle_t': 'int', 'mem_t': 'void*', + 'mem_ptr_t': 'void**', 'str_t': 'char*', 'cstr_t': 'const char*', 'interface_t' : 'const void*' diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.cc b/ppapi/native_client/src/trusted/plugin/file_downloader.cc index 5da04c686b..4bc1d4a673 100644 --- a/ppapi/native_client/src/trusted/plugin/file_downloader.cc +++ b/ppapi/native_client/src/trusted/plugin/file_downloader.cc @@ -33,8 +33,28 @@ struct NaClFileInfo NoFileInfo() { return info; } +// Converts a PP_FileHandle to a POSIX file descriptor. +int32_t ConvertFileDescriptor(PP_FileHandle handle) { + PLUGIN_PRINTF(("ConvertFileDescriptor, handle=%d\n", handle)); +#if NACL_WINDOWS + int32_t file_desc = NACL_NO_FILE_DESC; + // On Windows, valid handles are 32 bit unsigned integers so this is safe. + file_desc = reinterpret_cast<uintptr_t>(handle); + // Convert the Windows HANDLE from Pepper to a POSIX file descriptor. + int32_t posix_desc = _open_osfhandle(file_desc, _O_RDWR | _O_BINARY); + if (posix_desc == -1) { + // Close the Windows HANDLE if it can't be converted. + CloseHandle(reinterpret_cast<HANDLE>(file_desc)); + return -1; + } + return posix_desc; +#else + return handle; +#endif } +} // namespace + namespace plugin { void FileDownloader::Initialize(Plugin* instance) { @@ -44,11 +64,12 @@ void FileDownloader::Initialize(Plugin* instance) { CHECK(instance_ == NULL); // Can only initialize once. instance_ = instance; callback_factory_.Initialize(this); - file_io_trusted_interface_ = static_cast<const PPB_FileIOTrusted*>( - pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); + file_io_private_interface_ = static_cast<const PPB_FileIO_Private*>( + pp::Module::Get()->GetBrowserInterface(PPB_FILEIO_PRIVATE_INTERFACE)); url_loader_trusted_interface_ = static_cast<const PPB_URLLoaderTrusted*>( pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE)); temp_buffer_.resize(kTempBufferSize); + cached_file_info_ = NoFileInfo(); } bool FileDownloader::OpenStream( @@ -69,7 +90,7 @@ bool FileDownloader::Open( PLUGIN_PRINTF(("FileDownloader::Open (url=%s)\n", url.c_str())); if (callback.pp_completion_callback().func == NULL || instance_ == NULL || - file_io_trusted_interface_ == NULL) + file_io_private_interface_ == NULL) return false; CHECK(instance_ != NULL); @@ -80,6 +101,7 @@ bool FileDownloader::Open( file_open_notify_callback_ = callback; mode_ = mode; buffer_.clear(); + cached_file_info_ = NoFileInfo(); pp::URLRequestInfo url_request(instance_); // Allow CORS. @@ -137,18 +159,12 @@ bool FileDownloader::Open( } } while (0); - void (FileDownloader::*start_notify)(int32_t); - if (streaming_to_file()) - start_notify = &FileDownloader::URLLoadStartNotify; - else - start_notify = &FileDownloader::URLBufferStartNotify; - // Request asynchronous download of the url providing an on-load callback. // As long as this step is guaranteed to be asynchronous, we can call // synchronously all other internal callbacks that eventually result in the // invocation of the user callback. The user code will not be reentered. pp::CompletionCallback onload_callback = - callback_factory_.NewCallback(start_notify); + callback_factory_.NewCallback(&FileDownloader::URLLoadStartNotify); int32_t pp_error = url_loader_.Open(url_request, onload_callback); PLUGIN_PRINTF(("FileDownloader::Open (pp_error=%" NACL_PRId32 ")\n", pp_error)); @@ -160,6 +176,8 @@ void FileDownloader::OpenFast(const nacl::string& url, PP_FileHandle file_handle, uint64_t file_token_lo, uint64_t file_token_hi) { PLUGIN_PRINTF(("FileDownloader::OpenFast (url=%s)\n", url.c_str())); + + cached_file_info_ = NoFileInfo(); CHECK(instance_ != NULL); open_time_ = NaClGetTimeOfDayMicroseconds(); status_code_ = NACL_HTTP_STATUS_OK; @@ -172,41 +190,16 @@ void FileDownloader::OpenFast(const nacl::string& url, } struct NaClFileInfo FileDownloader::GetFileInfo() { - struct NaClFileInfo info = NoFileInfo(); - int32_t file_desc = NACL_NO_FILE_DESC; - if (not_streaming() && file_handle_ != PP_kInvalidFileHandle) { -#if NACL_WINDOWS - // On Windows, valid handles are 32 bit unsigned integers so this is safe. - file_desc = reinterpret_cast<uintptr_t>(file_handle_); -#else - file_desc = file_handle_; -#endif - info.file_token = file_token_; - } else { - if (!streaming_to_file()) { - return NoFileInfo(); - } - // Use the trusted interface to get the file descriptor. - if (file_io_trusted_interface_ == NULL) { - return NoFileInfo(); - } - file_desc = file_io_trusted_interface_->GetOSFileDescriptor( - file_reader_.pp_resource()); - } - -#if NACL_WINDOWS - // Convert the Windows HANDLE from Pepper to a POSIX file descriptor. - int32_t posix_desc = _open_osfhandle(file_desc, _O_RDWR | _O_BINARY); - if (posix_desc == -1) { - // Close the Windows HANDLE if it can't be converted. - CloseHandle(reinterpret_cast<HANDLE>(file_desc)); - return NoFileInfo(); + PLUGIN_PRINTF(("FileDownloader::GetFileInfo\n")); + if (cached_file_info_.desc != -1) { + return cached_file_info_; + } else if (not_streaming() && file_handle_ != PP_kInvalidFileHandle) { + cached_file_info_.desc = ConvertFileDescriptor(file_handle_); + if (cached_file_info_.desc != -1) + cached_file_info_.file_token = file_token_; + return cached_file_info_; } - file_desc = posix_desc; -#endif - - info.desc = file_desc; - return info; + return NoFileInfo(); } int64_t FileDownloader::TimeSinceOpenMilliseconds() const { @@ -218,18 +211,12 @@ int64_t FileDownloader::TimeSinceOpenMilliseconds() const { return (now - open_time_) / NACL_MICROS_PER_MILLI; } -bool FileDownloader::InitialResponseIsValid(int32_t pp_error) { - if (pp_error != PP_OK) { // Url loading failed. - file_open_notify_callback_.RunAndClear(pp_error); - return false; - } - +bool FileDownloader::InitialResponseIsValid() { // Process the response, validating the headers to confirm successful loading. url_response_ = url_loader_.GetResponseInfo(); if (url_response_.is_null()) { PLUGIN_PRINTF(( "FileDownloader::InitialResponseIsValid (url_response_=NULL)\n")); - file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED); return false; } @@ -237,7 +224,6 @@ bool FileDownloader::InitialResponseIsValid(int32_t pp_error) { if (!full_url.is_string()) { PLUGIN_PRINTF(( "FileDownloader::InitialResponseIsValid (url is not a string)\n")); - file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED); return false; } url_ = full_url.AsString(); @@ -265,43 +251,28 @@ bool FileDownloader::InitialResponseIsValid(int32_t pp_error) { status_ok = (status_code_ == NACL_HTTP_STATUS_OK); break; } - - if (!status_ok) { - file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED); - return false; - } - - return true; + return status_ok; } void FileDownloader::URLLoadStartNotify(int32_t pp_error) { PLUGIN_PRINTF(("FileDownloader::URLLoadStartNotify (pp_error=%" NACL_PRId32")\n", pp_error)); - - if (!InitialResponseIsValid(pp_error)) { - // InitialResponseIsValid() calls file_open_notify_callback_ on errors. + if (pp_error != PP_OK) { + file_open_notify_callback_.RunAndClear(pp_error); return; } - if (open_and_stream_) - return FinishStreaming(file_open_notify_callback_); - - file_open_notify_callback_.RunAndClear(pp_error); -} - -void FileDownloader::URLBufferStartNotify(int32_t pp_error) { - PLUGIN_PRINTF(("FileDownloader::URLBufferStartNotify (pp_error=%" - NACL_PRId32")\n", pp_error)); - - if (!InitialResponseIsValid(pp_error)) { - // InitialResponseIsValid() calls file_open_notify_callback_ on errors. + if (!InitialResponseIsValid()) { + file_open_notify_callback_.RunAndClear(PP_ERROR_FAILED); return; } - if (open_and_stream_) - return FinishStreaming(file_open_notify_callback_); + if (open_and_stream_) { + FinishStreaming(file_open_notify_callback_); + return; + } - file_open_notify_callback_.RunAndClear(pp_error); + file_open_notify_callback_.RunAndClear(PP_OK); } void FileDownloader::FinishStreaming( @@ -442,7 +413,19 @@ void FileDownloader::StreamFinishNotify(int32_t pp_error) { PLUGIN_PRINTF(( "FileDownloader::StreamFinishNotify (pp_error=%" NACL_PRId32 ")\n", pp_error)); - stream_finish_callback_.RunAndClear(pp_error); + + // Run the callback if we have an error, or if we don't have a file_reader_ + // to get a file handle for. + if (pp_error != PP_OK || file_reader_.pp_resource() == 0) { + stream_finish_callback_.RunAndClear(pp_error); + return; + } + + pp::CompletionCallbackWithOutput<PP_FileHandle> cb = + callback_factory_.NewCallbackWithOutput( + &FileDownloader::GotFileHandleNotify); + file_io_private_interface_->RequestOSFileHandle( + file_reader_.pp_resource(), cb.output(), cb.pp_completion_callback()); } bool FileDownloader::streaming_to_file() const { @@ -461,4 +444,15 @@ bool FileDownloader::not_streaming() const { return mode_ == DOWNLOAD_NONE; } +void FileDownloader::GotFileHandleNotify(int32_t pp_error, + PP_FileHandle handle) { + PLUGIN_PRINTF(( + "FileDownloader::GotFileHandleNotify (pp_error=%" NACL_PRId32 ")\n", + pp_error)); + if (pp_error == PP_OK) + cached_file_info_.desc = ConvertFileDescriptor(handle); + + stream_finish_callback_.RunAndClear(pp_error); +} + } // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/file_downloader.h b/ppapi/native_client/src/trusted/plugin/file_downloader.h index e84e636868..23f202cb08 100644 --- a/ppapi/native_client/src/trusted/plugin/file_downloader.h +++ b/ppapi/native_client/src/trusted/plugin/file_downloader.h @@ -11,7 +11,7 @@ #include "native_client/src/include/nacl_string.h" #include "native_client/src/trusted/validator/nacl_file_info.h" #include "ppapi/c/private/pp_file_handle.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" +#include "ppapi/c/private/ppb_file_io_private.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #include "ppapi/cpp/file_io.h" #include "ppapi/cpp/instance.h" @@ -52,7 +52,7 @@ class FileDownloader { file_open_notify_callback_(pp::BlockUntilComplete()), stream_finish_callback_(pp::BlockUntilComplete()), file_handle_(PP_kInvalidFileHandle), - file_io_trusted_interface_(NULL), + file_io_private_interface_(NULL), url_loader_trusted_interface_(NULL), open_time_(-1), mode_(DOWNLOAD_NONE), @@ -165,12 +165,12 @@ class FileDownloader { // data is passed directly to the user instead of saved in a buffer. // The public Open*() functions start step 1), and the public FinishStreaming // function proceeds to step 2) and 3). - bool InitialResponseIsValid(int32_t pp_error); + bool InitialResponseIsValid(); void URLLoadStartNotify(int32_t pp_error); void URLLoadFinishNotify(int32_t pp_error); - void URLBufferStartNotify(int32_t pp_error); void URLReadBodyNotify(int32_t pp_error); void StreamFinishNotify(int32_t pp_error); + void GotFileHandleNotify(int32_t pp_error, PP_FileHandle handle); Plugin* instance_; nacl::string url_to_open_; @@ -181,7 +181,7 @@ class FileDownloader { pp::FileIO file_reader_; PP_FileHandle file_handle_; struct NaClFileToken file_token_; - const PPB_FileIOTrusted* file_io_trusted_interface_; + const PPB_FileIO_Private* file_io_private_interface_; const PPB_URLLoaderTrusted* url_loader_trusted_interface_; pp::URLLoader url_loader_; pp::CompletionCallbackFactory<FileDownloader> callback_factory_; @@ -194,6 +194,7 @@ class FileDownloader { std::deque<char> buffer_; UrlSchemeType url_scheme_; StreamCallbackSource* data_stream_callback_source_; + NaClFileInfo cached_file_info_; }; } // namespace plugin; #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_ diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.cc b/ppapi/native_client/src/trusted/plugin/json_manifest.cc index 0928c05f2c..4a3640f504 100644 --- a/ppapi/native_client/src/trusted/plugin/json_manifest.cc +++ b/ppapi/native_client/src/trusted/plugin/json_manifest.cc @@ -42,8 +42,6 @@ const char* const kUrlKey = "url"; // PNaCl keys const char* const kOptLevelKey = "optlevel"; -// DEPRECATED! TODO(jvoung): remove the error message after launch. -const char* const kOptLevelKeyDeprecated = "-O"; // Sample NaCl manifest file: // { @@ -212,14 +210,6 @@ bool IsValidUrlSpec(const Json::Value& url_spec, *error_string = error_stream.str(); return false; } - if (url_spec.isMember(kOptLevelKeyDeprecated)) { - nacl::stringstream error_stream; - error_stream << parent_key << " property '" << container_key << - "' has deprecated key '" << kOptLevelKeyDeprecated << - "' please use '" << kOptLevelKey << "' instead."; - *error_string = error_stream.str(); - return false; - } return true; } diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index f4d30bfd0b..26268bf7eb 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -251,6 +251,7 @@ PnaclCoordinator::PnaclCoordinator( : translate_finish_error_(PP_OK), plugin_(plugin), translate_notify_callback_(translate_notify_callback), + translation_finished_reported_(false), manifest_(new PnaclManifest()), pexe_url_(pexe_url), pnacl_options_(pnacl_options), @@ -278,6 +279,11 @@ PnaclCoordinator::~PnaclCoordinator() { if (translate_thread_.get() != NULL) { translate_thread_->AbortSubprocesses(); } + if (!translation_finished_reported_) { + plugin_->nacl_interface()->ReportTranslationFinished( + plugin_->pp_instance(), + PP_FALSE); + } } nacl::DescWrapper* PnaclCoordinator::ReleaseTranslatedFD() { @@ -315,6 +321,10 @@ void PnaclCoordinator::ExitWithError() { callback_factory_.CancelAll(); if (!error_already_reported_) { error_already_reported_ = true; + translation_finished_reported_ = true; + plugin_->nacl_interface()->ReportTranslationFinished( + plugin_->pp_instance(), + PP_FALSE); translate_notify_callback_.Run(PP_ERROR_FAILED); } else { PLUGIN_PRINTF(("PnaclCoordinator::ExitWithError an earlier error was " @@ -329,9 +339,6 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) { // Bail out if there was an earlier error (e.g., pexe load failure), // or if there is an error from the translation thread. if (translate_finish_error_ != PP_OK || pp_error != PP_OK) { - plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), - PP_FALSE); ExitWithError(); return; } @@ -389,6 +396,7 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) { // Report to the browser that translation finished. The browser will take // care of storing the nexe in the cache. + translation_finished_reported_ = true; plugin_->nacl_interface()->ReportTranslationFinished( plugin_->pp_instance(), PP_TRUE); @@ -505,8 +513,6 @@ void PnaclCoordinator::BitcodeStreamDidOpen(int32_t pp_error) { nacl::string headers = streaming_downloader_->GetResponseHeaders(); NaClHttpResponseHeaders parser; parser.Parse(headers); - // TODO(dschuff): honor parser.CacheControlNoStore(). It wasn't handled in - // the new cache case before. temp_nexe_file_.reset(new TempFile(plugin_)); pp::CompletionCallback cb = @@ -596,9 +602,6 @@ void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); } - plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), - PP_FALSE); translate_thread_->AbortSubprocesses(); } else { // Compare download completion pct (100% now), to compile completion pct. @@ -673,9 +676,6 @@ void PnaclCoordinator::ObjectFileDidOpen(int32_t pp_error) { ReportPpapiError(ERROR_PNACL_CREATE_TEMP, pp_error, "Failed to open scratch object file."); - plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), - PP_FALSE); return; } // Open the nexe file for connecting ld and sel_ldr. diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h index a87b031d9f..97828646a5 100644 --- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h +++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h @@ -185,6 +185,12 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> { Plugin* plugin_; pp::CompletionCallback translate_notify_callback_; + // Set to true when the translation (if applicable) is finished and the nexe + // file is loaded, (or when there was an error), and the browser has been + // notified via ReportTranslationFinished. If it is not set before + // plugin/coordinator destruction, the destructor will call + // ReportTranslationFinished. + bool translation_finished_reported_; // Threadsafety is required to support file lookups. pp::CompletionCallbackFactory<PnaclCoordinator, pp::ThreadSafeThreadTraits> callback_factory_; diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h index 4241737602..b06a706ae8 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.h +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h @@ -23,7 +23,6 @@ #include "native_client/src/trusted/reverse_service/reverse_service.h" #include "native_client/src/trusted/weak_ref/weak_ref.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/cpp/completion_callback.h" #include "ppapi/native_client/src/trusted/plugin/utility.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 747d753e6e..4480008d91 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 @@ -13,6 +13,7 @@ #include "ppapi/c/dev/ppb_cursor_control_dev.h" #include "ppapi/c/dev/ppb_device_ref_dev.h" #include "ppapi/c/dev/ppb_file_chooser_dev.h" +#include "ppapi/c/dev/ppb_file_io_dev.h" #include "ppapi/c/dev/ppb_find_dev.h" #include "ppapi/c/dev/ppb_font_dev.h" #include "ppapi/c/dev/ppb_graphics_2d_dev.h" @@ -118,7 +119,6 @@ #include "ppapi/c/trusted/ppb_browser_font_trusted.h" #include "ppapi/c/trusted/ppb_char_set_trusted.h" #include "ppapi/c/trusted/ppb_file_chooser_trusted.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" /* Use local strcmp to avoid dependency on libc. */ @@ -179,6 +179,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_AudioInput_Dev_0_4; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_DeviceRef_Dev_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileChooser_Dev_0_5; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileChooser_Dev_0_6; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileIO_Dev_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Font_Dev_0_6; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_IMEInputEvent_Dev_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_IMEInputEvent_Dev_0_2; @@ -1617,8 +1618,6 @@ static void Pnacl_M14_PPP_Messaging_HandleMessage(PP_Instance instance, struct P /* Not generating wrapper methods for PPB_FileChooserTrusted_0_6 */ -/* Not generating wrapper methods for PPB_FileIOTrusted_0_4 */ - /* Not generating wrapper methods for PPB_URLLoaderTrusted_0_3 */ /* Begin wrapper methods for PPB_AudioInput_Dev_0_2 */ @@ -1831,6 +1830,25 @@ static int32_t Pnacl_M19_PPB_FileChooser_Dev_Show(PP_Resource chooser, struct PP /* End wrapper methods for PPB_FileChooser_Dev_0_6 */ +/* Begin wrapper methods for PPB_FileIO_Dev_0_1 */ + +static int32_t Pnacl_M31_PPB_FileIO_Dev_Map(PP_Resource file_io, int64_t length, uint32_t map_protection, uint32_t map_flags, int64_t offset, void** address, struct PP_CompletionCallback* callback) { + const struct PPB_FileIO_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_FileIO_Dev_0_1.real_iface; + return iface->Map(file_io, length, map_protection, map_flags, offset, address, *callback); +} + +static void Pnacl_M31_PPB_FileIO_Dev_Unmap(PP_Resource file_io, void* address, int64_t length) { + const struct PPB_FileIO_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_FileIO_Dev_0_1.real_iface; + iface->Unmap(file_io, address, length); +} + +static int64_t Pnacl_M31_PPB_FileIO_Dev_GetMapPageSize(PP_Resource file_io) { + const struct PPB_FileIO_Dev_0_1 *iface = Pnacl_WrapperInfo_PPB_FileIO_Dev_0_1.real_iface; + return iface->GetMapPageSize(file_io); +} + +/* End wrapper methods for PPB_FileIO_Dev_0_1 */ + /* Not generating wrapper methods for PPB_Find_Dev_0_3 */ /* Begin wrapper methods for PPB_Font_Dev_0_6 */ @@ -4492,8 +4510,6 @@ struct PPP_Messaging_1_0 Pnacl_Wrappers_PPP_Messaging_1_0 = { /* Not generating wrapper interface for PPB_FileChooserTrusted_0_6 */ -/* Not generating wrapper interface for PPB_FileIOTrusted_0_4 */ - /* Not generating wrapper interface for PPB_URLLoaderTrusted_0_3 */ struct PPB_AudioInput_Dev_0_2 Pnacl_Wrappers_PPB_AudioInput_Dev_0_2 = { @@ -4556,6 +4572,12 @@ struct PPB_FileChooser_Dev_0_6 Pnacl_Wrappers_PPB_FileChooser_Dev_0_6 = { .Show = (int32_t (*)(PP_Resource chooser, struct PP_ArrayOutput output, struct PP_CompletionCallback callback))&Pnacl_M19_PPB_FileChooser_Dev_Show }; +struct PPB_FileIO_Dev_0_1 Pnacl_Wrappers_PPB_FileIO_Dev_0_1 = { + .Map = (int32_t (*)(PP_Resource file_io, int64_t length, uint32_t map_protection, uint32_t map_flags, int64_t offset, void** address, struct PP_CompletionCallback callback))&Pnacl_M31_PPB_FileIO_Dev_Map, + .Unmap = (void (*)(PP_Resource file_io, void* address, int64_t length))&Pnacl_M31_PPB_FileIO_Dev_Unmap, + .GetMapPageSize = (int64_t (*)(PP_Resource file_io))&Pnacl_M31_PPB_FileIO_Dev_GetMapPageSize +}; + /* Not generating wrapper interface for PPB_Find_Dev_0_3 */ struct PPB_Font_Dev_0_6 Pnacl_Wrappers_PPB_Font_Dev_0_6 = { @@ -5445,6 +5467,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileChooser_Dev_0_6 = { .real_iface = NULL }; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileIO_Dev_0_1 = { + .iface_macro = PPB_FILEIO_DEV_INTERFACE_0_1, + .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_FileIO_Dev_0_1, + .real_iface = NULL +}; + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Font_Dev_0_6 = { .iface_macro = PPB_FONT_DEV_INTERFACE_0_6, .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_Font_Dev_0_6, @@ -5825,6 +5853,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { &Pnacl_WrapperInfo_PPB_DeviceRef_Dev_0_1, &Pnacl_WrapperInfo_PPB_FileChooser_Dev_0_5, &Pnacl_WrapperInfo_PPB_FileChooser_Dev_0_6, + &Pnacl_WrapperInfo_PPB_FileIO_Dev_0_1, &Pnacl_WrapperInfo_PPB_Font_Dev_0_6, &Pnacl_WrapperInfo_PPB_IMEInputEvent_Dev_0_1, &Pnacl_WrapperInfo_PPB_IMEInputEvent_Dev_0_2, diff --git a/ppapi/native_client/tools/browser_tester/browser_tester.py b/ppapi/native_client/tools/browser_tester/browser_tester.py index 0fef6ea671..e22bfde299 100755 --- a/ppapi/native_client/tools/browser_tester/browser_tester.py +++ b/ppapi/native_client/tools/browser_tester/browser_tester.py @@ -161,7 +161,7 @@ def ProcessToolLogs(options, logs_dir): analyzer = memcheck_analyze.MemcheckAnalyzer('', use_gdb=True) logs_wildcard = 'xml.*' elif options.tool == 'tsan': - analyzer = tsan_analyze.TsanAnalyzer('', use_gdb=True) + analyzer = tsan_analyze.TsanAnalyzer(use_gdb=True) logs_wildcard = 'log.*' files = glob.glob(os.path.join(logs_dir, logs_wildcard)) retcode = analyzer.Report(files, options.url) diff --git a/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py b/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py index 67ea29125e..c27ece5d60 100755 --- a/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py +++ b/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py @@ -294,6 +294,10 @@ class ChromeLauncher(BrowserLauncher): '--user-data-dir=%s' % self.profile] # Log network requests to assist debugging. cmd.append('--log-net-log=%s' % self.NetLogName()) + if PLATFORM == 'linux': + # Explicitly run with mesa on linux. The test infrastructure doesn't have + # sufficient native GL contextes to run these tests. + cmd.append('--use-gl=osmesa') if self.options.ppapi_plugin is None: cmd.append('--enable-nacl') disable_sandbox = False diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 267402d6f5..c078ef19ec 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -88,6 +88,8 @@ 'proxy/network_monitor_resource.h', 'proxy/network_proxy_resource.cc', 'proxy/network_proxy_resource.h', + 'proxy/output_protection_resource.cc', + 'proxy/output_protection_resource.h', 'proxy/pdf_resource.cc', 'proxy/pdf_resource.h', 'proxy/platform_verification_private_resource.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index 7edeb2f225..3931e0ef4d 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -157,7 +157,6 @@ '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', 'thunk/ppb_file_ref_thunk.cc', 'thunk/ppb_file_system_api.h', @@ -213,6 +212,8 @@ 'thunk/ppb_network_monitor_thunk.cc', 'thunk/ppb_network_proxy_api.h', 'thunk/ppb_network_proxy_thunk.cc', + 'thunk/ppb_output_protection_api.h', + 'thunk/ppb_output_protection_private_thunk.cc', 'thunk/ppb_pdf_api.h', 'thunk/ppb_pdf_thunk.cc', 'thunk/ppb_platform_verification_api.h', @@ -291,7 +292,6 @@ 'thunk/ppb_buffer_thunk.cc', 'thunk/ppb_content_decryptor_private_thunk.cc', 'thunk/ppb_char_set_thunk.cc', - 'thunk/ppb_file_io_trusted_thunk.cc', 'thunk/ppb_flash_clipboard_thunk.cc', 'thunk/ppb_flash_device_id_thunk.cc', 'thunk/ppb_flash_drm_thunk.cc', diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi index 6ec54b7000..bb141a6fa8 100644 --- a/ppapi/ppapi_sources.gypi +++ b/ppapi/ppapi_sources.gypi @@ -115,6 +115,7 @@ 'c/private/ppb_instance_private.h', 'c/private/ppb_nacl_private.h', 'c/private/ppb_net_address_private.h', + 'c/private/ppb_output_protection_private.h', 'c/private/ppb_pdf.h', 'c/private/ppb_platform_verification_private.h', 'c/private/ppb_proxy_private.h', @@ -136,7 +137,6 @@ 'c/trusted/ppb_broker_trusted.h', 'c/trusted/ppb_browser_font_trusted.h', 'c/trusted/ppb_file_chooser_trusted.h', - 'c/trusted/ppb_file_io_trusted.h', 'c/trusted/ppb_url_loader_trusted.h', 'c/trusted/ppp_broker.h', @@ -321,6 +321,8 @@ 'cpp/private/instance_private.h', 'cpp/private/net_address_private.cc', 'cpp/private/net_address_private.h', + 'cpp/private/output_protection_private.cc', + 'cpp/private/output_protection_private.h', 'cpp/private/pass_file_handle.cc', 'cpp/private/pass_file_handle.h', 'cpp/private/pdf.cc', @@ -349,8 +351,6 @@ 'cpp/trusted/browser_font_trusted.h', 'cpp/trusted/file_chooser_trusted.cc', 'cpp/trusted/file_chooser_trusted.h', - 'cpp/trusted/file_io_trusted.cc', - 'cpp/trusted/file_io_trusted.h', # Extensions interfaces. 'cpp/extensions/dict_field.h', @@ -450,6 +450,8 @@ 'tests/test_network_monitor.h', 'tests/test_network_proxy.cc', 'tests/test_network_proxy.h', + 'tests/test_output_protection_private.cc', + 'tests/test_output_protection_private.h', 'tests/test_paint_aggregator.cc', 'tests/test_paint_aggregator.h', 'tests/test_post_message.cc', diff --git a/ppapi/proxy/file_io_resource.cc b/ppapi/proxy/file_io_resource.cc index fc53fb0524..b1eb450479 100644 --- a/ppapi/proxy/file_io_resource.cc +++ b/ppapi/proxy/file_io_resource.cc @@ -43,24 +43,26 @@ void DoClose(base::PlatformFile file) { namespace ppapi { namespace proxy { -FileIOResource::QueryOp::QueryOp(PP_FileHandle file_handle) +FileIOResource::QueryOp::QueryOp(scoped_refptr<FileHandleHolder> file_handle) : file_handle_(file_handle) { + DCHECK(file_handle_); } FileIOResource::QueryOp::~QueryOp() { } int32_t FileIOResource::QueryOp::DoWork() { - return base::GetPlatformFileInfo(file_handle_, &file_info_) ? + return base::GetPlatformFileInfo(file_handle_->raw_handle(), &file_info_) ? PP_OK : PP_ERROR_FAILED; } -FileIOResource::ReadOp::ReadOp(PP_FileHandle file_handle, +FileIOResource::ReadOp::ReadOp(scoped_refptr<FileHandleHolder> file_handle, int64_t offset, int32_t bytes_to_read) : file_handle_(file_handle), offset_(offset), bytes_to_read_(bytes_to_read) { + DCHECK(file_handle_); } FileIOResource::ReadOp::~ReadOp() { @@ -70,18 +72,16 @@ int32_t FileIOResource::ReadOp::DoWork() { DCHECK(!buffer_.get()); buffer_.reset(new char[bytes_to_read_]); return base::ReadPlatformFile( - file_handle_, offset_, buffer_.get(), bytes_to_read_); + file_handle_->raw_handle(), offset_, buffer_.get(), bytes_to_read_); } FileIOResource::FileIOResource(Connection connection, PP_Instance instance) : PluginResource(connection, instance), - file_handle_(base::kInvalidPlatformFileValue), file_system_type_(PP_FILESYSTEMTYPE_INVALID) { SendCreate(RENDERER, PpapiHostMsg_FileIO_Create()); } FileIOResource::~FileIOResource() { - CloseFileHandle(); } PPB_FileIO_API* FileIOResource::AsPPB_FileIO_API() { @@ -134,7 +134,7 @@ int32_t FileIOResource::Query(PP_FileInfo* info, return rv; if (!info) return PP_ERROR_BADARGUMENT; - if (file_handle_ == base::kInvalidPlatformFileValue) + if (!FileHandleHolder::IsValid(file_handle_)) return PP_ERROR_FAILED; state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); @@ -154,7 +154,7 @@ int32_t FileIOResource::Query(PP_FileInfo* info, // For the non-blocking case, post a task to the file thread and add a // completion task to write the result. base::PostTaskAndReplyWithResult( - PpapiGlobals::Get()->GetFileTaskRunner(pp_instance()), + PpapiGlobals::Get()->GetFileTaskRunner(), FROM_HERE, Bind(&FileIOResource::QueryOp::DoWork, query_op), RunWhileLocked(Bind(&TrackedCallback::Run, callback))); @@ -262,18 +262,12 @@ int32_t FileIOResource::Flush(scoped_refptr<TrackedCallback> callback) { } void FileIOResource::Close() { - CloseFileHandle(); + if (file_handle_) { + file_handle_ = NULL; + } Post(RENDERER, PpapiHostMsg_FileIO_Close()); } -int32_t FileIOResource::GetOSFileDescriptor() { - int32_t file_descriptor; - // Only available when running in process. - SyncCall<PpapiPluginMsg_FileIO_GetOSFileDescriptorReply>( - RENDERER, PpapiHostMsg_FileIO_GetOSFileDescriptor(), &file_descriptor); - return file_descriptor; -} - int32_t FileIOResource::RequestOSFileHandle( PP_FileHandle* handle, scoped_refptr<TrackedCallback> callback) { @@ -291,25 +285,23 @@ int32_t FileIOResource::RequestOSFileHandle( return PP_OK_COMPLETIONPENDING; } -int32_t FileIOResource::WillWrite(int64_t offset, - int32_t bytes_to_write, - scoped_refptr<TrackedCallback> callback) { - Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, - PpapiHostMsg_FileIO_WillWrite(offset, bytes_to_write), - base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, callback)); - - state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); - return PP_OK_COMPLETIONPENDING; +FileIOResource::FileHandleHolder::FileHandleHolder(PP_FileHandle file_handle) + : raw_handle_(file_handle) { } -int32_t FileIOResource::WillSetLength(int64_t length, - scoped_refptr<TrackedCallback> callback) { - Call<PpapiPluginMsg_FileIO_GeneralReply>(RENDERER, - PpapiHostMsg_FileIO_WillSetLength(length), - base::Bind(&FileIOResource::OnPluginMsgGeneralComplete, this, callback)); +// static +bool FileIOResource::FileHandleHolder::IsValid( + const scoped_refptr<FileIOResource::FileHandleHolder>& handle) { + return handle && (handle->raw_handle() != base::kInvalidPlatformFileValue); +} - state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_EXCLUSIVE); - return PP_OK_COMPLETIONPENDING; +FileIOResource::FileHandleHolder::~FileHandleHolder() { + if (raw_handle_ != base::kInvalidPlatformFileValue) { + base::TaskRunner* file_task_runner = + PpapiGlobals::Get()->GetFileTaskRunner(); + file_task_runner->PostTask(FROM_HERE, + base::Bind(&DoClose, raw_handle_)); + } } int32_t FileIOResource::ReadValidated(int64_t offset, @@ -318,7 +310,7 @@ int32_t FileIOResource::ReadValidated(int64_t offset, scoped_refptr<TrackedCallback> callback) { if (bytes_to_read < 0) return PP_ERROR_FAILED; - if (file_handle_ == base::kInvalidPlatformFileValue) + if (!FileHandleHolder::IsValid(file_handle_)) return PP_ERROR_FAILED; state_manager_.SetPendingOperation(FileIOStateManager::OPERATION_READ); @@ -338,7 +330,7 @@ int32_t FileIOResource::ReadValidated(int64_t offset, // For the non-blocking case, post a task to the file thread. base::PostTaskAndReplyWithResult( - PpapiGlobals::Get()->GetFileTaskRunner(pp_instance()), + PpapiGlobals::Get()->GetFileTaskRunner(), FROM_HERE, Bind(&FileIOResource::ReadOp::DoWork, read_op), RunWhileLocked(Bind(&TrackedCallback::Run, callback))); @@ -348,18 +340,6 @@ int32_t FileIOResource::ReadValidated(int64_t offset, return PP_OK_COMPLETIONPENDING; } -void FileIOResource::CloseFileHandle() { - if (file_handle_ != base::kInvalidPlatformFileValue) { - // Close our local fd on the file thread. - base::TaskRunner* file_task_runner = - PpapiGlobals::Get()->GetFileTaskRunner(pp_instance()); - file_task_runner->PostTask(FROM_HERE, - base::Bind(&DoClose, file_handle_)); - - file_handle_ = base::kInvalidPlatformFileValue; - } -} - int32_t FileIOResource::OnQueryComplete(scoped_refptr<QueryOp> query_op, PP_FileInfo* info, int32_t result) { @@ -422,8 +402,10 @@ void FileIOResource::OnPluginMsgOpenFileComplete( int32_t result = params.result(); IPC::PlatformFileForTransit transit_file; - if ((result == PP_OK) && params.TakeFileHandleAtIndex(0, &transit_file)) - file_handle_ = IPC::PlatformFileForTransitToPlatformFile(transit_file); + if ((result == PP_OK) && params.TakeFileHandleAtIndex(0, &transit_file)) { + file_handle_ = new FileHandleHolder( + IPC::PlatformFileForTransitToPlatformFile(transit_file)); + } // End this operation now, so the user's callback can execute another FileIO // operation, assuming there are no other pending operations. state_manager_.SetOperationFinished(); diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h index 26c4abb948..5fc6370de3 100644 --- a/ppapi/proxy/file_io_resource.h +++ b/ppapi/proxy/file_io_resource.h @@ -7,6 +7,7 @@ #include <string> +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "ppapi/c/private/pp_file_handle.h" #include "ppapi/proxy/connection.h" @@ -57,22 +58,48 @@ class PPAPI_PROXY_EXPORT FileIOResource scoped_refptr<TrackedCallback> callback) OVERRIDE; 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; - virtual int32_t WillSetLength( - int64_t length, - scoped_refptr<TrackedCallback> callback) OVERRIDE; private: + // FileHandleHolder is used to guarantee that file operations will have a + // valid FD to operate on, even if they're in a different thread. + // If instead we just passed the raw FD, the FD could be closed before the + // file operation has a chance to run. It could interact with an invalid FD, + // or worse, the FD value could be reused if another file is opened quickly + // (POSIX is required to provide the lowest available value when opening a + // file). This could result in strange problems such as writing data to the + // wrong file. + // + // Operations that run on a background thread should hold one of these to + // ensure they have a valid file descriptor. The file handle is only closed + // when the last reference to the FileHandleHolder is removed, so we are + // guaranteed to operate on the correct file descriptor. It *is* still + // possible that the FileIOResource will be destroyed and "Abort" callbacks + // just before the operation does its task (e.g., Reading). In that case, we + // might for example Read from a file even though the FileIO has been + // destroyed and the plugin's callback got a PP_ERROR_ABORTED result. In the + // case of a write, we could write some data to the file despite the plugin + // receiving a PP_ERROR_ABORTED instead of a successful result. + class FileHandleHolder : public base::RefCountedThreadSafe<FileHandleHolder> { + public: + explicit FileHandleHolder(PP_FileHandle file_handle_); + PP_FileHandle raw_handle() { + return raw_handle_; + } + static bool IsValid( + const scoped_refptr<FileIOResource::FileHandleHolder>& handle); + private: + friend class base::RefCountedThreadSafe<FileHandleHolder>; + ~FileHandleHolder(); + PP_FileHandle raw_handle_; + }; + // Class to perform file query operations across multiple threads. class QueryOp : public base::RefCountedThreadSafe<QueryOp> { public: - explicit QueryOp(PP_FileHandle file_handle); + explicit QueryOp(scoped_refptr<FileHandleHolder> file_handle); // Queries the file. Called on the file thread (non-blocking) or the plugin // thread (blocking). This should not be called when we hold the proxy lock. @@ -84,14 +111,16 @@ class PPAPI_PROXY_EXPORT FileIOResource friend class base::RefCountedThreadSafe<QueryOp>; ~QueryOp(); - PP_FileHandle file_handle_; + scoped_refptr<FileHandleHolder> file_handle_; base::PlatformFileInfo file_info_; }; // Class to perform file read operations across multiple threads. class ReadOp : public base::RefCountedThreadSafe<ReadOp> { public: - ReadOp(PP_FileHandle file_handle, int64_t offset, int32_t bytes_to_read); + ReadOp(scoped_refptr<FileHandleHolder> file_handle, + int64_t offset, + int32_t bytes_to_read); // Reads the file. Called on the file thread (non-blocking) or the plugin // thread (blocking). This should not be called when we hold the proxy lock. @@ -103,7 +132,7 @@ class PPAPI_PROXY_EXPORT FileIOResource friend class base::RefCountedThreadSafe<ReadOp>; ~ReadOp(); - PP_FileHandle file_handle_; + scoped_refptr<FileHandleHolder> file_handle_; int64_t offset_; int32_t bytes_to_read_; scoped_ptr<char[]> buffer_; @@ -114,9 +143,6 @@ class PPAPI_PROXY_EXPORT FileIOResource const PP_ArrayOutput& array_output, scoped_refptr<TrackedCallback> callback); - void CloseFileHandle(); - - // Completion tasks for file operations that are done in the plugin. int32_t OnQueryComplete(scoped_refptr<QueryOp> query_op, PP_FileInfo* info, @@ -135,7 +161,7 @@ class PPAPI_PROXY_EXPORT FileIOResource PP_FileHandle* output_handle, const ResourceMessageReplyParams& params); - PP_FileHandle file_handle_; + scoped_refptr<FileHandleHolder> file_handle_; PP_FileSystemType file_system_type_; FileIOStateManager state_manager_; diff --git a/ppapi/proxy/file_system_resource.cc b/ppapi/proxy/file_system_resource.cc index bab771929a..af1928b4c6 100644 --- a/ppapi/proxy/file_system_resource.cc +++ b/ppapi/proxy/file_system_resource.cc @@ -23,12 +23,23 @@ FileSystemResource::FileSystemResource(Connection connection, called_open_(false), callback_count_(0) { DCHECK(type_ != PP_FILESYSTEMTYPE_INVALID); - // TODO(teravest): Temporarily create hosts in both the browser and renderer - // while we move file related hosts to the browser. SendCreate(RENDERER, PpapiHostMsg_FileSystem_Create(type_)); SendCreate(BROWSER, PpapiHostMsg_FileSystem_Create(type_)); } +FileSystemResource::FileSystemResource(Connection connection, + PP_Instance instance, + int pending_renderer_id, + int pending_browser_id, + PP_FileSystemType type) + : PluginResource(connection, instance), + type_(type), + called_open_(true) { + DCHECK(type_ != PP_FILESYSTEMTYPE_INVALID); + AttachToPendingHost(RENDERER, pending_renderer_id); + AttachToPendingHost(BROWSER, pending_browser_id); +} + FileSystemResource::~FileSystemResource() { } diff --git a/ppapi/proxy/file_system_resource.h b/ppapi/proxy/file_system_resource.h index 74677f724e..a716434333 100644 --- a/ppapi/proxy/file_system_resource.h +++ b/ppapi/proxy/file_system_resource.h @@ -25,9 +25,19 @@ class PPAPI_PROXY_EXPORT FileSystemResource : public PluginResource, public NON_EXPORTED_BASE(thunk::PPB_FileSystem_API) { public: + // Creates a new FileSystemResource. The resource must be subsequently opened + // via Open() before use. FileSystemResource(Connection connection, PP_Instance instance, PP_FileSystemType type); + // Creates a FileSystemResource, attached to an existing pending host + // resource. The |pending_renderer_id| and |pending_browser_id| must be + // already-opened file systems. + FileSystemResource(Connection connection, + PP_Instance instance, + int pending_renderer_id, + int pending_browser_id, + PP_FileSystemType type); virtual ~FileSystemResource(); // Resource overrides. diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc index 9c810a350c..57fe2196a6 100644 --- a/ppapi/proxy/interface_list.cc +++ b/ppapi/proxy/interface_list.cc @@ -81,6 +81,7 @@ #include "ppapi/c/private/ppb_flash_print.h" #include "ppapi/c/private/ppb_host_resolver_private.h" #include "ppapi/c/private/ppb_net_address_private.h" +#include "ppapi/c/private/ppb_output_protection_private.h" #include "ppapi/c/private/ppb_pdf.h" #include "ppapi/c/private/ppb_platform_verification_private.h" #include "ppapi/c/private/ppb_talk_private.h" @@ -95,7 +96,6 @@ #include "ppapi/c/trusted/ppb_browser_font_trusted.h" #include "ppapi/c/trusted/ppb_char_set_trusted.h" #include "ppapi/c/trusted/ppb_file_chooser_trusted.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/ppb_audio_proxy.h" diff --git a/ppapi/proxy/output_protection_resource.cc b/ppapi/proxy/output_protection_resource.cc new file mode 100644 index 0000000000..8f601de453 --- /dev/null +++ b/ppapi/proxy/output_protection_resource.cc @@ -0,0 +1,105 @@ +// Copyright 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/proxy/output_protection_resource.h" + +#include "base/logging.h" +#include "ppapi/proxy/plugin_globals.h" +#include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/proxy_lock.h" +#include "ppapi/shared_impl/resource_tracker.h" +#include "ppapi/shared_impl/tracked_callback.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_output_protection_api.h" + +namespace ppapi { +namespace proxy { + +OutputProtectionResource::OutputProtectionResource( + Connection connection, + PP_Instance instance) + : PluginResource(connection, instance) { + SendCreate(BROWSER, PpapiHostMsg_OutputProtection_Create()); +} + +OutputProtectionResource::~OutputProtectionResource() { + if (TrackedCallback::IsPending(query_status_callback_)) + query_status_callback_->PostAbort(); + if (TrackedCallback::IsPending(enable_protection_callback_)) + enable_protection_callback_->PostAbort(); +} + +thunk::PPB_OutputProtection_API* + OutputProtectionResource::AsPPB_OutputProtection_API() { + return this; +} + +int32_t OutputProtectionResource::QueryStatus( + uint32_t* link_mask, + uint32_t* protection_mask, + const scoped_refptr<TrackedCallback>& callback) { + if (!link_mask || !protection_mask) + return PP_ERROR_BADARGUMENT; + if (TrackedCallback::IsPending(query_status_callback_)) + return PP_ERROR_INPROGRESS; + + query_status_callback_ = callback; + + Call<PpapiPluginMsg_OutputProtection_QueryStatusReply>( + BROWSER, + PpapiHostMsg_OutputProtection_QueryStatus(), + base::Bind(&OutputProtectionResource::OnPluginMsgQueryStatusReply, + base::Unretained(this), + link_mask, + protection_mask)); + return PP_OK_COMPLETIONPENDING; +} + +void OutputProtectionResource::OnPluginMsgQueryStatusReply( + uint32_t* out_link_mask, + uint32_t* out_protection_mask, + const ResourceMessageReplyParams& params, + uint32_t link_mask, + uint32_t protection_mask) { + // The callback may have been aborted. + if (!TrackedCallback::IsPending(query_status_callback_)) + return; + + int32_t result = params.result(); + + if (result == PP_OK) { + DCHECK(out_link_mask); + DCHECK(out_protection_mask); + *out_link_mask = link_mask; + *out_protection_mask = protection_mask; + } + query_status_callback_->Run(result); +} + +int32_t OutputProtectionResource::EnableProtection( + uint32_t desired_method_mask, + const scoped_refptr<TrackedCallback>& callback) { + if (TrackedCallback::IsPending(enable_protection_callback_)) + return PP_ERROR_INPROGRESS; + + enable_protection_callback_ = callback; + + Call<PpapiPluginMsg_OutputProtection_EnableProtectionReply>( + BROWSER, + PpapiHostMsg_OutputProtection_EnableProtection(desired_method_mask), + base::Bind(&OutputProtectionResource::OnPluginMsgEnableProtectionReply, + base::Unretained(this))); + return PP_OK_COMPLETIONPENDING; +} + +void OutputProtectionResource::OnPluginMsgEnableProtectionReply( + const ResourceMessageReplyParams& params) { + // The callback may have been aborted. + if (TrackedCallback::IsPending(enable_protection_callback_)) + enable_protection_callback_->Run(params.result()); +} + +} // namespace proxy +} // namespace ppapi diff --git a/ppapi/proxy/output_protection_resource.h b/ppapi/proxy/output_protection_resource.h new file mode 100644 index 0000000000..b56a33d7b2 --- /dev/null +++ b/ppapi/proxy/output_protection_resource.h @@ -0,0 +1,58 @@ +// Copyright 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_PROXY_OUTPUT_PROTECTION_RESOURCE_H_ +#define PPAPI_PROXY_OUTPUT_PROTECTION_RESOURCE_H_ + +#include "base/compiler_specific.h" +#include "ppapi/c/private/ppb_output_protection_private.h" +#include "ppapi/proxy/device_enumeration_resource_helper.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/thunk/ppb_output_protection_api.h" + +namespace ppapi { +namespace proxy { + +class OutputProtectionResource + : public PluginResource, + public ::ppapi::thunk::PPB_OutputProtection_API { + public: + OutputProtectionResource(Connection connection, + PP_Instance instance); + + private: + virtual ~OutputProtectionResource(); + + // PluginResource overrides. + virtual thunk::PPB_OutputProtection_API* AsPPB_OutputProtection_API() + OVERRIDE; + + // PPB_OutputProtection_API implementation. + virtual int32_t QueryStatus( + uint32_t* link_mask, + uint32_t* protection_mask, + const scoped_refptr<TrackedCallback>& callback) OVERRIDE; + virtual int32_t EnableProtection( + uint32_t desired_method_mask, + const scoped_refptr<TrackedCallback>& callback) OVERRIDE; + + void OnPluginMsgQueryStatusReply( + uint32_t* out_link_mask, + uint32_t* out_protection_mask, + const ResourceMessageReplyParams& params, + uint32_t link_mask, + uint32_t protection_mask); + void OnPluginMsgEnableProtectionReply( + const ResourceMessageReplyParams& params); + + scoped_refptr<TrackedCallback> query_status_callback_; + scoped_refptr<TrackedCallback> enable_protection_callback_; + + DISALLOW_COPY_AND_ASSIGN(OutputProtectionResource); +}; + +} // namespace proxy +} // namespace ppapi + +#endif // PPAPI_PROXY_OUTPUT_PROTECTION_RESOURCE_H_ diff --git a/ppapi/proxy/plugin_globals.cc b/ppapi/proxy/plugin_globals.cc index 83217f0d96..fa5530e439 100644 --- a/ppapi/proxy/plugin_globals.cc +++ b/ppapi/proxy/plugin_globals.cc @@ -150,7 +150,7 @@ MessageLoopShared* PluginGlobals::GetCurrentMessageLoop() { return MessageLoopResource::GetCurrent(); } -base::TaskRunner* PluginGlobals::GetFileTaskRunner(PP_Instance instance) { +base::TaskRunner* PluginGlobals::GetFileTaskRunner() { if (!file_thread_.get()) { file_thread_.reset(new base::Thread("Plugin::File")); base::Thread::Options options; diff --git a/ppapi/proxy/plugin_globals.h b/ppapi/proxy/plugin_globals.h index 31adef5584..bc55245d61 100644 --- a/ppapi/proxy/plugin_globals.h +++ b/ppapi/proxy/plugin_globals.h @@ -72,7 +72,7 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals { const std::string& source, const std::string& value) OVERRIDE; virtual MessageLoopShared* GetCurrentMessageLoop() OVERRIDE; - base::TaskRunner* GetFileTaskRunner(PP_Instance instance) OVERRIDE; + base::TaskRunner* GetFileTaskRunner() OVERRIDE; // Returns the channel for sending to the browser. IPC::Sender* GetBrowserSender(); diff --git a/ppapi/proxy/plugin_main_nacl.cc b/ppapi/proxy/plugin_main_nacl.cc index 5978233a53..f050778227 100644 --- a/ppapi/proxy/plugin_main_nacl.cc +++ b/ppapi/proxy/plugin_main_nacl.cc @@ -215,6 +215,12 @@ void PpapiDispatcher::OnMsgCreateNaClChannel( ppapi::proxy::InterfaceList::SetProcessGlobalPermissions( args.permissions); + int32_t error = ::PPP_InitializeModule( + 0 /* module */, + &ppapi::proxy::PluginDispatcher::GetBrowserInterface); + if (error) + ::exit(error); + PluginDispatcher* dispatcher = new PluginDispatcher(::PPP_GetInterface, args.permissions, args.off_the_record); @@ -280,13 +286,6 @@ int PpapiPluginMain() { return 1; } - int32_t error = ::PPP_InitializeModule( - 0 /* module */, - &ppapi::proxy::PluginDispatcher::GetBrowserInterface); - // TODO(dmichael): Handle other error conditions, like failure to connect? - if (error) - return error; - PpapiDispatcher ppapi_dispatcher(io_thread.message_loop_proxy()); plugin_globals.set_plugin_proxy_delegate(&ppapi_dispatcher); diff --git a/ppapi/proxy/plugin_resource_var.cc b/ppapi/proxy/plugin_resource_var.cc index 0ccff749e4..be4eec5b67 100644 --- a/ppapi/proxy/plugin_resource_var.cc +++ b/ppapi/proxy/plugin_resource_var.cc @@ -10,7 +10,7 @@ PluginResourceVar::PluginResourceVar(ppapi::Resource* resource) : resource_(resource) {} PP_Resource PluginResourceVar::GetPPResource() const { - return resource_->pp_resource(); + return resource_ ? resource_->pp_resource() : 0; } bool PluginResourceVar::IsPending() const { diff --git a/ppapi/proxy/plugin_resource_var.h b/ppapi/proxy/plugin_resource_var.h index b02718b6a9..42be66d219 100644 --- a/ppapi/proxy/plugin_resource_var.h +++ b/ppapi/proxy/plugin_resource_var.h @@ -31,6 +31,7 @@ class PPAPI_PROXY_EXPORT PluginResourceVar : public ppapi::ResourceVar { virtual ~PluginResourceVar(); private: + // If NULL, this represents the PP_Resource 0. scoped_refptr<ppapi::Resource> resource_; DISALLOW_COPY_AND_ASSIGN(PluginResourceVar); diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc index d4ab09dd1a..0788b99923 100644 --- a/ppapi/proxy/plugin_var_tracker.cc +++ b/ppapi/proxy/plugin_var_tracker.cc @@ -155,8 +155,13 @@ void PluginVarTracker::ReleaseHostObject(PluginDispatcher* dispatcher, } ResourceVar* PluginVarTracker::MakeResourceVar(PP_Resource pp_resource) { + // The resource 0 returns a null resource var. + if (!pp_resource) + return new PluginResourceVar(); + ResourceTracker* resource_tracker = PpapiGlobals::Get()->GetResourceTracker(); ppapi::Resource* resource = resource_tracker->GetResource(pp_resource); + // A non-existant resource other than 0 returns NULL. if (!resource) return NULL; return new PluginResourceVar(resource); diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc index 8ca17e442d..9ea9d69377 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.cc +++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc @@ -8,6 +8,7 @@ #include "ppapi/proxy/proxy_channel.h" #include "ppapi/shared_impl/api_id.h" #include "ppapi/shared_impl/host_resource.h" +#include "ppapi/shared_impl/proxy_lock.h" namespace ppapi { namespace proxy { @@ -29,32 +30,6 @@ PpapiCommandBufferProxy::~PpapiCommandBufferProxy() { } } -void PpapiCommandBufferProxy::ReportChannelError() { - if (!channel_error_callback_.is_null()) { - channel_error_callback_.Run(); - channel_error_callback_.Reset(); - } -} - -int PpapiCommandBufferProxy::GetRouteID() const { - NOTIMPLEMENTED(); - return 0; -} - -bool PpapiCommandBufferProxy::Echo(const base::Closure& callback) { - return false; -} - -bool PpapiCommandBufferProxy::ProduceFrontBuffer(const gpu::Mailbox& mailbox) { - NOTIMPLEMENTED(); - return false; -} - -void PpapiCommandBufferProxy::SetChannelErrorCallback( - const base::Closure& callback) { - channel_error_callback_ = callback; -} - bool PpapiCommandBufferProxy::Initialize() { return true; } @@ -74,14 +49,12 @@ gpu::CommandBuffer::State PpapiCommandBufferProxy::GetState() { } gpu::CommandBuffer::State PpapiCommandBufferProxy::GetLastState() { - // Note: The locking command buffer wrapper does not take a global lock before - // calling this function. + ppapi::ProxyLock::AssertAcquiredDebugOnly(); return last_state_; } int32 PpapiCommandBufferProxy::GetLastToken() { - // Note: The locking command buffer wrapper does not take a global lock before - // calling this function. + ppapi::ProxyLock::AssertAcquiredDebugOnly(); return last_state_.token; } @@ -230,6 +203,42 @@ uint32 PpapiCommandBufferProxy::InsertSyncPoint() { return sync_point; } +void PpapiCommandBufferProxy::SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) { + NOTREACHED(); +} + +void PpapiCommandBufferProxy::SignalQuery(uint32 query, + const base::Closure& callback) { + NOTREACHED(); +} + +bool PpapiCommandBufferProxy::SupportsGpuMemoryBuffer() { + return false; +} + +gfx::GpuMemoryBuffer* PpapiCommandBufferProxy::CreateGpuMemoryBuffer( + size_t width, + size_t height, + unsigned internalformat, + int32* id) { + NOTREACHED(); + return NULL; +} + +void PpapiCommandBufferProxy::DestroyGpuMemoryBuffer(int32 id) { + NOTREACHED(); +} + +bool PpapiCommandBufferProxy::GenerateMailboxNames( + unsigned num, std::vector<gpu::Mailbox>* names) { + // TODO(piman): implement this so we can expose mailboxes to pepper + // eventually. + NOTREACHED(); + return false; +} + + bool PpapiCommandBufferProxy::Send(IPC::Message* msg) { DCHECK(last_state_.error == gpu::error::kNoError); diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h index b5c2c93081..430054dd9e 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.h +++ b/ppapi/proxy/ppapi_command_buffer_proxy.h @@ -8,7 +8,7 @@ #include "base/callback.h" #include "base/containers/hash_tables.h" #include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/ipc/command_buffer_proxy.h" +#include "gpu/command_buffer/common/gpu_control.h" #include "ppapi/proxy/ppapi_proxy_export.h" #include "ppapi/shared_impl/host_resource.h" @@ -21,36 +21,46 @@ namespace proxy { class ProxyChannel; -class PPAPI_PROXY_EXPORT PpapiCommandBufferProxy : public CommandBufferProxy { +class PPAPI_PROXY_EXPORT PpapiCommandBufferProxy + : public gpu::CommandBuffer, + public gpu::GpuControl { public: PpapiCommandBufferProxy(const HostResource& resource, ProxyChannel* channel); virtual ~PpapiCommandBufferProxy(); - void ReportChannelError(); - - // CommandBufferProxy implementation: - virtual int GetRouteID() const OVERRIDE; - virtual bool Echo(const base::Closure& callback) OVERRIDE; - virtual bool ProduceFrontBuffer(const gpu::Mailbox& mailbox) OVERRIDE; - virtual void SetChannelErrorCallback(const base::Closure& callback) OVERRIDE; - // gpu::CommandBuffer implementation: - virtual bool Initialize(); - virtual State GetState(); - virtual State GetLastState(); - virtual int32 GetLastToken(); - virtual void Flush(int32 put_offset); - virtual State FlushSync(int32 put_offset, int32 last_known_get); - virtual void SetGetBuffer(int32 transfer_buffer_id); - virtual void SetGetOffset(int32 get_offset); - virtual gpu::Buffer CreateTransferBuffer(size_t size, int32* id); - virtual void DestroyTransferBuffer(int32 id); - virtual gpu::Buffer GetTransferBuffer(int32 id); - virtual void SetToken(int32 token); - virtual void SetParseError(gpu::error::Error error); - virtual void SetContextLostReason(gpu::error::ContextLostReason reason); - virtual uint32 InsertSyncPoint(); + virtual bool Initialize() OVERRIDE; + virtual State GetState() OVERRIDE; + virtual State GetLastState() OVERRIDE; + virtual int32 GetLastToken() OVERRIDE; + virtual void Flush(int32 put_offset) OVERRIDE; + virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE; + virtual void SetGetBuffer(int32 transfer_buffer_id) OVERRIDE; + virtual void SetGetOffset(int32 get_offset) OVERRIDE; + virtual gpu::Buffer CreateTransferBuffer(size_t size, int32* id) OVERRIDE; + virtual void DestroyTransferBuffer(int32 id) OVERRIDE; + virtual gpu::Buffer GetTransferBuffer(int32 id) OVERRIDE; + virtual void SetToken(int32 token) OVERRIDE; + virtual void SetParseError(gpu::error::Error error) OVERRIDE; + virtual void SetContextLostReason(gpu::error::ContextLostReason reason) + OVERRIDE; + + // gpu::GpuControl implementation: + virtual bool SupportsGpuMemoryBuffer() OVERRIDE; + virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer( + size_t width, + size_t height, + unsigned internalformat, + int32* id) OVERRIDE; + virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE; + virtual bool GenerateMailboxNames(unsigned num, + std::vector<gpu::Mailbox>* names) OVERRIDE; + virtual uint32 InsertSyncPoint() OVERRIDE; + virtual void SignalSyncPoint(uint32 sync_point, + const base::Closure& callback) OVERRIDE; + virtual void SignalQuery(uint32 query, + const base::Closure& callback) OVERRIDE; private: bool Send(IPC::Message* msg); diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 2a2533fbfb..e7966a4f7d 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -1220,14 +1220,6 @@ IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_Write, IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_SetLength, int64_t /* length */) IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileIO_Flush) -IPC_MESSAGE_CONTROL2(PpapiHostMsg_FileIO_WillWrite, - int64_t /* offset */, - int32_t /* bytes_to_write */) -IPC_MESSAGE_CONTROL1(PpapiHostMsg_FileIO_WillSetLength, - int64_t /* length */) -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) @@ -1707,6 +1699,17 @@ IPC_MESSAGE_CONTROL4(PpapiPluginMsg_WebSocket_ClosedReply, uint16_t /* code */, std::string /* reason */) +// OutputProtection ----------------------------------------------------------- + +IPC_MESSAGE_CONTROL0(PpapiHostMsg_OutputProtection_Create) +IPC_MESSAGE_CONTROL1(PpapiHostMsg_OutputProtection_EnableProtection, + uint32_t /* desired_method_mask */) +IPC_MESSAGE_CONTROL0(PpapiPluginMsg_OutputProtection_EnableProtectionReply) +IPC_MESSAGE_CONTROL0(PpapiHostMsg_OutputProtection_QueryStatus) +IPC_MESSAGE_CONTROL2(PpapiPluginMsg_OutputProtection_QueryStatusReply, + uint32_t /* link_mask */, + uint32_t /* protection_mask */) + #if !defined(OS_NACL) && !defined(NACL_WIN64) // Audio input. diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.cc b/ppapi/proxy/ppb_graphics_3d_proxy.cc index 204466baf6..02e06f76b8 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_3d_proxy.cc @@ -12,7 +12,6 @@ #include "ppapi/proxy/ppapi_command_buffer_proxy.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/ppapi_globals.h" -#include "ppapi/shared_impl/proxy_lock.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/resource_creation_api.h" #include "ppapi/thunk/thunk.h" @@ -53,137 +52,12 @@ gpu::CommandBuffer::State GetErrorState() { } // namespace -// This class just wraps a CommandBuffer and optionally locks around every -// method. This is used to ensure that we have the Proxy lock any time we enter -// PpapiCommandBufferProxy. -// -// Note, for performance reasons, most of this code is not truly thread -// safe in the sense of multiple threads concurrently rendering to the same -// Graphics3D context; this isn't allowed, and will likely either crash or -// result in undefined behavior. It is assumed that the thread which creates -// the Graphics3D context will be the thread on which subsequent gl rendering -// will be done. This is why it is okay to read need_to_lock_ without the lock; -// it should only ever be read and written on the same thread where the context -// was created. -// -// TODO(nfullagar): At some point, allow multiple threads to concurrently render -// each to its own context. First step is to allow a single thread (either main -// thread or background thread) to render to a single Graphics3D context. -class Graphics3D::LockingCommandBuffer : public gpu::CommandBuffer { - public: - explicit LockingCommandBuffer(gpu::CommandBuffer* gpu_command_buffer) - : gpu_command_buffer_(gpu_command_buffer), need_to_lock_(true) { - } - virtual ~LockingCommandBuffer() { - } - void set_need_to_lock(bool need_to_lock) { need_to_lock_ = need_to_lock; } - bool need_to_lock() const { return need_to_lock_; } - - private: - // MaybeLock acquires the proxy lock on construction if and only if - // need_to_lock is true. If it acquired the lock, it releases it on - // destruction. If need_to_lock is false, then the lock must already be held. - struct MaybeLock { - explicit MaybeLock(bool need_to_lock) : locked_(need_to_lock) { - if (need_to_lock) - ppapi::ProxyLock::Acquire(); - else - ppapi::ProxyLock::AssertAcquired(); - } - ~MaybeLock() { - if (locked_) - ppapi::ProxyLock::Release(); - } - private: - bool locked_; - }; - - // gpu::CommandBuffer implementation: - virtual bool Initialize() OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->Initialize(); - } - virtual State GetState() OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->GetState(); - } - virtual State GetLastState() OVERRIDE { - // During a normal scene, the vast majority of calls are to GetLastState(). - // We don't allow multi-threaded rendering on the same contex, so for - // performance reasons, avoid the global lock for this entry point. We can - // get away with this here because the underlying implementation of - // GetLastState() is trivial and does not involve global or shared state - // between other contexts. - // TODO(nfullagar): We can probably skip MaybeLock for other methods, but - // the performance gain may not be worth it. - // - // MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->GetLastState(); - } - virtual int32 GetLastToken() OVERRIDE { - return GetLastState().token; - } - virtual void Flush(int32 put_offset) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->Flush(put_offset); - } - virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->FlushSync(put_offset, last_known_get); - } - virtual void SetGetBuffer(int32 transfer_buffer_id) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetGetBuffer(transfer_buffer_id); - } - virtual void SetGetOffset(int32 get_offset) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetGetOffset(get_offset); - } - virtual gpu::Buffer CreateTransferBuffer(size_t size, - int32* id) OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->CreateTransferBuffer(size, id); - } - virtual void DestroyTransferBuffer(int32 id) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->DestroyTransferBuffer(id); - } - virtual gpu::Buffer GetTransferBuffer(int32 id) OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->GetTransferBuffer(id); - } - virtual void SetToken(int32 token) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetToken(token); - } - virtual void SetParseError(gpu::error::Error error) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetParseError(error); - } - virtual void SetContextLostReason( - gpu::error::ContextLostReason reason) OVERRIDE { - MaybeLock lock(need_to_lock_); - gpu_command_buffer_->SetContextLostReason(reason); - } - virtual uint32 InsertSyncPoint() OVERRIDE { - MaybeLock lock(need_to_lock_); - return gpu_command_buffer_->InsertSyncPoint(); - } - - // Weak pointer - see class Graphics3D for the scopted_ptr. - gpu::CommandBuffer* gpu_command_buffer_; - - bool need_to_lock_; -}; - Graphics3D::Graphics3D(const HostResource& resource) - : PPB_Graphics3D_Shared(resource), - num_already_locked_calls_(0) { + : PPB_Graphics3D_Shared(resource) { } Graphics3D::~Graphics3D() { - if (gles2_impl()) - DestroyGLES2Impl(); + DestroyGLES2Impl(); } bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) { @@ -193,10 +67,7 @@ bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) { command_buffer_.reset( new PpapiCommandBufferProxy(host_resource(), dispatcher)); - locking_command_buffer_.reset( - new LockingCommandBuffer(command_buffer_.get())); - ScopedNoLocking already_locked(this); return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize, share_gles2); } @@ -242,14 +113,14 @@ uint32_t Graphics3D::InsertSyncPoint() { } gpu::CommandBuffer* Graphics3D::GetCommandBuffer() { - return locking_command_buffer_.get(); + return command_buffer_.get(); } -int32 Graphics3D::DoSwapBuffers() { - // gles2_impl()->SwapBuffers() results in CommandBuffer calls, and we already - // have the proxy lock. - ScopedNoLocking already_locked(this); +gpu::GpuControl* Graphics3D::GetGpuControl() { + return command_buffer_.get(); +} +int32 Graphics3D::DoSwapBuffers() { gles2_impl()->SwapBuffers(); IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers( API_ID_PPB_GRAPHICS_3D, host_resource()); @@ -259,31 +130,6 @@ int32 Graphics3D::DoSwapBuffers() { return PP_OK_COMPLETIONPENDING; } -void Graphics3D::PushAlreadyLocked() { - ppapi::ProxyLock::AssertAcquired(); - if (!locking_command_buffer_) { - NOTREACHED(); - return; - } - if (num_already_locked_calls_ == 0) - locking_command_buffer_->set_need_to_lock(false); - ++num_already_locked_calls_; -} - -void Graphics3D::PopAlreadyLocked() { - // We must have Pushed before we can Pop. - DCHECK(!locking_command_buffer_->need_to_lock()); - DCHECK_GT(num_already_locked_calls_, 0); - ppapi::ProxyLock::AssertAcquired(); - if (!locking_command_buffer_) { - NOTREACHED(); - return; - } - --num_already_locked_calls_; - if (num_already_locked_calls_ == 0) - locking_command_buffer_->set_need_to_lock(true); -} - PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher) : InterfaceProxy(dispatcher), callback_factory_(this) { diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.h b/ppapi/proxy/ppb_graphics_3d_proxy.h index ffda80c754..18ba9dd5e3 100644 --- a/ppapi/proxy/ppb_graphics_3d_proxy.h +++ b/ppapi/proxy/ppb_graphics_3d_proxy.h @@ -24,6 +24,7 @@ class HostResource; namespace proxy { class SerializedHandle; +class PpapiCommandBufferProxy; class Graphics3D : public PPB_Graphics3D_Shared { public: @@ -48,17 +49,12 @@ class Graphics3D : public PPB_Graphics3D_Shared { virtual uint32_t InsertSyncPoint() OVERRIDE; private: - class LockingCommandBuffer; - // PPB_Graphics3D_Shared overrides. virtual gpu::CommandBuffer* GetCommandBuffer() OVERRIDE; + virtual gpu::GpuControl* GetGpuControl() OVERRIDE; virtual int32 DoSwapBuffers() OVERRIDE; - virtual void PushAlreadyLocked() OVERRIDE; - virtual void PopAlreadyLocked() OVERRIDE; - int num_already_locked_calls_; - scoped_ptr<gpu::CommandBuffer> command_buffer_; - scoped_ptr<LockingCommandBuffer> locking_command_buffer_; + scoped_ptr<PpapiCommandBufferProxy> command_buffer_; DISALLOW_COPY_AND_ASSIGN(Graphics3D); }; diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc index 0ed3c24a37..c9d61f9fea 100644 --- a/ppapi/proxy/ppb_image_data_proxy.cc +++ b/ppapi/proxy/ppb_image_data_proxy.cc @@ -249,15 +249,15 @@ class ImageDataCache { // Timer callback to expire entries for the given instance. void OnTimer(PP_Instance instance); + typedef std::map<PP_Instance, ImageDataInstanceCache> CacheMap; + CacheMap cache_; + // This class does timer calls and we don't want to run these outside of the // scope of the object. Technically, since this class is a leaked static, // this will never happen and this factory is unnecessary. However, it's // probably better not to make assumptions about the lifetime of this class. base::WeakPtrFactory<ImageDataCache> weak_factory_; - typedef std::map<PP_Instance, ImageDataInstanceCache> CacheMap; - CacheMap cache_; - DISALLOW_COPY_AND_ASSIGN(ImageDataCache); }; diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.cc b/ppapi/proxy/ppb_var_deprecated_proxy.cc index 43452ef019..212a839a4e 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.cc +++ b/ppapi/proxy/ppb_var_deprecated_proxy.cc @@ -285,8 +285,8 @@ InterfaceProxy* CreateVarDeprecatedProxy(Dispatcher* dispatcher) { PPB_Var_Deprecated_Proxy::PPB_Var_Deprecated_Proxy( Dispatcher* dispatcher) : InterfaceProxy(dispatcher), - task_factory_(this), - ppb_var_impl_(NULL) { + ppb_var_impl_(NULL), + task_factory_(this) { if (!dispatcher->IsPlugin()) { ppb_var_impl_ = static_cast<const PPB_Var_Deprecated*>( dispatcher->local_get_interface()(PPB_VAR_DEPRECATED_INTERFACE)); diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.h b/ppapi/proxy/ppb_var_deprecated_proxy.h index 59400aede6..195c29afe3 100644 --- a/ppapi/proxy/ppb_var_deprecated_proxy.h +++ b/ppapi/proxy/ppb_var_deprecated_proxy.h @@ -89,10 +89,11 @@ class PPB_Var_Deprecated_Proxy : public InterfaceProxy { void SetAllowPluginReentrancy(); void DoReleaseObject(int64 object_id); - base::WeakPtrFactory<PPB_Var_Deprecated_Proxy> task_factory_; const PPB_Var_Deprecated* ppb_var_impl_; + base::WeakPtrFactory<PPB_Var_Deprecated_Proxy> task_factory_; + DISALLOW_COPY_AND_ASSIGN(PPB_Var_Deprecated_Proxy); }; diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index d1b99ecb01..7ee761bad3 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -21,6 +21,7 @@ #include "ppapi/proxy/host_resolver_resource.h" #include "ppapi/proxy/net_address_resource.h" #include "ppapi/proxy/network_monitor_resource.h" +#include "ppapi/proxy/output_protection_resource.h" #include "ppapi/proxy/platform_verification_private_resource.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_globals.h" @@ -313,6 +314,12 @@ PP_Resource ResourceCreationProxy::CreateNetworkMonitor( GetReference(); } +PP_Resource ResourceCreationProxy::CreateOutputProtectionPrivate( + PP_Instance instance) { + return (new OutputProtectionResource(GetConnection(), instance))-> + GetReference(); +} + PP_Resource ResourceCreationProxy::CreatePrinting(PP_Instance instance) { return (new PrintingResource(GetConnection(), instance))->GetReference(); } diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h index 1507dc8c6c..df564da7ca 100644 --- a/ppapi/proxy/resource_creation_proxy.h +++ b/ppapi/proxy/resource_creation_proxy.h @@ -134,6 +134,8 @@ class ResourceCreationProxy : public InterfaceProxy, PP_Instance instance, const PP_NetAddress_Private& private_addr) OVERRIDE; virtual PP_Resource CreateNetworkMonitor(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateOutputProtectionPrivate( + PP_Instance instance) OVERRIDE; virtual PP_Resource CreatePrinting(PP_Instance) OVERRIDE; virtual PP_Resource CreateTCPServerSocketPrivate( PP_Instance instance) OVERRIDE; diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h index fdc939a288..93ab2998e3 100644 --- a/ppapi/shared_impl/ppapi_globals.h +++ b/ppapi/shared_impl/ppapi_globals.h @@ -115,7 +115,7 @@ class PPAPI_SHARED_EXPORT PpapiGlobals { // Returns a task runner for file operations that may block. // TODO(bbudge) Move this to PluginGlobals when we no longer support // in-process plugins. - virtual base::TaskRunner* GetFileTaskRunner(PP_Instance instance) = 0; + virtual base::TaskRunner* GetFileTaskRunner() = 0; // Returns the command line for the process. virtual std::string GetCmdLine() = 0; diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.cc b/ppapi/shared_impl/ppb_graphics_3d_shared.cc index e24a13c461..0f39663d6e 100644 --- a/ppapi/shared_impl/ppb_graphics_3d_shared.cc +++ b/ppapi/shared_impl/ppb_graphics_3d_shared.cc @@ -50,7 +50,6 @@ int32_t PPB_Graphics3D_Shared::ResizeBuffers(int32_t width, int32_t height) { if ((width < 0) || (height < 0)) return PP_ERROR_BADARGUMENT; - ScopedNoLocking already_locked(this); gles2_impl()->ResizeCHROMIUM(width, height, 1.f); // TODO(alokp): Check if resize succeeded and return appropriate error code. return PP_OK; @@ -58,7 +57,6 @@ int32_t PPB_Graphics3D_Shared::ResizeBuffers(int32_t width, int32_t height) { int32_t PPB_Graphics3D_Shared::SwapBuffers( scoped_refptr<TrackedCallback> callback) { - ScopedNoLocking already_locked(this); if (HasPendingSwap()) { Log(PP_LOGLEVEL_ERROR, "PPB_Graphics3D.SwapBuffers: Plugin attempted swap " "with previous swap still pending."); @@ -85,13 +83,11 @@ void* PPB_Graphics3D_Shared::MapTexSubImage2DCHROMIUM(GLenum target, GLenum format, GLenum type, GLenum access) { - ScopedNoLocking already_locked(this); return gles2_impl_->MapTexSubImage2DCHROMIUM( target, level, xoffset, yoffset, width, height, format, type, access); } void PPB_Graphics3D_Shared::UnmapTexSubImage2DCHROMIUM(const void* mem) { - ScopedNoLocking already_locked(this); gles2_impl_->UnmapTexSubImage2DCHROMIUM(mem); } @@ -108,7 +104,6 @@ bool PPB_Graphics3D_Shared::CreateGLES2Impl( int32 command_buffer_size, int32 transfer_buffer_size, gpu::gles2::GLES2Implementation* share_gles2) { - ScopedNoLocking already_locked(this); gpu::CommandBuffer* command_buffer = GetCommandBuffer(); DCHECK(command_buffer); @@ -129,8 +124,7 @@ bool PPB_Graphics3D_Shared::CreateGLES2Impl( share_gles2 ? share_gles2->share_group() : NULL, transfer_buffer_.get(), true, - NULL // Do not use GpuMemoryBuffers. - )); + GetGpuControl())); if (!gles2_impl_->Initialize( transfer_buffer_size, @@ -146,19 +140,10 @@ bool PPB_Graphics3D_Shared::CreateGLES2Impl( } void PPB_Graphics3D_Shared::DestroyGLES2Impl() { - ScopedNoLocking already_locked(this); gles2_impl_.reset(); transfer_buffer_.reset(); gles2_helper_.reset(); } -void PPB_Graphics3D_Shared::PushAlreadyLocked() { - // Do nothing. This should be overridden in the plugin side. -} - -void PPB_Graphics3D_Shared::PopAlreadyLocked() { - // Do nothing. This should be overridden in the plugin side. -} - } // namespace ppapi diff --git a/ppapi/shared_impl/ppb_graphics_3d_shared.h b/ppapi/shared_impl/ppb_graphics_3d_shared.h index 482cb4cf03..d576d57fa2 100644 --- a/ppapi/shared_impl/ppb_graphics_3d_shared.h +++ b/ppapi/shared_impl/ppb_graphics_3d_shared.h @@ -15,6 +15,7 @@ namespace gpu { class CommandBuffer; +class GpuControl; class TransferBuffer; namespace gles2 { class GLES2CmdHelper; @@ -58,33 +59,12 @@ class PPAPI_SHARED_EXPORT PPB_Graphics3D_Shared void SwapBuffersACK(int32_t pp_error); protected: - // ScopedNoLocking makes sure we don't try to lock again when we already have - // the proxy lock. This is used when we need to use the CommandBuffer - // (possibly via gles2_impl) but we already have the proxy lock. The - // CommandBuffer in the plugin side of the proxy will otherwise try to acquire - // the ProxyLock, causing a crash because we already own the lock. (Locks in - // Chromium are never recursive). - class ScopedNoLocking { - public: - explicit ScopedNoLocking(PPB_Graphics3D_Shared* graphics3d_shared) - : graphics3d_shared_(graphics3d_shared) { - graphics3d_shared_->PushAlreadyLocked(); - } - ~ScopedNoLocking() { - graphics3d_shared_->PopAlreadyLocked(); - } - private: - PPB_Graphics3D_Shared* graphics3d_shared_; // Weak - - DISALLOW_COPY_AND_ASSIGN(ScopedNoLocking); - }; - - PPB_Graphics3D_Shared(PP_Instance instance); PPB_Graphics3D_Shared(const HostResource& host_resource); virtual ~PPB_Graphics3D_Shared(); virtual gpu::CommandBuffer* GetCommandBuffer() = 0; + virtual gpu::GpuControl* GetGpuControl() = 0; virtual int32 DoSwapBuffers() = 0; bool HasPendingSwap() const; @@ -94,17 +74,6 @@ class PPAPI_SHARED_EXPORT PPB_Graphics3D_Shared void DestroyGLES2Impl(); private: - // On the plugin side, we need to know that we already have the lock, so that - // we don't try to acquire it again. The default implementation does nothing; - // the Plugin side of the proxy must implement these. - friend class ScopedNoLocking; - virtual void PushAlreadyLocked(); - virtual void PopAlreadyLocked(); - - // The VideoDecoder needs to be able to call Graphics3D Flush() after taking - // the proxy lock. Hence it needs access to ScopedNoLocking. - friend class PPB_VideoDecoder_Shared; - scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_; scoped_ptr<gpu::TransferBuffer> transfer_buffer_; scoped_ptr<gpu::gles2::GLES2Implementation> gles2_impl_; diff --git a/ppapi/shared_impl/ppb_opengles2_shared.cc b/ppapi/shared_impl/ppb_opengles2_shared.cc index 03db4631f1..534e816396 100644 --- a/ppapi/shared_impl/ppb_opengles2_shared.cc +++ b/ppapi/shared_impl/ppb_opengles2_shared.cc @@ -17,827 +17,1344 @@ namespace ppapi { namespace { -gpu::gles2::GLES2Implementation* GetGLES(PP_Resource context) { - thunk::EnterResource<thunk::PPB_Graphics3D_API> enter_g3d(context, false); - DCHECK(enter_g3d.succeeded()); - return static_cast<PPB_Graphics3D_Shared*>(enter_g3d.object())->gles2_impl(); +typedef thunk::EnterResource<thunk::PPB_Graphics3D_API> Enter3D; + +gpu::gles2::GLES2Implementation* ToGles2Impl(Enter3D* enter) { + DCHECK(enter); + DCHECK(enter->succeeded()); + return static_cast<PPB_Graphics3D_Shared*>(enter->object())->gles2_impl(); } void ActiveTexture(PP_Resource context_id, GLenum texture) { - GetGLES(context_id)->ActiveTexture(texture); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ActiveTexture(texture); + } } void AttachShader(PP_Resource context_id, GLuint program, GLuint shader) { - GetGLES(context_id)->AttachShader(program, shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->AttachShader(program, shader); + } } void BindAttribLocation( PP_Resource context_id, GLuint program, GLuint index, const char* name) { - GetGLES(context_id)->BindAttribLocation(program, index, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindAttribLocation(program, index, name); + } } void BindBuffer(PP_Resource context_id, GLenum target, GLuint buffer) { - GetGLES(context_id)->BindBuffer(target, buffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindBuffer(target, buffer); + } } void BindFramebuffer( PP_Resource context_id, GLenum target, GLuint framebuffer) { - GetGLES(context_id)->BindFramebuffer(target, framebuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindFramebuffer(target, framebuffer); + } } void BindRenderbuffer( PP_Resource context_id, GLenum target, GLuint renderbuffer) { - GetGLES(context_id)->BindRenderbuffer(target, renderbuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindRenderbuffer(target, renderbuffer); + } } void BindTexture(PP_Resource context_id, GLenum target, GLuint texture) { - GetGLES(context_id)->BindTexture(target, texture); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BindTexture(target, texture); + } } void BlendColor( PP_Resource context_id, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - GetGLES(context_id)->BlendColor(red, green, blue, alpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendColor(red, green, blue, alpha); + } } void BlendEquation(PP_Resource context_id, GLenum mode) { - GetGLES(context_id)->BlendEquation(mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendEquation(mode); + } } void BlendEquationSeparate( PP_Resource context_id, GLenum modeRGB, GLenum modeAlpha) { - GetGLES(context_id)->BlendEquationSeparate(modeRGB, modeAlpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendEquationSeparate(modeRGB, modeAlpha); + } } void BlendFunc(PP_Resource context_id, GLenum sfactor, GLenum dfactor) { - GetGLES(context_id)->BlendFunc(sfactor, dfactor); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendFunc(sfactor, dfactor); + } } void BlendFuncSeparate( PP_Resource context_id, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { - GetGLES(context_id)->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + } } void BufferData( PP_Resource context_id, GLenum target, GLsizeiptr size, const void* data, GLenum usage) { - GetGLES(context_id)->BufferData(target, size, data, usage); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BufferData(target, size, data, usage); + } } void BufferSubData( PP_Resource context_id, GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { - GetGLES(context_id)->BufferSubData(target, offset, size, data); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BufferSubData(target, offset, size, data); + } } GLenum CheckFramebufferStatus(PP_Resource context_id, GLenum target) { - return GetGLES(context_id)->CheckFramebufferStatus(target); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->CheckFramebufferStatus(target); + } else { + return 0; + } } void Clear(PP_Resource context_id, GLbitfield mask) { - GetGLES(context_id)->Clear(mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Clear(mask); + } } void ClearColor( PP_Resource context_id, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - GetGLES(context_id)->ClearColor(red, green, blue, alpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ClearColor(red, green, blue, alpha); + } } void ClearDepthf(PP_Resource context_id, GLclampf depth) { - GetGLES(context_id)->ClearDepthf(depth); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ClearDepthf(depth); + } } void ClearStencil(PP_Resource context_id, GLint s) { - GetGLES(context_id)->ClearStencil(s); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ClearStencil(s); + } } void ColorMask( PP_Resource context_id, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - GetGLES(context_id)->ColorMask(red, green, blue, alpha); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ColorMask(red, green, blue, alpha); + } } void CompileShader(PP_Resource context_id, GLuint shader) { - GetGLES(context_id)->CompileShader(shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->CompileShader(shader); + } } void CompressedTexImage2D( PP_Resource context_id, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) { - GetGLES( - context_id)->CompressedTexImage2D( - target, level, internalformat, width, height, border, imageSize, - data); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CompressedTexImage2D( + target, level, internalformat, width, height, border, imageSize, + data); + } } void CompressedTexSubImage2D( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) { - GetGLES( - context_id)->CompressedTexSubImage2D( - target, level, xoffset, yoffset, width, height, format, imageSize, - data); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, + data); + } } void CopyTexImage2D( PP_Resource context_id, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - GetGLES( - context_id)->CopyTexImage2D( - target, level, internalformat, x, y, width, height, border); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CopyTexImage2D( + target, level, internalformat, x, y, width, height, border); + } } void CopyTexSubImage2D( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - GetGLES( - context_id)->CopyTexSubImage2D( - target, level, xoffset, yoffset, x, y, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->CopyTexSubImage2D( + target, level, xoffset, yoffset, x, y, width, height); + } } GLuint CreateProgram(PP_Resource context_id) { - return GetGLES(context_id)->CreateProgram(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->CreateProgram(); + } else { + return 0; + } } GLuint CreateShader(PP_Resource context_id, GLenum type) { - return GetGLES(context_id)->CreateShader(type); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->CreateShader(type); + } else { + return 0; + } } void CullFace(PP_Resource context_id, GLenum mode) { - GetGLES(context_id)->CullFace(mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->CullFace(mode); + } } void DeleteBuffers(PP_Resource context_id, GLsizei n, const GLuint* buffers) { - GetGLES(context_id)->DeleteBuffers(n, buffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteBuffers(n, buffers); + } } void DeleteFramebuffers( PP_Resource context_id, GLsizei n, const GLuint* framebuffers) { - GetGLES(context_id)->DeleteFramebuffers(n, framebuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteFramebuffers(n, framebuffers); + } } void DeleteProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->DeleteProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteProgram(program); + } } void DeleteRenderbuffers( PP_Resource context_id, GLsizei n, const GLuint* renderbuffers) { - GetGLES(context_id)->DeleteRenderbuffers(n, renderbuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteRenderbuffers(n, renderbuffers); + } } void DeleteShader(PP_Resource context_id, GLuint shader) { - GetGLES(context_id)->DeleteShader(shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteShader(shader); + } } void DeleteTextures( PP_Resource context_id, GLsizei n, const GLuint* textures) { - GetGLES(context_id)->DeleteTextures(n, textures); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteTextures(n, textures); + } } void DepthFunc(PP_Resource context_id, GLenum func) { - GetGLES(context_id)->DepthFunc(func); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DepthFunc(func); + } } void DepthMask(PP_Resource context_id, GLboolean flag) { - GetGLES(context_id)->DepthMask(flag); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DepthMask(flag); + } } void DepthRangef(PP_Resource context_id, GLclampf zNear, GLclampf zFar) { - GetGLES(context_id)->DepthRangef(zNear, zFar); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DepthRangef(zNear, zFar); + } } void DetachShader(PP_Resource context_id, GLuint program, GLuint shader) { - GetGLES(context_id)->DetachShader(program, shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DetachShader(program, shader); + } } void Disable(PP_Resource context_id, GLenum cap) { - GetGLES(context_id)->Disable(cap); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Disable(cap); + } } void DisableVertexAttribArray(PP_Resource context_id, GLuint index) { - GetGLES(context_id)->DisableVertexAttribArray(index); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DisableVertexAttribArray(index); + } } void DrawArrays( PP_Resource context_id, GLenum mode, GLint first, GLsizei count) { - GetGLES(context_id)->DrawArrays(mode, first, count); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DrawArrays(mode, first, count); + } } void DrawElements( PP_Resource context_id, GLenum mode, GLsizei count, GLenum type, const void* indices) { - GetGLES(context_id)->DrawElements(mode, count, type, indices); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DrawElements(mode, count, type, indices); + } } void Enable(PP_Resource context_id, GLenum cap) { - GetGLES(context_id)->Enable(cap); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Enable(cap); + } } void EnableVertexAttribArray(PP_Resource context_id, GLuint index) { - GetGLES(context_id)->EnableVertexAttribArray(index); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->EnableVertexAttribArray(index); + } } void Finish(PP_Resource context_id) { - GetGLES(context_id)->Finish(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Finish(); + } } void Flush(PP_Resource context_id) { - GetGLES(context_id)->Flush(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Flush(); + } } void FramebufferRenderbuffer( PP_Resource context_id, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { - GetGLES( - context_id)->FramebufferRenderbuffer( - target, attachment, renderbuffertarget, renderbuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->FramebufferRenderbuffer( + target, attachment, renderbuffertarget, renderbuffer); + } } void FramebufferTexture2D( PP_Resource context_id, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - GetGLES( - context_id)->FramebufferTexture2D( - target, attachment, textarget, texture, level); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->FramebufferTexture2D( + target, attachment, textarget, texture, level); + } } void FrontFace(PP_Resource context_id, GLenum mode) { - GetGLES(context_id)->FrontFace(mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->FrontFace(mode); + } } void GenBuffers(PP_Resource context_id, GLsizei n, GLuint* buffers) { - GetGLES(context_id)->GenBuffers(n, buffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenBuffers(n, buffers); + } } void GenerateMipmap(PP_Resource context_id, GLenum target) { - GetGLES(context_id)->GenerateMipmap(target); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenerateMipmap(target); + } } void GenFramebuffers(PP_Resource context_id, GLsizei n, GLuint* framebuffers) { - GetGLES(context_id)->GenFramebuffers(n, framebuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenFramebuffers(n, framebuffers); + } } void GenRenderbuffers( PP_Resource context_id, GLsizei n, GLuint* renderbuffers) { - GetGLES(context_id)->GenRenderbuffers(n, renderbuffers); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenRenderbuffers(n, renderbuffers); + } } void GenTextures(PP_Resource context_id, GLsizei n, GLuint* textures) { - GetGLES(context_id)->GenTextures(n, textures); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenTextures(n, textures); + } } void GetActiveAttrib( PP_Resource context_id, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - GetGLES( - context_id)->GetActiveAttrib( - program, index, bufsize, length, size, type, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetActiveAttrib( + program, index, bufsize, length, size, type, name); + } } void GetActiveUniform( PP_Resource context_id, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { - GetGLES( - context_id)->GetActiveUniform( - program, index, bufsize, length, size, type, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetActiveUniform( + program, index, bufsize, length, size, type, name); + } } void GetAttachedShaders( PP_Resource context_id, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { - GetGLES(context_id)->GetAttachedShaders(program, maxcount, count, shaders); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetAttachedShaders(program, maxcount, count, shaders); + } } GLint GetAttribLocation( PP_Resource context_id, GLuint program, const char* name) { - return GetGLES(context_id)->GetAttribLocation(program, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetAttribLocation(program, name); + } else { + return -1; + } } void GetBooleanv(PP_Resource context_id, GLenum pname, GLboolean* params) { - GetGLES(context_id)->GetBooleanv(pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetBooleanv(pname, params); + } } void GetBufferParameteriv( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetBufferParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetBufferParameteriv(target, pname, params); + } } GLenum GetError(PP_Resource context_id) { - return GetGLES(context_id)->GetError(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetError(); + } else { + return 0; + } } void GetFloatv(PP_Resource context_id, GLenum pname, GLfloat* params) { - GetGLES(context_id)->GetFloatv(pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetFloatv(pname, params); + } } void GetFramebufferAttachmentParameteriv( PP_Resource context_id, GLenum target, GLenum attachment, GLenum pname, GLint* params) { - GetGLES( - context_id)->GetFramebufferAttachmentParameteriv( - target, attachment, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetFramebufferAttachmentParameteriv( + target, attachment, pname, params); + } } void GetIntegerv(PP_Resource context_id, GLenum pname, GLint* params) { - GetGLES(context_id)->GetIntegerv(pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetIntegerv(pname, params); + } } void GetProgramiv( PP_Resource context_id, GLuint program, GLenum pname, GLint* params) { - GetGLES(context_id)->GetProgramiv(program, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetProgramiv(program, pname, params); + } } void GetProgramInfoLog( PP_Resource context_id, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) { - GetGLES(context_id)->GetProgramInfoLog(program, bufsize, length, infolog); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetProgramInfoLog(program, bufsize, length, infolog); + } } void GetRenderbufferParameteriv( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetRenderbufferParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetRenderbufferParameteriv(target, pname, params); + } } void GetShaderiv( PP_Resource context_id, GLuint shader, GLenum pname, GLint* params) { - GetGLES(context_id)->GetShaderiv(shader, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetShaderiv(shader, pname, params); + } } void GetShaderInfoLog( PP_Resource context_id, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) { - GetGLES(context_id)->GetShaderInfoLog(shader, bufsize, length, infolog); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetShaderInfoLog(shader, bufsize, length, infolog); + } } void GetShaderPrecisionFormat( PP_Resource context_id, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { - GetGLES( - context_id)->GetShaderPrecisionFormat( - shadertype, precisiontype, range, precision); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->GetShaderPrecisionFormat( + shadertype, precisiontype, range, precision); + } } void GetShaderSource( PP_Resource context_id, GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { - GetGLES(context_id)->GetShaderSource(shader, bufsize, length, source); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetShaderSource(shader, bufsize, length, source); + } } const GLubyte* GetString(PP_Resource context_id, GLenum name) { - return GetGLES(context_id)->GetString(name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetString(name); + } else { + return NULL; + } } void GetTexParameterfv( PP_Resource context_id, GLenum target, GLenum pname, GLfloat* params) { - GetGLES(context_id)->GetTexParameterfv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetTexParameterfv(target, pname, params); + } } void GetTexParameteriv( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetTexParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetTexParameteriv(target, pname, params); + } } void GetUniformfv( PP_Resource context_id, GLuint program, GLint location, GLfloat* params) { - GetGLES(context_id)->GetUniformfv(program, location, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetUniformfv(program, location, params); + } } void GetUniformiv( PP_Resource context_id, GLuint program, GLint location, GLint* params) { - GetGLES(context_id)->GetUniformiv(program, location, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetUniformiv(program, location, params); + } } GLint GetUniformLocation( PP_Resource context_id, GLuint program, const char* name) { - return GetGLES(context_id)->GetUniformLocation(program, name); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->GetUniformLocation(program, name); + } else { + return -1; + } } void GetVertexAttribfv( PP_Resource context_id, GLuint index, GLenum pname, GLfloat* params) { - GetGLES(context_id)->GetVertexAttribfv(index, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetVertexAttribfv(index, pname, params); + } } void GetVertexAttribiv( PP_Resource context_id, GLuint index, GLenum pname, GLint* params) { - GetGLES(context_id)->GetVertexAttribiv(index, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetVertexAttribiv(index, pname, params); + } } void GetVertexAttribPointerv( PP_Resource context_id, GLuint index, GLenum pname, void** pointer) { - GetGLES(context_id)->GetVertexAttribPointerv(index, pname, pointer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetVertexAttribPointerv(index, pname, pointer); + } } void Hint(PP_Resource context_id, GLenum target, GLenum mode) { - GetGLES(context_id)->Hint(target, mode); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Hint(target, mode); + } } GLboolean IsBuffer(PP_Resource context_id, GLuint buffer) { - return GetGLES(context_id)->IsBuffer(buffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsBuffer(buffer); + } else { + return GL_FALSE; + } } GLboolean IsEnabled(PP_Resource context_id, GLenum cap) { - return GetGLES(context_id)->IsEnabled(cap); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsEnabled(cap); + } else { + return GL_FALSE; + } } GLboolean IsFramebuffer(PP_Resource context_id, GLuint framebuffer) { - return GetGLES(context_id)->IsFramebuffer(framebuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsFramebuffer(framebuffer); + } else { + return GL_FALSE; + } } GLboolean IsProgram(PP_Resource context_id, GLuint program) { - return GetGLES(context_id)->IsProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsProgram(program); + } else { + return GL_FALSE; + } } GLboolean IsRenderbuffer(PP_Resource context_id, GLuint renderbuffer) { - return GetGLES(context_id)->IsRenderbuffer(renderbuffer); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsRenderbuffer(renderbuffer); + } else { + return GL_FALSE; + } } GLboolean IsShader(PP_Resource context_id, GLuint shader) { - return GetGLES(context_id)->IsShader(shader); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsShader(shader); + } else { + return GL_FALSE; + } } GLboolean IsTexture(PP_Resource context_id, GLuint texture) { - return GetGLES(context_id)->IsTexture(texture); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsTexture(texture); + } else { + return GL_FALSE; + } } void LineWidth(PP_Resource context_id, GLfloat width) { - GetGLES(context_id)->LineWidth(width); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->LineWidth(width); + } } void LinkProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->LinkProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->LinkProgram(program); + } } void PixelStorei(PP_Resource context_id, GLenum pname, GLint param) { - GetGLES(context_id)->PixelStorei(pname, param); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->PixelStorei(pname, param); + } } void PolygonOffset(PP_Resource context_id, GLfloat factor, GLfloat units) { - GetGLES(context_id)->PolygonOffset(factor, units); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->PolygonOffset(factor, units); + } } void ReadPixels( PP_Resource context_id, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { - GetGLES(context_id)->ReadPixels(x, y, width, height, format, type, pixels); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ReadPixels(x, y, width, height, format, type, pixels); + } } void ReleaseShaderCompiler(PP_Resource context_id) { - GetGLES(context_id)->ReleaseShaderCompiler(); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ReleaseShaderCompiler(); + } } void RenderbufferStorage( PP_Resource context_id, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { - GetGLES( - context_id)->RenderbufferStorage(target, internalformat, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->RenderbufferStorage(target, internalformat, width, height); + } } void SampleCoverage(PP_Resource context_id, GLclampf value, GLboolean invert) { - GetGLES(context_id)->SampleCoverage(value, invert); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->SampleCoverage(value, invert); + } } void Scissor( PP_Resource context_id, GLint x, GLint y, GLsizei width, GLsizei height) { - GetGLES(context_id)->Scissor(x, y, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Scissor(x, y, width, height); + } } void ShaderBinary( PP_Resource context_id, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) { - GetGLES(context_id)->ShaderBinary(n, shaders, binaryformat, binary, length); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->ShaderBinary(n, shaders, binaryformat, binary, length); + } } void ShaderSource( PP_Resource context_id, GLuint shader, GLsizei count, const char** str, const GLint* length) { - GetGLES(context_id)->ShaderSource(shader, count, str, length); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ShaderSource(shader, count, str, length); + } } void StencilFunc(PP_Resource context_id, GLenum func, GLint ref, GLuint mask) { - GetGLES(context_id)->StencilFunc(func, ref, mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilFunc(func, ref, mask); + } } void StencilFuncSeparate( PP_Resource context_id, GLenum face, GLenum func, GLint ref, GLuint mask) { - GetGLES(context_id)->StencilFuncSeparate(face, func, ref, mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilFuncSeparate(face, func, ref, mask); + } } void StencilMask(PP_Resource context_id, GLuint mask) { - GetGLES(context_id)->StencilMask(mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilMask(mask); + } } void StencilMaskSeparate(PP_Resource context_id, GLenum face, GLuint mask) { - GetGLES(context_id)->StencilMaskSeparate(face, mask); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilMaskSeparate(face, mask); + } } void StencilOp( PP_Resource context_id, GLenum fail, GLenum zfail, GLenum zpass) { - GetGLES(context_id)->StencilOp(fail, zfail, zpass); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilOp(fail, zfail, zpass); + } } void StencilOpSeparate( PP_Resource context_id, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - GetGLES(context_id)->StencilOpSeparate(face, fail, zfail, zpass); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->StencilOpSeparate(face, fail, zfail, zpass); + } } void TexImage2D( PP_Resource context_id, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) { - GetGLES( - context_id)->TexImage2D( - target, level, internalformat, width, height, border, format, type, - pixels); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->TexImage2D( + target, level, internalformat, width, height, border, format, type, + pixels); + } } void TexParameterf( PP_Resource context_id, GLenum target, GLenum pname, GLfloat param) { - GetGLES(context_id)->TexParameterf(target, pname, param); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameterf(target, pname, param); + } } void TexParameterfv( PP_Resource context_id, GLenum target, GLenum pname, const GLfloat* params) { - GetGLES(context_id)->TexParameterfv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameterfv(target, pname, params); + } } void TexParameteri( PP_Resource context_id, GLenum target, GLenum pname, GLint param) { - GetGLES(context_id)->TexParameteri(target, pname, param); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameteri(target, pname, param); + } } void TexParameteriv( PP_Resource context_id, GLenum target, GLenum pname, const GLint* params) { - GetGLES(context_id)->TexParameteriv(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->TexParameteriv(target, pname, params); + } } void TexSubImage2D( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { - GetGLES( - context_id)->TexSubImage2D( - target, level, xoffset, yoffset, width, height, format, type, - pixels); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->TexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, + pixels); + } } void Uniform1f(PP_Resource context_id, GLint location, GLfloat x) { - GetGLES(context_id)->Uniform1f(location, x); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1f(location, x); + } } void Uniform1fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform1fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1fv(location, count, v); + } } void Uniform1i(PP_Resource context_id, GLint location, GLint x) { - GetGLES(context_id)->Uniform1i(location, x); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1i(location, x); + } } void Uniform1iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform1iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform1iv(location, count, v); + } } void Uniform2f(PP_Resource context_id, GLint location, GLfloat x, GLfloat y) { - GetGLES(context_id)->Uniform2f(location, x, y); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2f(location, x, y); + } } void Uniform2fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform2fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2fv(location, count, v); + } } void Uniform2i(PP_Resource context_id, GLint location, GLint x, GLint y) { - GetGLES(context_id)->Uniform2i(location, x, y); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2i(location, x, y); + } } void Uniform2iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform2iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform2iv(location, count, v); + } } void Uniform3f( PP_Resource context_id, GLint location, GLfloat x, GLfloat y, GLfloat z) { - GetGLES(context_id)->Uniform3f(location, x, y, z); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3f(location, x, y, z); + } } void Uniform3fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform3fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3fv(location, count, v); + } } void Uniform3i( PP_Resource context_id, GLint location, GLint x, GLint y, GLint z) { - GetGLES(context_id)->Uniform3i(location, x, y, z); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3i(location, x, y, z); + } } void Uniform3iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform3iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform3iv(location, count, v); + } } void Uniform4f( PP_Resource context_id, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - GetGLES(context_id)->Uniform4f(location, x, y, z, w); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4f(location, x, y, z, w); + } } void Uniform4fv( PP_Resource context_id, GLint location, GLsizei count, const GLfloat* v) { - GetGLES(context_id)->Uniform4fv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4fv(location, count, v); + } } void Uniform4i( PP_Resource context_id, GLint location, GLint x, GLint y, GLint z, GLint w) { - GetGLES(context_id)->Uniform4i(location, x, y, z, w); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4i(location, x, y, z, w); + } } void Uniform4iv( PP_Resource context_id, GLint location, GLsizei count, const GLint* v) { - GetGLES(context_id)->Uniform4iv(location, count, v); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Uniform4iv(location, count, v); + } } void UniformMatrix2fv( PP_Resource context_id, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - GetGLES(context_id)->UniformMatrix2fv(location, count, transpose, value); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UniformMatrix2fv(location, count, transpose, value); + } } void UniformMatrix3fv( PP_Resource context_id, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - GetGLES(context_id)->UniformMatrix3fv(location, count, transpose, value); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UniformMatrix3fv(location, count, transpose, value); + } } void UniformMatrix4fv( PP_Resource context_id, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - GetGLES(context_id)->UniformMatrix4fv(location, count, transpose, value); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UniformMatrix4fv(location, count, transpose, value); + } } void UseProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->UseProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UseProgram(program); + } } void ValidateProgram(PP_Resource context_id, GLuint program) { - GetGLES(context_id)->ValidateProgram(program); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->ValidateProgram(program); + } } void VertexAttrib1f(PP_Resource context_id, GLuint indx, GLfloat x) { - GetGLES(context_id)->VertexAttrib1f(indx, x); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib1f(indx, x); + } } void VertexAttrib1fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib1fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib1fv(indx, values); + } } void VertexAttrib2f( PP_Resource context_id, GLuint indx, GLfloat x, GLfloat y) { - GetGLES(context_id)->VertexAttrib2f(indx, x, y); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib2f(indx, x, y); + } } void VertexAttrib2fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib2fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib2fv(indx, values); + } } void VertexAttrib3f( PP_Resource context_id, GLuint indx, GLfloat x, GLfloat y, GLfloat z) { - GetGLES(context_id)->VertexAttrib3f(indx, x, y, z); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib3f(indx, x, y, z); + } } void VertexAttrib3fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib3fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib3fv(indx, values); + } } void VertexAttrib4f( PP_Resource context_id, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - GetGLES(context_id)->VertexAttrib4f(indx, x, y, z, w); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib4f(indx, x, y, z, w); + } } void VertexAttrib4fv( PP_Resource context_id, GLuint indx, const GLfloat* values) { - GetGLES(context_id)->VertexAttrib4fv(indx, values); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttrib4fv(indx, values); + } } void VertexAttribPointer( PP_Resource context_id, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) { - GetGLES( - context_id)->VertexAttribPointer( - indx, size, type, normalized, stride, ptr); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->VertexAttribPointer( + indx, size, type, normalized, stride, ptr); + } } void Viewport( PP_Resource context_id, GLint x, GLint y, GLsizei width, GLsizei height) { - GetGLES(context_id)->Viewport(x, y, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->Viewport(x, y, width, height); + } } void BlitFramebufferEXT( PP_Resource context_id, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - GetGLES( - context_id)->BlitFramebufferEXT( - srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, - filter); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->BlitFramebufferEXT( + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, + filter); + } } void RenderbufferStorageMultisampleEXT( PP_Resource context_id, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { - GetGLES( - context_id)->RenderbufferStorageMultisampleEXT( - target, samples, internalformat, width, height); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->RenderbufferStorageMultisampleEXT( + target, samples, internalformat, width, height); + } } void GenQueriesEXT(PP_Resource context_id, GLsizei n, GLuint* queries) { - GetGLES(context_id)->GenQueriesEXT(n, queries); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GenQueriesEXT(n, queries); + } } void DeleteQueriesEXT( PP_Resource context_id, GLsizei n, const GLuint* queries) { - GetGLES(context_id)->DeleteQueriesEXT(n, queries); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->DeleteQueriesEXT(n, queries); + } } GLboolean IsQueryEXT(PP_Resource context_id, GLuint id) { - return GetGLES(context_id)->IsQueryEXT(id); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->IsQueryEXT(id); + } else { + return GL_FALSE; + } } void BeginQueryEXT(PP_Resource context_id, GLenum target, GLuint id) { - GetGLES(context_id)->BeginQueryEXT(target, id); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->BeginQueryEXT(target, id); + } } void EndQueryEXT(PP_Resource context_id, GLenum target) { - GetGLES(context_id)->EndQueryEXT(target); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->EndQueryEXT(target); + } } void GetQueryivEXT( PP_Resource context_id, GLenum target, GLenum pname, GLint* params) { - GetGLES(context_id)->GetQueryivEXT(target, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetQueryivEXT(target, pname, params); + } } void GetQueryObjectuivEXT( PP_Resource context_id, GLuint id, GLenum pname, GLuint* params) { - GetGLES(context_id)->GetQueryObjectuivEXT(id, pname, params); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->GetQueryObjectuivEXT(id, pname, params); + } } GLboolean EnableFeatureCHROMIUM(PP_Resource context_id, const char* feature) { - return GetGLES(context_id)->EnableFeatureCHROMIUM(feature); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl(&enter)->EnableFeatureCHROMIUM(feature); + } else { + return GL_FALSE; + } } void* MapBufferSubDataCHROMIUM( PP_Resource context_id, GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) { - return GetGLES( - context_id)->MapBufferSubDataCHROMIUM(target, offset, size, access); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl( + &enter)->MapBufferSubDataCHROMIUM(target, offset, size, access); + } else { + return NULL; + } } void UnmapBufferSubDataCHROMIUM(PP_Resource context_id, const void* mem) { - GetGLES(context_id)->UnmapBufferSubDataCHROMIUM(mem); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UnmapBufferSubDataCHROMIUM(mem); + } } void* MapTexSubImage2DCHROMIUM( PP_Resource context_id, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access) { - return GetGLES( - context_id)->MapTexSubImage2DCHROMIUM( - target, level, xoffset, yoffset, width, height, format, type, - access); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + return ToGles2Impl( + &enter)->MapTexSubImage2DCHROMIUM( + target, level, xoffset, yoffset, width, height, format, type, + access); + } else { + return NULL; + } } void UnmapTexSubImage2DCHROMIUM(PP_Resource context_id, const void* mem) { - GetGLES(context_id)->UnmapTexSubImage2DCHROMIUM(mem); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->UnmapTexSubImage2DCHROMIUM(mem); + } } void DrawArraysInstancedANGLE( PP_Resource context_id, GLenum mode, GLint first, GLsizei count, GLsizei primcount) { - GetGLES(context_id)->DrawArraysInstancedANGLE(mode, first, count, primcount); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->DrawArraysInstancedANGLE(mode, first, count, primcount); + } } void DrawElementsInstancedANGLE( PP_Resource context_id, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount) { - GetGLES( - context_id)->DrawElementsInstancedANGLE( - mode, count, type, indices, primcount); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl( + &enter)->DrawElementsInstancedANGLE( + mode, count, type, indices, primcount); + } } void VertexAttribDivisorANGLE( PP_Resource context_id, GLuint index, GLuint divisor) { - GetGLES(context_id)->VertexAttribDivisorANGLE(index, divisor); + Enter3D enter(context_id, true); + if (enter.succeeded()) { + ToGles2Impl(&enter)->VertexAttribDivisorANGLE(index, divisor); + } } } // namespace diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.cc b/ppapi/shared_impl/ppb_video_decoder_shared.cc index 7d8d021b5b..5232e6c3b3 100644 --- a/ppapi/shared_impl/ppb_video_decoder_shared.cc +++ b/ppapi/shared_impl/ppb_video_decoder_shared.cc @@ -96,16 +96,8 @@ void PPB_VideoDecoder_Shared::RunBitstreamBufferCallback( } void PPB_VideoDecoder_Shared::FlushCommandBuffer() { - if (gles2_impl_) { - // To call Flush() we have to tell Graphics3D that we hold the proxy lock. - thunk::EnterResource<thunk::PPB_Graphics3D_API, false> enter_g3d( - graphics_context_, false); - DCHECK(enter_g3d.succeeded()); - PPB_Graphics3D_Shared* graphics3d = - static_cast<PPB_Graphics3D_Shared*>(enter_g3d.object()); - PPB_Graphics3D_Shared::ScopedNoLocking dont_lock(graphics3d); + if (gles2_impl_) gles2_impl_->Flush(); - } } } // namespace ppapi diff --git a/ppapi/shared_impl/proxy_lock.h b/ppapi/shared_impl/proxy_lock.h index 9a81a13baa..f6dea31841 100644 --- a/ppapi/shared_impl/proxy_lock.h +++ b/ppapi/shared_impl/proxy_lock.h @@ -50,6 +50,11 @@ class PPAPI_SHARED_EXPORT ProxyLock { // Assert that the lock is owned by the current thread (in the plugin // process). Does nothing when running in-process (or in the host process). static void AssertAcquired(); + static void AssertAcquiredDebugOnly() { +#ifndef NDEBUG + AssertAcquired(); +#endif + } // We have some unit tests where one thread pretends to be the host and one // pretends to be the plugin. This allows the lock to do nothing on only one diff --git a/ppapi/shared_impl/resource.h b/ppapi/shared_impl/resource.h index 15ce142c13..d364b44e60 100644 --- a/ppapi/shared_impl/resource.h +++ b/ppapi/shared_impl/resource.h @@ -57,6 +57,7 @@ F(PPB_NetworkList_API) \ F(PPB_NetworkMonitor_API) \ F(PPB_NetworkProxy_API) \ + F(PPB_OutputProtection_API) \ F(PPB_PDF_API) \ F(PPB_PlatformVerification_API) \ F(PPB_Printing_API) \ diff --git a/ppapi/shared_impl/resource_tracker.h b/ppapi/shared_impl/resource_tracker.h index ee93376b4c..6feeea7692 100644 --- a/ppapi/shared_impl/resource_tracker.h +++ b/ppapi/shared_impl/resource_tracker.h @@ -126,14 +126,14 @@ class PPAPI_SHARED_EXPORT ResourceTracker { int32 last_resource_value_; - base::WeakPtrFactory<ResourceTracker> weak_ptr_factory_; - // On the host side, we want to check that we are only called on the main // thread. This is to protect us from accidentally using the tracker from // other threads (especially the IO thread). On the plugin side, the tracker // is protected by the proxy lock and is thread-safe, so this will be NULL. scoped_ptr<base::ThreadChecker> thread_checker_; + base::WeakPtrFactory<ResourceTracker> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ResourceTracker); }; diff --git a/ppapi/shared_impl/test_globals.cc b/ppapi/shared_impl/test_globals.cc index f4d58cfd8d..2739e26373 100644 --- a/ppapi/shared_impl/test_globals.cc +++ b/ppapi/shared_impl/test_globals.cc @@ -71,7 +71,7 @@ MessageLoopShared* TestGlobals::GetCurrentMessageLoop() { return NULL; } -base::TaskRunner* TestGlobals::GetFileTaskRunner(PP_Instance instance) { +base::TaskRunner* TestGlobals::GetFileTaskRunner() { return NULL; } diff --git a/ppapi/shared_impl/test_globals.h b/ppapi/shared_impl/test_globals.h index 2a0ece302a..36ed829a78 100644 --- a/ppapi/shared_impl/test_globals.h +++ b/ppapi/shared_impl/test_globals.h @@ -73,7 +73,7 @@ class TestGlobals : public PpapiGlobals { const std::string& source, const std::string& value) OVERRIDE; virtual MessageLoopShared* GetCurrentMessageLoop() OVERRIDE; - virtual base::TaskRunner* GetFileTaskRunner(PP_Instance instance) OVERRIDE; + virtual base::TaskRunner* GetFileTaskRunner() OVERRIDE; // PpapiGlobals overrides: virtual bool IsHostGlobals() const OVERRIDE; diff --git a/ppapi/shared_impl/var.cc b/ppapi/shared_impl/var.cc index d128d90241..56def197c6 100644 --- a/ppapi/shared_impl/var.cc +++ b/ppapi/shared_impl/var.cc @@ -19,12 +19,6 @@ namespace ppapi { // Var ------------------------------------------------------------------------- -Var::Var() : var_id_(0) { -} - -Var::~Var() { -} - // static std::string Var::PPVarToLogString(PP_Var var) { switch (var.type) { @@ -126,6 +120,12 @@ int32 Var::GetExistingVarID() const { return var_id_; } +Var::Var() : var_id_(0) { +} + +Var::~Var() { +} + int32 Var::GetOrCreateVarID() { VarTracker* tracker = PpapiGlobals::Get()->GetVarTracker(); if (var_id_) { diff --git a/ppapi/shared_impl/var.h b/ppapi/shared_impl/var.h index d656019c74..a52dc3accc 100644 --- a/ppapi/shared_impl/var.h +++ b/ppapi/shared_impl/var.h @@ -31,8 +31,6 @@ class VarTracker; // Represents a non-POD var. class PPAPI_SHARED_EXPORT Var : public base::RefCounted<Var> { public: - virtual ~Var(); - // Returns a string representing the given var for logging purposes. static std::string PPVarToLogString(PP_Var var); @@ -60,9 +58,11 @@ class PPAPI_SHARED_EXPORT Var : public base::RefCounted<Var> { int32 GetExistingVarID() const; protected: + friend class base::RefCounted<Var>; friend class VarTracker; Var(); + virtual ~Var(); // Returns the unique ID associated with this string or object, creating it // if necessary. The return value will be 0 if the string or object is diff --git a/ppapi/shared_impl/var_tracker.h b/ppapi/shared_impl/var_tracker.h index 379f645bbf..168fcb9933 100644 --- a/ppapi/shared_impl/var_tracker.h +++ b/ppapi/shared_impl/var_tracker.h @@ -87,11 +87,17 @@ class PPAPI_SHARED_EXPORT VarTracker { // Creates a new resource var that points to a given resource ID. Returns a // PP_Var that references it and has an initial reference count of 1. + // If |pp_resource| is 0, returns a valid, empty resource var. On the plugin + // side (where it is possible to tell which resources exist), if |pp_resource| + // does not exist, returns a null var. PP_Var MakeResourcePPVar(PP_Resource pp_resource); // Creates a new resource var that points to a given resource ID. This is // implemented by the host and plugin tracker separately, because the plugin // keeps a reference to the resource, and the host does not. + // If |pp_resource| is 0, returns a valid, empty resource var. On the plugin + // side (where it is possible to tell which resources exist), if |pp_resource| + // does not exist, returns NULL. virtual ResourceVar* MakeResourceVar(PP_Resource pp_resource) = 0; // Return a vector containing all PP_Vars that are in the tracker. This is diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h index f6e3de04cf..76f939641f 100644 --- a/ppapi/tests/all_c_includes.h +++ b/ppapi/tests/all_c_includes.h @@ -117,6 +117,7 @@ #include "ppapi/c/private/ppb_instance_private.h" #include "ppapi/c/private/ppb_nacl_private.h" #include "ppapi/c/private/ppb_net_address_private.h" +#include "ppapi/c/private/ppb_output_protection_private.h" #include "ppapi/c/private/ppb_pdf.h" #include "ppapi/c/private/ppb_platform_verification_private.h" #include "ppapi/c/private/ppb_proxy_private.h" @@ -128,7 +129,6 @@ #include "ppapi/c/private/ppb_x509_certificate_private.h" #include "ppapi/c/private/ppp_content_decryptor_private.h" #include "ppapi/c/private/ppp_instance_private.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #endif /* PPAPI_TESTS_ALL_C_INCLUDES_H_ */ diff --git a/ppapi/tests/extensions/extensions.gyp b/ppapi/tests/extensions/extensions.gyp new file mode 100644 index 0000000000..d063b83f47 --- /dev/null +++ b/ppapi/tests/extensions/extensions.gyp @@ -0,0 +1,33 @@ +# 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. + +{ + 'includes': [ + '../../../ppapi/ppapi_nacl_test_common.gypi', + ], + 'targets': [ + { + 'target_name': 'ppapi_tests_extensions_socket', + 'type': 'none', + 'variables': { + 'nexe_target': 'ppapi_tests_extensions_socket', + 'build_newlib': 1, + 'build_glibc': 0, + 'build_pnacl_newlib': 0, + 'nexe_destination_dir': 'test_data/ppapi/tests/extensions/socket', + 'sources': [ + 'socket/test_socket.cc', + '<(DEPTH)/ppapi/tests/test_utils.cc', + '<(DEPTH)/ppapi/tests/test_utils.h', + ], + 'test_files': [ + 'socket/controller.js', + 'socket/index.html', + 'socket/main.js', + 'socket/manifest.json', + ], + }, + }, + ], +} diff --git a/ppapi/tests/extensions/socket/controller.js b/ppapi/tests/extensions/socket/controller.js new file mode 100644 index 0000000000..b6aa402543 --- /dev/null +++ b/ppapi/tests/extensions/socket/controller.js @@ -0,0 +1,34 @@ +// 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. + +var control_message; + +function testAll() { + var nacl_module = document.getElementById('nacl_module'); + // The plugin will start the corresponding test and post a message back when + // the test is done. If the test has failed, the message is a description of + // the error; otherwise the message is empty. + nacl_module.postMessage(control_message); +} + +var onControlMessageReceived = function(message) { + control_message = message; + chrome.test.runTests([testAll]); +} + +var onPluginMessageReceived = function(message) { + if (message.data == "ready") { + chrome.test.sendMessage("info_please", onControlMessageReceived); + } else if (message.data) { + chrome.test.fail(message.data); + } else { + chrome.test.succeed(); + } +}; + +window.onload = function() { + var nacl_module = document.getElementById('nacl_module'); + nacl_module.addEventListener("message", onPluginMessageReceived, false); +}; + diff --git a/ppapi/tests/extensions/socket/index.html b/ppapi/tests/extensions/socket/index.html new file mode 100644 index 0000000000..028abd6157 --- /dev/null +++ b/ppapi/tests/extensions/socket/index.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html> +<head> + <title>chrome.socket</title> + <script src="controller.js"></script> +</head> +<body> + <embed id="nacl_module" src="ppapi_tests_extensions_socket.nmf" + type="application/x-nacl" /> +</body> +</html> diff --git a/ppapi/tests/extensions/socket/main.js b/ppapi/tests/extensions/socket/main.js new file mode 100644 index 0000000000..68957dc94c --- /dev/null +++ b/ppapi/tests/extensions/socket/main.js @@ -0,0 +1,7 @@ +// 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. + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('index.html', {width: 500, height: 500}); +}); diff --git a/ppapi/tests/extensions/socket/manifest.json b/ppapi/tests/extensions/socket/manifest.json new file mode 100644 index 0000000000..635f97a584 --- /dev/null +++ b/ppapi/tests/extensions/socket/manifest.json @@ -0,0 +1,22 @@ +{ + "manifest_version": 2, + "name": "chrome.socket", + "version": "0.1", + "description": "end-to-end browser test for chrome.socket API in Pepper", + "app": { + "background": { + "scripts": ["main.js"] + } + }, + "permissions": [ + { + "socket": [ + "tcp-connect", + "tcp-listen", + "udp-send-to", + "udp-bind", + "udp-multicast-membership" + ] + } + ] +} diff --git a/ppapi/tests/extensions/socket/test_socket.cc b/ppapi/tests/extensions/socket/test_socket.cc new file mode 100644 index 0000000000..487c53ff87 --- /dev/null +++ b/ppapi/tests/extensions/socket/test_socket.cc @@ -0,0 +1,654 @@ +// 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 <cstdarg> +#include <cstdio> +#include <cstdlib> +#include <cstring> + +#include "ppapi/c/ppb_console.h" +#include "ppapi/cpp/extensions/dev/socket_dev.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/module.h" +#include "ppapi/cpp/var.h" +#include "ppapi/cpp/var_array_buffer.h" +#include "ppapi/tests/test_utils.h" + +using namespace pp; +using namespace pp::ext; + +namespace { + +const char* const kSendContents = "0100000005320000005hello"; +const char* const kReceiveContentsPrefix = "0100000005320000005"; +const size_t kReceiveContentsSuffixSize = 11; + +const char* const kMulticastAddress = "237.132.100.133"; +const int32_t kMulticastPort = 11103; +const char* const kMulticastMessage = "hello world!"; + +} // namespace + +class MyInstance : public Instance { + public: + explicit MyInstance(PP_Instance instance) + : Instance(instance), + socket_(InstanceHandle(instance)), + console_interface_(NULL), + port_(0) { + } + virtual ~MyInstance() { + } + + virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { + console_interface_ = static_cast<const PPB_Console*>( + Module::Get()->GetBrowserInterface(PPB_CONSOLE_INTERFACE)); + + if (!console_interface_) + return false; + + PostMessage(Var("ready")); + return true; + } + + virtual void HandleMessage(const pp::Var& message_data) { + std::string output; + do { + if (!message_data.is_string()) { + output = "Invalid control message."; + break; + } + + std::string control_message = message_data.AsString(); + std::vector<std::string> parts; + size_t pos = 0; + size_t next_match = 0; + while (pos < control_message.size()) { + next_match = control_message.find(':', pos); + if (next_match == std::string::npos) + next_match = control_message.size(); + parts.push_back(control_message.substr(pos, next_match - pos)); + pos = next_match + 1; + } + + if (parts.size() != 3) { + output = "Invalid protocol/address/port input."; + break; + } + + test_type_ = parts[0]; + address_ = parts[1]; + port_ = atoi(parts[2].c_str()); + Log(PP_LOGLEVEL_LOG, "Running tests, protocol %s, server %s:%d", + test_type_.c_str(), address_.c_str(), port_); + + if (test_type_ == "tcp_server") { + output = TestServerSocket(); + } else if (test_type_ == "multicast") { + output = TestMulticast(); + } else { + output = TestClientSocket(); + } + } while (false); + + NotifyTestDone(output); + } + + private: + std::string TestServerSocket() { + int32_t socket_id = 0; + { + TestExtCompletionCallbackWithOutput<socket::CreateInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Create( + socket::SocketType_Dev(socket::SocketType_Dev::TCP), + Optional<socket::CreateOptions_Dev>(), callback.GetCallback())); + if (callback.result() != PP_OK) + return "Create(): failed."; + socket_id = callback.output().socket_id(); + if (socket_id <= 0) + return "Create(): invalid socket ID."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.Listen( + socket_id, address_, port_, Optional<int32_t>(), + callback.GetCallback())); + if (callback.result() != PP_OK) + return "Listen(): failed."; + if (callback.output() != 0) + return "Listen(): failed."; + } + + int32_t client_socket_id = 0; + { + TestExtCompletionCallbackWithOutput<socket::CreateInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Create( + socket::SocketType_Dev(socket::SocketType_Dev::TCP), + Optional<socket::CreateOptions_Dev>(), callback.GetCallback())); + if (callback.result() != PP_OK) + return "Create(): failed."; + client_socket_id = callback.output().socket_id(); + if (client_socket_id <= 0) + return "Create(): invalid socket ID."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.Connect( + client_socket_id, address_, port_, callback.GetCallback())); + if (callback.result() != PP_OK) + return "Connect(): failed."; + if (callback.output() != 0) + return "Connect(): failed."; + } + + int32_t accepted_socket_id = 0; + { + TestExtCompletionCallbackWithOutput<socket::AcceptInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Accept(socket_id, callback.GetCallback())); + if (callback.result() != PP_OK) + return "Accept(): failed."; + socket::AcceptInfo_Dev accept_info = callback.output(); + if (accept_info.result_code() != 0 || !accept_info.socket_id().IsSet()) + return "Accept(): failed."; + accepted_socket_id = *accept_info.socket_id(); + } + + size_t bytes_written = 0; + { + TestExtCompletionCallbackWithOutput<socket::WriteInfo_Dev> + callback(pp_instance()); + VarArrayBuffer array_buffer = ConvertToArrayBuffer(kSendContents); + callback.WaitForResult(socket_.Write(client_socket_id, array_buffer, + callback.GetCallback())); + if (callback.result() != PP_OK) + return "Write(): failed."; + socket::WriteInfo_Dev write_info = callback.output(); + bytes_written = static_cast<size_t>(write_info.bytes_written()); + if (bytes_written <= 0) + return "Write(): did not write any bytes."; + } + + { + TestExtCompletionCallbackWithOutput<socket::ReadInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Read( + accepted_socket_id, Optional<int32_t>(), callback.GetCallback())); + if (callback.result() != PP_OK) + return "Read(): failed."; + + std::string data_string = ConvertFromArrayBuffer( + &callback.output().data()); + if (data_string.compare(0, std::string::npos, kSendContents, + bytes_written) != 0) { + return "Read(): Received data does not match."; + } + } + + socket_.Destroy(client_socket_id); + socket_.Destroy(accepted_socket_id); + socket_.Destroy(socket_id); + return std::string(); + } + + std::string TestMulticast() { + int32_t socket_id = 0; + { + TestExtCompletionCallbackWithOutput<socket::CreateInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Create( + socket::SocketType_Dev::UDP, Optional<socket::CreateOptions_Dev>(), + callback.GetCallback())); + if (callback.result() != PP_OK) + return "Create(): failed."; + socket_id = callback.output().socket_id(); + if (socket_id <= 0) + return "Create(): invalid socket ID."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.SetMulticastTimeToLive( + socket_id, 0, callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "SetMulticastTimeToLive(): failed."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.SetMulticastTimeToLive( + socket_id, -3, callback.GetCallback())); + if (callback.result() == PP_OK) + return "SetMulticastTimeToLive(): succeeded unexpectedly."; + if (callback.output() != -4) + return "SetMulticastTimeToLive(): returned unexpected result."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.SetMulticastLoopbackMode( + socket_id, false, callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "SetMulticastLoopbackMode(): failed."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.SetMulticastLoopbackMode( + socket_id, true, callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "SetMulticastLoopbackMode(): failed."; + } + + socket_.Destroy(socket_id); + socket_id = 0; + + int32_t server_socket_id = 0; + { + TestExtCompletionCallbackWithOutput<socket::CreateInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Create( + socket::SocketType_Dev::UDP, Optional<socket::CreateOptions_Dev>(), + callback.GetCallback())); + if (callback.result() != PP_OK) + return "Create(): failed."; + server_socket_id = callback.output().socket_id(); + if (server_socket_id <= 0) + return "Create(): invalid socket ID."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.Bind( + server_socket_id, "0.0.0.0", kMulticastPort, callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "Bind(): failed"; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.JoinGroup( + server_socket_id, kMulticastAddress, callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "JoinGroup(): failed."; + } + + { + TestExtCompletionCallbackWithOutput<std::vector<std::string> > + callback(pp_instance()); + callback.WaitForResult(socket_.GetJoinedGroups( + server_socket_id, callback.GetCallback())); + if (callback.result() != PP_OK) + return "GetJoinedGroups(): failed."; + std::vector<std::string> groups = callback.output(); + if (groups.size() != 1 || groups[0] != kMulticastAddress) { + return "GetJoinedGroups(): the returned groups didn't match those " + "joined."; + } + } + + int32_t client_socket_id = 0; + { + TestExtCompletionCallbackWithOutput<socket::CreateInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Create( + socket::SocketType_Dev::UDP, Optional<socket::CreateOptions_Dev>(), + callback.GetCallback())); + if (callback.result() != PP_OK) + return "Create(): failed."; + client_socket_id = callback.output().socket_id(); + if (client_socket_id <= 0) + return "Create(): invalid socket ID."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.SetMulticastTimeToLive( + client_socket_id, 0, callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "SetMulticastTimeToLive(): failed."; + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.Connect( + client_socket_id, kMulticastAddress, kMulticastPort, + callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "Connnect(): failed."; + } + + { + VarArrayBuffer input_array_buffer = + ConvertToArrayBuffer(kMulticastMessage); + size_t bytes_written = 0; + int32_t result_code = 0; + VarArrayBuffer data; + + TestExtCompletionCallbackWithOutput<socket::RecvFromInfo_Dev> + recv_from_callback(pp_instance()); + int32_t recv_from_result = socket_.RecvFrom( + server_socket_id, 1024, recv_from_callback.GetCallback()); + if (recv_from_result != PP_OK_COMPLETIONPENDING) + return "RecvFrom(): did not wait for data."; + + TestExtCompletionCallbackWithOutput<socket::WriteInfo_Dev> + write_callback(pp_instance()); + write_callback.WaitForResult(socket_.Write( + client_socket_id, input_array_buffer, write_callback.GetCallback())); + if (write_callback.result() != PP_OK) + return "Write(): failed."; + bytes_written = static_cast<size_t>( + write_callback.output().bytes_written()); + + recv_from_callback.WaitForResult(recv_from_result); + if (recv_from_callback.result() != PP_OK) + return "RecvFrom(): failed."; + socket::RecvFromInfo_Dev recv_from_info = recv_from_callback.output(); + result_code = recv_from_info.result_code(); + data = recv_from_info.data(); + + if (bytes_written != strlen(kMulticastMessage)) + return "Write(): did not send the whole data buffer."; + + if (result_code > 0 && + static_cast<uint32_t>(result_code) != data.ByteLength()) { + return "RecvFrom(): inconsistent result code and byte length."; + } + + std::string output_string = ConvertFromArrayBuffer(&data); + if (output_string != kMulticastMessage) { + return std::string("RecvFrom(): mismatched data: ").append( + output_string); + } + } + + { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.LeaveGroup( + server_socket_id, kMulticastAddress, callback.GetCallback())); + if (callback.result() != PP_OK || callback.output() != 0) + return "LeaveGroup(): failed."; + } + + socket_.Destroy(server_socket_id); + socket_.Destroy(client_socket_id); + return std::string(); + } + + std::string TestClientSocket() { + socket::SocketType_Dev socket_type; + if (!socket_type.Populate(Var(test_type_).pp_var())) + return "Invalid socket type."; + + int32_t socket_id = 0; + { + TestExtCompletionCallbackWithOutput<socket::CreateInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.Create( + socket_type, Optional<socket::CreateOptions_Dev>(), + callback.GetCallback())); + if (callback.result() != PP_OK) + return "Create(): failed."; + socket_id = callback.output().socket_id(); + if (socket_id <= 0) + return "Create(): invalid socket ID."; + } + + { + TestExtCompletionCallbackWithOutput<socket::SocketInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.GetInfo(socket_id, + callback.GetCallback())); + if (callback.result() != PP_OK) + return "GetInfo(): failed."; + + socket::SocketInfo_Dev socket_info = callback.output(); + if (socket_info.socket_type().value != socket_type.value) + return "GetInfo(): inconsistent socket type."; + if (socket_info.connected()) + return "GetInfo(): socket should not be connected."; + if (socket_info.peer_address().IsSet() || socket_info.peer_port().IsSet()) + return "GetInfo(): unconnected socket should not have peer."; + if (socket_info.local_address().IsSet() || + socket_info.local_port().IsSet()) { + return "GetInfo(): unconnected socket should not have local binding."; + } + } + + { + if (socket_type.value == socket::SocketType_Dev::TCP) { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.Connect( + socket_id, address_, port_, callback.GetCallback())); + if (callback.result() != PP_OK) + return "Connect(): failed."; + if (callback.output() != 0) + return "Connect(): failed."; + } else { + TestExtCompletionCallbackWithOutput<int32_t> callback(pp_instance()); + callback.WaitForResult(socket_.Bind( + socket_id, "0.0.0.0", 0, callback.GetCallback())); + if (callback.result() != PP_OK) + return "Bind(): failed."; + if (callback.output() != 0) + return "Bind(): failed."; + } + } + + { + TestExtCompletionCallbackWithOutput<socket::SocketInfo_Dev> + callback(pp_instance()); + callback.WaitForResult(socket_.GetInfo(socket_id, + callback.GetCallback())); + if (callback.result() != PP_OK) + return "GetInfo(): failed."; + + socket::SocketInfo_Dev socket_info = callback.output(); + if (socket_info.socket_type().value != socket_type.value) + return "GetInfo(): inconsistent socket type."; + if (!socket_info.local_address().IsSet() || + !socket_info.local_port().IsSet()) { + return "GetInfo(): bound socket should have local address and port."; + } + if (socket_type.value == socket::SocketType_Dev::TCP) { + if (!socket_info.connected()) + return "GetInfo(): TCP socket should be connected."; + if (!socket_info.peer_address().IsSet() || + !socket_info.peer_port().IsSet()) { + return "GetInfo(): connected TCP socket should have peer address and " + "port"; + } + if (*socket_info.peer_address() != "127.0.0.1" || + *socket_info.peer_port() != port_) { + return "GetInfo(): peer address and port should match the listening " + "server."; + } + } else { + if (socket_info.connected()) + return "GetInfo(): UDP socket should not be connected."; + if (socket_info.peer_address().IsSet() || + socket_info.peer_port().IsSet()) { + return "GetInfo(): unconnected UDP socket should not have peer " + "address or port."; + } + } + } + + { + TestExtCompletionCallbackWithOutput<bool> callback(pp_instance()); + callback.WaitForResult(socket_.SetNoDelay( + socket_id, true, callback.GetCallback())); + if (callback.result() != PP_OK) + return "SetNoDelay(): failed."; + if (socket_type.value == socket::SocketType_Dev::TCP) { + if (!callback.output()) + return "SetNoDelay(): failed for TCP."; + } else { + if (callback.output()) + return "SetNoDelay(): did not fail for UDP."; + } + } + + { + TestExtCompletionCallbackWithOutput<bool> callback(pp_instance()); + callback.WaitForResult(socket_.SetKeepAlive( + socket_id, true, 1000, callback.GetCallback())); + if (callback.result() != PP_OK) + return "SetKeepAlive(): failed."; + if (socket_type.value == socket::SocketType_Dev::TCP) { + if (!callback.output()) + return "SetKeepAlive(): failed for TCP."; + } else { + if (callback.output()) + return "SetKeepAlive(): did not fail for UDP."; + } + } + + { + VarArrayBuffer input_array_buffer = ConvertToArrayBuffer(kSendContents); + size_t bytes_written = 0; + int32_t result_code = 0; + VarArrayBuffer data; + if (socket_type.value == socket::SocketType_Dev::TCP) { + TestExtCompletionCallbackWithOutput<socket::ReadInfo_Dev> + read_callback(pp_instance()); + int32_t read_result = socket_.Read(socket_id, Optional<int32_t>(), + read_callback.GetCallback()); + if (read_result != PP_OK_COMPLETIONPENDING) + return "Read(): did not wait for data."; + + TestExtCompletionCallbackWithOutput<socket::WriteInfo_Dev> + write_callback(pp_instance()); + write_callback.WaitForResult(socket_.Write( + socket_id, input_array_buffer, write_callback.GetCallback())); + if (write_callback.result() != PP_OK) + return "Write(): failed."; + bytes_written = static_cast<size_t>( + write_callback.output().bytes_written()); + + read_callback.WaitForResult(read_result); + if (read_callback.result() != PP_OK) + return "Read(): failed."; + socket::ReadInfo_Dev read_info = read_callback.output(); + result_code = read_info.result_code(), + data = read_info.data(); + } else { + TestExtCompletionCallbackWithOutput<socket::RecvFromInfo_Dev> + recv_from_callback(pp_instance()); + int32_t recv_from_result = socket_.RecvFrom( + socket_id, Optional<int32_t>(), recv_from_callback.GetCallback()); + if (recv_from_result != PP_OK_COMPLETIONPENDING) + return "RecvFrom(): did not wait for data."; + + TestExtCompletionCallbackWithOutput<socket::WriteInfo_Dev> + send_to_callback(pp_instance()); + send_to_callback.WaitForResult(socket_.SendTo( + socket_id, input_array_buffer, address_, port_, + send_to_callback.GetCallback())); + if (send_to_callback.result() != PP_OK) + return "SendTo(): failed."; + bytes_written = static_cast<size_t>( + send_to_callback.output().bytes_written()); + + recv_from_callback.WaitForResult(recv_from_result); + if (recv_from_callback.result() != PP_OK) + return "RecvFrom(): failed."; + socket::RecvFromInfo_Dev recv_from_info = recv_from_callback.output(); + result_code = recv_from_info.result_code(); + data = recv_from_info.data(); + } + + if (bytes_written != strlen(kSendContents)) + return "SendTo() or Write(): did not send the whole data buffer."; + + if (result_code > 0 && + static_cast<uint32_t>(result_code) != data.ByteLength()) { + return "Read() or RecvFrom(): inconsistent result code and byte " + "length."; + } + + std::string output_string = ConvertFromArrayBuffer(&data); + size_t prefix_len = strlen(kReceiveContentsPrefix); + if (output_string.size() != prefix_len + kReceiveContentsSuffixSize || + output_string.compare(0, prefix_len, kReceiveContentsPrefix) != 0) { + return std::string("Read() or RecvFrom(): mismatched data: ").append( + output_string); + } + } + + { + TestExtCompletionCallbackWithOutput< + std::vector<socket::NetworkInterface_Dev> > callback(pp_instance()); + callback.WaitForResult(socket_.GetNetworkList(callback.GetCallback())); + if (callback.result() != PP_OK) + return "GetNetworkList(): failed."; + if (callback.output().empty()) + return "GetNetworkList(): returned an empty list."; + } + + socket_.Destroy(socket_id); + return std::string(); + } + + void Log(PP_LogLevel level, const char* format, ...) { + va_list args; + va_start(args, format); + char buf[512]; + vsnprintf(buf, sizeof(buf) - 1, format, args); + buf[sizeof(buf) - 1] = '\0'; + va_end(args); + + Var value(buf); + console_interface_->Log(pp_instance(), level, value.pp_var()); + } + + void NotifyTestDone(const std::string& message) { + PostMessage(message); + } + + VarArrayBuffer ConvertToArrayBuffer(const std::string data) { + VarArrayBuffer array_buffer(data.size()); + memcpy(array_buffer.Map(), data.c_str(), data.size()); + array_buffer.Unmap(); + return array_buffer; + } + + std::string ConvertFromArrayBuffer(VarArrayBuffer* array_buffer) { + std::string result(static_cast<const char*>(array_buffer->Map()), + array_buffer->ByteLength()); + array_buffer->Unmap(); + return result; + } + + socket::Socket_Dev socket_; + const PPB_Console* console_interface_; + + std::string test_type_; + std::string address_; + int32_t port_; +}; + +class MyModule : public Module { + public: + MyModule() : Module() {} + virtual ~MyModule() {} + + virtual Instance* CreateInstance(PP_Instance instance) { + return new MyInstance(instance); + } +}; + +namespace pp { + +Module* CreateModule() { + return new MyModule(); +} + +} // namespace pp + diff --git a/ppapi/tests/test_char_set.cc b/ppapi/tests/test_char_set.cc index de998d09a3..f7ff910573 100644 --- a/ppapi/tests/test_char_set.cc +++ b/ppapi/tests/test_char_set.cc @@ -113,7 +113,8 @@ std::string TestCharSet::TestUTF16ToCharSet() { std::vector<uint16_t> utf16; utf16.push_back(0); std::string output_buffer; - uint32_t utf8result_len = static_cast<uint32_t>(output_buffer.size()); + output_buffer.resize(1); + uint32_t utf8result_len = 0; PP_Bool result = char_set_trusted_interface_->UTF16ToCharSet( &utf16[0], 0, "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE, &output_buffer[0], &utf8result_len); diff --git a/ppapi/tests/test_file_io.cc b/ppapi/tests/test_file_io.cc index 443f7866e5..9b0bc27022 100644 --- a/ppapi/tests/test_file_io.cc +++ b/ppapi/tests/test_file_io.cc @@ -17,7 +17,6 @@ #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" @@ -183,7 +182,6 @@ void TestFileIO::RunTests(const std::string& filter) { RUN_CALLBACK_TEST(TestFileIO, ParallelReads, filter); RUN_CALLBACK_TEST(TestFileIO, ParallelWrites, filter); RUN_CALLBACK_TEST(TestFileIO, NotAllowMixedReadWrite, filter); - RUN_CALLBACK_TEST(TestFileIO, WillWriteWillSetLength, filter); RUN_CALLBACK_TEST(TestFileIO, RequestOSFileHandle, filter); RUN_CALLBACK_TEST(TestFileIO, RequestOSFileHandleWithOpenExclusive, filter); RUN_CALLBACK_TEST(TestFileIO, Mmap, filter); @@ -991,76 +989,6 @@ std::string TestFileIO::TestNotAllowMixedReadWrite() { PASS(); } -std::string TestFileIO::TestWillWriteWillSetLength() { - TestCompletionCallback callback(instance_->pp_instance(), callback_type()); - - pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY); - pp::FileRef file_ref(file_system, "/file_will_write"); - callback.WaitForResult(file_system.Open(1024, callback.GetCallback())); - CHECK_CALLBACK_BEHAVIOR(callback); - ASSERT_EQ(PP_OK, callback.result()); - - pp::FileIO file_io(instance_); - callback.WaitForResult(file_io.Open(file_ref, - PP_FILEOPENFLAG_CREATE | - PP_FILEOPENFLAG_TRUNCATE | - PP_FILEOPENFLAG_READ | - PP_FILEOPENFLAG_WRITE, - callback.GetCallback())); - CHECK_CALLBACK_BEHAVIOR(callback); - ASSERT_EQ(PP_OK, callback.result()); - - const PPB_FileIOTrusted* trusted = static_cast<const PPB_FileIOTrusted*>( - pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); - ASSERT_TRUE(trusted); - - // Get file descriptor. This is only supported in-process for now, so don't - // test out of process. - const PPB_Testing_Dev* testing_interface = GetTestingInterface(); - if (testing_interface && !testing_interface->IsOutOfProcess()) { - int32_t fd = trusted->GetOSFileDescriptor(file_io.pp_resource()); - ASSERT_TRUE(fd >= 0); - } - - // Calling WillWrite. - callback.WaitForResult(trusted->WillWrite( - file_io.pp_resource(), 0, 9, - callback.GetCallback().pp_completion_callback())); - CHECK_CALLBACK_BEHAVIOR(callback); - ASSERT_EQ(9, callback.result()); - - // Writing the actual data. - int32_t rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0, - "test_test", callback_type()); - ASSERT_EQ(PP_OK, rv); - - std::string read_buffer; - rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0, &read_buffer, - callback_type()); - ASSERT_EQ(PP_OK, rv); - ASSERT_EQ(std::string("test_test"), read_buffer); - - // Calling WillSetLength. - callback.WaitForResult(trusted->WillSetLength( - file_io.pp_resource(), 4, - callback.GetCallback().pp_completion_callback())); - CHECK_CALLBACK_BEHAVIOR(callback); - ASSERT_EQ(PP_OK, rv); - - // Calling actual SetLength. - callback.WaitForResult(file_io.SetLength(4, callback.GetCallback())); - CHECK_CALLBACK_BEHAVIOR(callback); - ASSERT_EQ(PP_OK, rv); - - read_buffer.clear(); - rv = ReadEntireFile(instance_->pp_instance(), &file_io, 0, &read_buffer, - callback_type()); - ASSERT_EQ(PP_OK, rv); - ASSERT_EQ(std::string("test"), read_buffer); - - PASS(); -} - std::string TestFileIO::TestRequestOSFileHandle() { TestCompletionCallback callback(instance_->pp_instance(), callback_type()); diff --git a/ppapi/tests/test_file_io.h b/ppapi/tests/test_file_io.h index 8221f4da80..3cc0095c91 100644 --- a/ppapi/tests/test_file_io.h +++ b/ppapi/tests/test_file_io.h @@ -46,7 +46,6 @@ class TestFileIO : public TestCase { std::string TestParallelReads(); std::string TestParallelWrites(); std::string TestNotAllowMixedReadWrite(); - std::string TestWillWriteWillSetLength(); std::string TestRequestOSFileHandle(); std::string TestRequestOSFileHandleWithOpenExclusive(); std::string TestMmap(); diff --git a/ppapi/tests/test_file_ref.cc b/ppapi/tests/test_file_ref.cc index d1448ec7ed..0799445d54 100644 --- a/ppapi/tests/test_file_ref.cc +++ b/ppapi/tests/test_file_ref.cc @@ -115,13 +115,9 @@ void TestFileRef::RunTests(const std::string& filter) { RUN_CALLBACK_TEST(TestFileRef, QueryAndTouchFile, filter); RUN_CALLBACK_TEST(TestFileRef, DeleteFileAndDirectory, filter); RUN_CALLBACK_TEST(TestFileRef, RenameFileAndDirectory, filter); - // FileRef::Query is out-of-process only. - if (testing_interface_->IsOutOfProcess()) - RUN_CALLBACK_TEST(TestFileRef, Query, filter); + RUN_CALLBACK_TEST(TestFileRef, Query, filter); RUN_CALLBACK_TEST(TestFileRef, FileNameEscaping, filter); - // FileRef::ReadDirectoryEntries is out-of-process only. - if (testing_interface_->IsOutOfProcess()) - RUN_CALLBACK_TEST(TestFileRef, ReadDirectoryEntries, filter); + RUN_CALLBACK_TEST(TestFileRef, ReadDirectoryEntries, filter); } std::string TestFileRef::TestCreate() { diff --git a/ppapi/tests/test_graphics_3d.cc b/ppapi/tests/test_graphics_3d.cc index 61bedbf198..8c1bdc17bc 100644 --- a/ppapi/tests/test_graphics_3d.cc +++ b/ppapi/tests/test_graphics_3d.cc @@ -34,6 +34,7 @@ void TestGraphics3D::RunTests(const std::string& filter) { RUN_CALLBACK_TEST(TestGraphics3D, FramePPAPI, filter); RUN_CALLBACK_TEST(TestGraphics3D, FrameGL, filter); RUN_CALLBACK_TEST(TestGraphics3D, ExtensionsGL, filter); + RUN_CALLBACK_TEST(TestGraphics3D, BadResource, filter); } std::string TestGraphics3D::TestFramePPAPI() { @@ -167,3 +168,32 @@ std::string TestGraphics3D::CheckPixelGL( PASS(); } +std::string TestGraphics3D::TestBadResource() { + // The point of this test is mostly just to make sure that we don't crash and + // provide reasonable (error) results when the resource is bad. + const PP_Resource kBadResource = 123; + + // Access OpenGLES API through the PPAPI interface. + opengl_es2_->ClearColor(kBadResource, 0.0f, 0.0f, 0.0f, 0.0f); + opengl_es2_->Clear(kBadResource, GL_COLOR_BUFFER_BIT); + ASSERT_EQ(0, opengl_es2_->GetError(kBadResource)); + ASSERT_EQ(NULL, opengl_es2_->GetString(kBadResource, GL_VERSION)); + ASSERT_EQ(-1, opengl_es2_->GetUniformLocation(kBadResource, 0, NULL)); + ASSERT_EQ(GL_FALSE, opengl_es2_->IsBuffer(kBadResource, 0)); + ASSERT_EQ(0, opengl_es2_->CheckFramebufferStatus(kBadResource, + GL_DRAW_FRAMEBUFFER)); + + glSetCurrentContextPPAPI(kBadResource); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_EQ(0, glGetError()); + ASSERT_EQ(NULL, glGetString(GL_VERSION)); + ASSERT_EQ(-1, glGetUniformLocation(0, NULL)); + ASSERT_EQ(GL_FALSE, glIsBuffer(0)); + ASSERT_EQ(0, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + PASS(); +} + diff --git a/ppapi/tests/test_graphics_3d.h b/ppapi/tests/test_graphics_3d.h index 3d5b1cff99..2914f969bd 100644 --- a/ppapi/tests/test_graphics_3d.h +++ b/ppapi/tests/test_graphics_3d.h @@ -27,6 +27,7 @@ class TestGraphics3D : public TestCase { std::string TestExtensionsGL(); std::string TestFrameGL(); std::string TestFramePPAPI(); + std::string TestBadResource(); // Utils used by various tests. int32_t SwapBuffersSync(pp::Graphics3D* context); diff --git a/ppapi/tests/test_output_protection_private.cc b/ppapi/tests/test_output_protection_private.cc new file mode 100644 index 0000000000..49a44aed11 --- /dev/null +++ b/ppapi/tests/test_output_protection_private.cc @@ -0,0 +1,60 @@ +// Copyright 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/tests/test_output_protection_private.h" + +#include "ppapi/tests/testing_instance.h" + +REGISTER_TEST_CASE(OutputProtectionPrivate); + +TestOutputProtectionPrivate::TestOutputProtectionPrivate( + TestingInstance* instance) + : TestCase(instance) { +} + +bool TestOutputProtectionPrivate::Init() { + output_protection_interface_ = + static_cast<const PPB_OutputProtection_Private*>( + pp::Module::Get()->GetBrowserInterface( + PPB_OUTPUTPROTECTION_PRIVATE_INTERFACE_0_1)); + return output_protection_interface_ && CheckTestingInterface(); +} + +void TestOutputProtectionPrivate::RunTests(const std::string& filter) { + RUN_TEST(QueryStatus, filter); + RUN_TEST(EnableProtection, filter); +} + +std::string TestOutputProtectionPrivate::TestQueryStatus() { + TestCompletionCallback callback(instance_->pp_instance(), callback_type()); + + PP_Resource output_protection_resource = output_protection_interface_-> + Create(instance_->pp_instance()); + uint32_t link_mask; + uint32_t protection_mask; + callback.WaitForResult( + output_protection_interface_->QueryStatus( + output_protection_resource, + &link_mask, + &protection_mask, + callback.GetCallback().pp_completion_callback())); + CHECK_CALLBACK_BEHAVIOR(callback); + + PASS(); +} + +std::string TestOutputProtectionPrivate::TestEnableProtection() { + TestCompletionCallback callback(instance_->pp_instance(), callback_type()); + + PP_Resource output_protection_resource = output_protection_interface_-> + Create(instance_->pp_instance()); + callback.WaitForResult( + output_protection_interface_->EnableProtection( + output_protection_resource, + PP_OUTPUT_PROTECTION_METHOD_PRIVATE_NONE, + callback.GetCallback().pp_completion_callback())); + CHECK_CALLBACK_BEHAVIOR(callback); + + PASS(); +} diff --git a/ppapi/tests/test_output_protection_private.h b/ppapi/tests/test_output_protection_private.h new file mode 100644 index 0000000000..a7a341e921 --- /dev/null +++ b/ppapi/tests/test_output_protection_private.h @@ -0,0 +1,29 @@ +// Copyright 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_TESTS_TEST_OUTPUT_PROTECTION_PRIVATE_H_ +#define PPAPI_TESTS_TEST_OUTPUT_PROTECTION_PRIVATE_H_ + +#include <string> + +#include "ppapi/cpp/private/output_protection_private.h" +#include "ppapi/tests/test_case.h" +#include "ppapi/tests/test_utils.h" + +class TestOutputProtectionPrivate: public TestCase { + public: + explicit TestOutputProtectionPrivate(TestingInstance* instance); + + private: + // TestCase implementation. + virtual bool Init(); + virtual void RunTests(const std::string& filter); + + std::string TestQueryStatus(); + std::string TestEnableProtection(); + + const PPB_OutputProtection_Private* output_protection_interface_; +}; + +#endif // PPAPI_TESTS_TEST_OUTPUT_PROTECTION_PRIVATE_H_ diff --git a/ppapi/tests/test_tcp_socket.cc b/ppapi/tests/test_tcp_socket.cc index ba456c3262..604487c5b9 100644 --- a/ppapi/tests/test_tcp_socket.cc +++ b/ppapi/tests/test_tcp_socket.cc @@ -25,12 +25,19 @@ bool ValidateHttpResponse(const std::string& s) { REGISTER_TEST_CASE(TCPSocket); -TestTCPSocket::TestTCPSocket(TestingInstance* instance) : TestCase(instance) { +TestTCPSocket::TestTCPSocket(TestingInstance* instance) + : TestCase(instance), + socket_interface_1_0_(NULL) { } bool TestTCPSocket::Init() { if (!pp::TCPSocket::IsAvailable()) return false; + socket_interface_1_0_ = + static_cast<const PPB_TCPSocket_1_0*>( + pp::Module::Get()->GetBrowserInterface(PPB_TCPSOCKET_INTERFACE_1_0)); + if (!socket_interface_1_0_) + return false; // We need something to connect to, so we connect to the HTTP server whence we // came. Grab the host and port. @@ -54,6 +61,7 @@ void TestTCPSocket::RunTests(const std::string& filter) { RUN_CALLBACK_TEST(TestTCPSocket, SetOption, filter); RUN_CALLBACK_TEST(TestTCPSocket, Listen, filter); RUN_CALLBACK_TEST(TestTCPSocket, Backlog, filter); + RUN_CALLBACK_TEST(TestTCPSocket, Interface_1_0, filter); } std::string TestTCPSocket::TestConnect() { @@ -305,6 +313,27 @@ std::string TestTCPSocket::TestBacklog() { PASS(); } +std::string TestTCPSocket::TestInterface_1_0() { + PP_Resource socket = socket_interface_1_0_->Create(instance_->pp_instance()); + ASSERT_NE(0, socket); + + TestCompletionCallback cb(instance_->pp_instance(), callback_type()); + cb.WaitForResult(socket_interface_1_0_->Connect( + socket, addr_.pp_resource(), cb.GetCallback().pp_completion_callback())); + CHECK_CALLBACK_BEHAVIOR(cb); + ASSERT_EQ(PP_OK, cb.result()); + + ASSERT_SUBTEST_SUCCESS(WriteToSocket_1_0(socket, "GET / HTTP/1.0\r\n\r\n")); + + // Read up to the first \n and check that it looks like valid HTTP response. + std::string s; + ASSERT_SUBTEST_SUCCESS(ReadFirstLineFromSocket_1_0(socket, &s)); + ASSERT_TRUE(ValidateHttpResponse(s)); + + pp::Module::Get()->core()->ReleaseResource(socket); + PASS(); +} + std::string TestTCPSocket::ReadFirstLineFromSocket(pp::TCPSocket* socket, std::string* s) { char buffer[1000]; @@ -326,6 +355,29 @@ std::string TestTCPSocket::ReadFirstLineFromSocket(pp::TCPSocket* socket, PASS(); } +std::string TestTCPSocket::ReadFirstLineFromSocket_1_0(PP_Resource socket, + std::string* s) { + char buffer[1000]; + + s->clear(); + // Make sure we don't just hang if |Read()| spews. + while (s->size() < 10000) { + TestCompletionCallback cb(instance_->pp_instance(), callback_type()); + cb.WaitForResult(socket_interface_1_0_->Read( + socket, buffer, sizeof(buffer), + cb.GetCallback().pp_completion_callback())); + CHECK_CALLBACK_BEHAVIOR(cb); + ASSERT_GT(cb.result(), 0); + s->reserve(s->size() + cb.result()); + for (int32_t i = 0; i < cb.result(); ++i) { + s->push_back(buffer[i]); + if (buffer[i] == '\n') + PASS(); + } + } + PASS(); +} + std::string TestTCPSocket::ReadFromSocket(pp::TCPSocket* socket, char* buffer, size_t num_bytes) { @@ -358,6 +410,24 @@ std::string TestTCPSocket::WriteToSocket(pp::TCPSocket* socket, PASS(); } +std::string TestTCPSocket::WriteToSocket_1_0( + PP_Resource socket, + const std::string& s) { + const char* buffer = s.data(); + size_t written = 0; + while (written < s.size()) { + TestCompletionCallback cb(instance_->pp_instance(), callback_type()); + cb.WaitForResult(socket_interface_1_0_->Write( + socket, buffer + written, s.size() - written, + cb.GetCallback().pp_completion_callback())); + CHECK_CALLBACK_BEHAVIOR(cb); + ASSERT_GT(cb.result(), 0); + written += cb.result(); + } + ASSERT_EQ(written, s.size()); + PASS(); +} + std::string TestTCPSocket::GetAddressToBind(pp::NetAddress* address) { pp::TCPSocket socket(instance_); TestCompletionCallback callback(instance_->pp_instance(), callback_type()); diff --git a/ppapi/tests/test_tcp_socket.h b/ppapi/tests/test_tcp_socket.h index 136dc46657..8f7e2f4126 100644 --- a/ppapi/tests/test_tcp_socket.h +++ b/ppapi/tests/test_tcp_socket.h @@ -8,6 +8,7 @@ #include <string> #include "ppapi/c/pp_stdint.h" +#include "ppapi/c/ppb_tcp_socket.h" #include "ppapi/cpp/net_address.h" #include "ppapi/tests/test_case.h" @@ -29,16 +30,23 @@ class TestTCPSocket: public TestCase { std::string TestSetOption(); std::string TestListen(); std::string TestBacklog(); + std::string TestInterface_1_0(); std::string ReadFirstLineFromSocket(pp::TCPSocket* socket, std::string* s); + std::string ReadFirstLineFromSocket_1_0(PP_Resource socket, + std::string* s); std::string ReadFromSocket(pp::TCPSocket* socket, char* buffer, size_t num_bytes); std::string WriteToSocket(pp::TCPSocket* socket, const std::string& s); + std::string WriteToSocket_1_0(PP_Resource socket, const std::string& s); + std::string GetAddressToBind(pp::NetAddress* address); std::string StartListen(pp::TCPSocket* socket, int32_t backlog); pp::NetAddress addr_; + + const PPB_TCPSocket_1_0* socket_interface_1_0_; }; #endif // PAPPI_TESTS_TEST_TCP_SOCKET_H_ diff --git a/ppapi/tests/test_url_loader.cc b/ppapi/tests/test_url_loader.cc index 8d13f4089f..c268eb09ac 100644 --- a/ppapi/tests/test_url_loader.cc +++ b/ppapi/tests/test_url_loader.cc @@ -12,7 +12,6 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/ppb_file_io.h" #include "ppapi/c/ppb_url_loader.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #include "ppapi/cpp/dev/url_util_dev.h" #include "ppapi/cpp/file_io.h" @@ -20,6 +19,7 @@ #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/cpp/url_loader.h" #include "ppapi/cpp/url_request_info.h" #include "ppapi/cpp/url_response_info.h" @@ -59,7 +59,7 @@ int32_t WriteEntireBuffer(PP_Instance instance, TestURLLoader::TestURLLoader(TestingInstance* instance) : TestCase(instance), - file_io_trusted_interface_(NULL), + file_io_private_interface_(NULL), url_loader_trusted_interface_(NULL) { } @@ -74,20 +74,18 @@ bool TestURLLoader::Init() { if (!file_io_interface) instance_->AppendError("FileIO interface not available"); - file_io_trusted_interface_ = static_cast<const PPB_FileIOTrusted*>( - pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE)); + file_io_private_interface_ = static_cast<const PPB_FileIO_Private*>( + pp::Module::Get()->GetBrowserInterface(PPB_FILEIO_PRIVATE_INTERFACE)); + if (!file_io_private_interface_) + instance_->AppendError("FileIO_Private interface not available"); url_loader_trusted_interface_ = static_cast<const PPB_URLLoaderTrusted*>( pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE)); if (!testing_interface_->IsOutOfProcess()) { // Trusted interfaces are not supported under NaCl. #if !(defined __native_client__) - if (!file_io_trusted_interface_) - instance_->AppendError("FileIOTrusted interface not available"); if (!url_loader_trusted_interface_) instance_->AppendError("URLLoaderTrusted interface not available"); #else - if (file_io_trusted_interface_) - instance_->AppendError("FileIOTrusted interface is supported by NaCl"); if (url_loader_trusted_interface_) instance_->AppendError("URLLoaderTrusted interface is supported by NaCl"); #endif @@ -490,15 +488,6 @@ std::string TestURLLoader::TestStreamToFile() { if (data != expected_body) return "ReadEntireFile returned unexpected content"; - // FileIOTrusted is not supported by NaCl or ppapi/proxy. - if (!testing_interface_->IsOutOfProcess()) { -#if !(defined __native_client__) - int32_t file_descriptor = file_io_trusted_interface_->GetOSFileDescriptor( - reader.pp_resource()); - if (file_descriptor < 0) - return "FileIO::GetOSFileDescriptor() returned a bad file descriptor."; -#endif - } PASS(); } diff --git a/ppapi/tests/test_url_loader.h b/ppapi/tests/test_url_loader.h index 95c97b1f14..3e49ce9fa0 100644 --- a/ppapi/tests/test_url_loader.h +++ b/ppapi/tests/test_url_loader.h @@ -7,7 +7,7 @@ #include <string> -#include "ppapi/c/trusted/ppb_file_io_trusted.h" +#include "ppapi/c/private/ppb_file_io_private.h" #include "ppapi/c/trusted/ppb_url_loader_trusted.h" #include "ppapi/tests/test_case.h" @@ -73,7 +73,7 @@ class TestURLLoader : public TestCase { std::string TestUntendedLoad(); std::string TestPrefetchBufferThreshold(); - const PPB_FileIOTrusted* file_io_trusted_interface_; + const PPB_FileIO_Private* file_io_private_interface_; const PPB_URLLoaderTrusted* url_loader_trusted_interface_; }; diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h index 038d5c521c..d4b5b641bb 100644 --- a/ppapi/thunk/interfaces_ppb_private.h +++ b/ppapi/thunk/interfaces_ppb_private.h @@ -52,12 +52,13 @@ PROXIED_IFACE(NoAPIName, PPB_TALK_PRIVATE_INTERFACE_1_0, PPB_Talk_Private_1_0) PROXIED_IFACE(NoAPIName, PPB_TALK_PRIVATE_INTERFACE_2_0, PPB_Talk_Private_2_0) -// This uses the FileIO API which is declared in the public stable file. -PROXIED_IFACE(NoAPIName, PPB_FILEIOTRUSTED_INTERFACE_0_4, PPB_FileIOTrusted_0_4) PROXIED_IFACE(NoAPIName, PPB_URLLOADERTRUSTED_INTERFACE_0_3, PPB_URLLoaderTrusted_0_3) +PROXIED_IFACE(NoAPIName, PPB_OUTPUTPROTECTION_PRIVATE_INTERFACE_0_1, + PPB_OutputProtection_Private_0_1) + // Hack to keep font working. The Font 0.6 API is binary compatible with // BrowserFont 1.0, so just map the string to the same thing. // TODO(brettw) remove support for the old Font API. diff --git a/ppapi/thunk/ppb_file_io_api.h b/ppapi/thunk/ppb_file_io_api.h index ec7f16d114..b794f1ca80 100644 --- a/ppapi/thunk/ppb_file_io_api.h +++ b/ppapi/thunk/ppb_file_io_api.h @@ -45,14 +45,6 @@ class PPAPI_THUNK_EXPORT PPB_FileIO_API { virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) = 0; virtual void Close() = 0; - // Trusted API. - virtual int32_t GetOSFileDescriptor() = 0; - virtual int32_t WillWrite(int64_t offset, - int32_t bytes_to_write, - 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, diff --git a/ppapi/thunk/ppb_file_io_trusted_thunk.cc b/ppapi/thunk/ppb_file_io_trusted_thunk.cc deleted file mode 100644 index 3336026e8e..0000000000 --- a/ppapi/thunk/ppb_file_io_trusted_thunk.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2012 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/c/pp_completion_callback.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/c/trusted/ppb_file_io_trusted.h" -#include "ppapi/shared_impl/tracked_callback.h" -#include "ppapi/thunk/enter.h" -#include "ppapi/thunk/thunk.h" -#include "ppapi/thunk/ppb_file_io_api.h" -#include "ppapi/thunk/resource_creation_api.h" - -namespace ppapi { -namespace thunk { - -namespace { - -typedef EnterResource<PPB_FileIO_API> EnterFileIO; - -int32_t GetOSFileDescriptor(PP_Resource file_io) { - EnterFileIO enter(file_io, true); - if (enter.failed()) - return enter.retval(); - return enter.object()->GetOSFileDescriptor(); -} - -int32_t WillWrite(PP_Resource file_io, - int64_t offset, - int32_t bytes_to_write, - PP_CompletionCallback callback) { - EnterFileIO enter(file_io, callback, true); - if (enter.failed()) - return enter.retval(); - return enter.SetResult(enter.object()->WillWrite(offset, bytes_to_write, - enter.callback())); -} - -int32_t WillSetLength(PP_Resource file_io, - int64_t length, - PP_CompletionCallback callback) { - EnterFileIO enter(file_io, callback, true); - if (enter.failed()) - return enter.retval(); - return enter.SetResult(enter.object()->WillSetLength(length, - enter.callback())); -} - -const PPB_FileIOTrusted g_ppb_file_io_trusted_thunk = { - &GetOSFileDescriptor, - &WillWrite, - &WillSetLength -}; - -} // namespace - -const PPB_FileIOTrusted_0_4* GetPPB_FileIOTrusted_0_4_Thunk() { - return &g_ppb_file_io_trusted_thunk; -} - -} // namespace thunk -} // namespace ppapi diff --git a/ppapi/thunk/ppb_output_protection_api.h b/ppapi/thunk/ppb_output_protection_api.h new file mode 100644 index 0000000000..8a12090ae5 --- /dev/null +++ b/ppapi/thunk/ppb_output_protection_api.h @@ -0,0 +1,32 @@ +// Copyright 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_THUNK_OUTPUT_PROTECTION_API_H_ +#define PPAPI_THUNK_OUTPUT_PROTECTION_API_H_ + +#include "ppapi/c/private/ppb_output_protection_private.h" + +namespace ppapi { + +class TrackedCallback; + +namespace thunk { + +class PPB_OutputProtection_API { + public: + virtual ~PPB_OutputProtection_API() {} + + virtual int32_t QueryStatus( + uint32_t* link_mask, + uint32_t* protection_mask, + const scoped_refptr<TrackedCallback>& callback) = 0; + virtual int32_t EnableProtection( + uint32_t desired_method_mask, + const scoped_refptr<TrackedCallback>& callback) = 0; +}; + +} // namespace thunk +} // namespace ppapi + +#endif // PPAPI_THUNK_OUTPUT_PROTECTION_API_H_ diff --git a/ppapi/thunk/resource_creation_api.h b/ppapi/thunk/resource_creation_api.h index aa731cfd7b..61eaa973f0 100644 --- a/ppapi/thunk/resource_creation_api.h +++ b/ppapi/thunk/resource_creation_api.h @@ -146,6 +146,7 @@ class ResourceCreationAPI { PP_Instance instance, const PP_NetAddress_Private& private_addr) = 0; virtual PP_Resource CreateNetworkMonitor(PP_Instance instance) = 0; + virtual PP_Resource CreateOutputProtectionPrivate(PP_Instance instance) = 0; virtual PP_Resource CreatePrinting(PP_Instance instance) = 0; virtual PP_Resource CreateTCPServerSocketPrivate(PP_Instance instance) = 0; virtual PP_Resource CreateTCPSocket1_0(PP_Instance instace) = 0; |